]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - sound/soc/bcm/pisound.c
sound: Suppress error message about deferrals
[mirror_ubuntu-zesty-kernel.git] / sound / soc / bcm / pisound.c
CommitLineData
178f845a 1/*
2 * pisound Linux kernel module.
3 * Copyright (C) 2016 Vilniaus Blokas UAB, http://blokas.io/pisound
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; version 2 of the
8 * License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/gpio.h>
25#include <linux/kobject.h>
26#include <linux/sysfs.h>
27#include <linux/delay.h>
28#include <linux/spi/spi.h>
29#include <linux/interrupt.h>
30#include <linux/kfifo.h>
31
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/jack.h>
37#include <sound/rawmidi.h>
38#include <sound/asequencer.h>
41409144 39#include <sound/control.h>
178f845a 40
41static int pisnd_spi_init(struct device *dev);
42static void pisnd_spi_uninit(void);
43
44static void pisnd_spi_send(uint8_t val);
45static uint8_t pisnd_spi_recv(uint8_t *buffer, uint8_t length);
46
47typedef void (*pisnd_spi_recv_cb)(void *data);
48static void pisnd_spi_set_callback(pisnd_spi_recv_cb cb, void *data);
49
50static const char *pisnd_spi_get_serial(void);
51static const char *pisnd_spi_get_id(void);
52static const char *pisnd_spi_get_version(void);
53
54static int pisnd_midi_init(struct snd_card *card);
55static void pisnd_midi_uninit(void);
56
57#define PISOUND_LOG_PREFIX "pisound: "
58
59#ifdef DEBUG
60# define printd(...) pr_alert(PISOUND_LOG_PREFIX __VA_ARGS__)
61#else
62# define printd(...) do {} while (0)
63#endif
64
65#define printe(...) pr_err(PISOUND_LOG_PREFIX __VA_ARGS__)
66#define printi(...) pr_info(PISOUND_LOG_PREFIX __VA_ARGS__)
67
68static int pisnd_output_open(struct snd_rawmidi_substream *substream)
69{
70 return 0;
71}
72
73static int pisnd_output_close(struct snd_rawmidi_substream *substream)
74{
75 return 0;
76}
77
78static void pisnd_output_trigger(
79 struct snd_rawmidi_substream *substream,
80 int up
81 )
82{
83 uint8_t data;
84
85 if (!up)
86 return;
87
88 while (snd_rawmidi_transmit_peek(substream, &data, 1)) {
89 pisnd_spi_send(data);
90 snd_rawmidi_transmit_ack(substream, 1);
91 }
92}
93
94static void pisnd_output_drain(struct snd_rawmidi_substream *substream)
95{
96 uint8_t data;
97
98 while (snd_rawmidi_transmit_peek(substream, &data, 1)) {
99 pisnd_spi_send(data);
100
101 snd_rawmidi_transmit_ack(substream, 1);
102 }
103}
104
105static int pisnd_input_open(struct snd_rawmidi_substream *substream)
106{
107 return 0;
108}
109
110static int pisnd_input_close(struct snd_rawmidi_substream *substream)
111{
112 return 0;
113}
114
115static void pisnd_midi_recv_callback(void *substream)
116{
117 uint8_t data[128];
118 uint8_t n = 0;
119
120 while ((n = pisnd_spi_recv(data, sizeof(data)))) {
121 int res = snd_rawmidi_receive(substream, data, n);
122 (void)res;
123 printd("midi recv 0x%02x, res = %d\n", data, res);
124 }
125}
126
127static void pisnd_input_trigger(struct snd_rawmidi_substream *substream, int up)
128{
129 if (up) {
130 pisnd_spi_set_callback(pisnd_midi_recv_callback, substream);
131 pisnd_midi_recv_callback(substream);
132 } else {
133 pisnd_spi_set_callback(NULL, NULL);
134 }
135}
136
137static struct snd_rawmidi *g_rmidi;
138
139static struct snd_rawmidi_ops pisnd_output_ops = {
140 .open = pisnd_output_open,
141 .close = pisnd_output_close,
142 .trigger = pisnd_output_trigger,
143 .drain = pisnd_output_drain,
144};
145
146static struct snd_rawmidi_ops pisnd_input_ops = {
147 .open = pisnd_input_open,
148 .close = pisnd_input_close,
149 .trigger = pisnd_input_trigger,
150};
151
152static void pisnd_get_port_info(
153 struct snd_rawmidi *rmidi,
154 int number,
155 struct snd_seq_port_info *seq_port_info
156 )
157{
158 seq_port_info->type =
159 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
160 SNDRV_SEQ_PORT_TYPE_HARDWARE |
161 SNDRV_SEQ_PORT_TYPE_PORT;
162 seq_port_info->midi_voices = 0;
163}
164
165static struct snd_rawmidi_global_ops pisnd_global_ops = {
166 .get_port_info = pisnd_get_port_info,
167};
168
169static int pisnd_midi_init(struct snd_card *card)
170{
171 int err = snd_rawmidi_new(card, "pisound MIDI", 0, 1, 1, &g_rmidi);
172
173 if (err < 0) {
174 printe("snd_rawmidi_new failed: %d\n", err);
175 return err;
176 }
177
178 strcpy(g_rmidi->name, "pisound MIDI ");
179 strcat(g_rmidi->name, pisnd_spi_get_serial());
180
181 g_rmidi->info_flags =
182 SNDRV_RAWMIDI_INFO_OUTPUT |
183 SNDRV_RAWMIDI_INFO_INPUT |
184 SNDRV_RAWMIDI_INFO_DUPLEX;
185
186 g_rmidi->ops = &pisnd_global_ops;
187
188 g_rmidi->private_data = (void *)0;
189
190 snd_rawmidi_set_ops(
191 g_rmidi,
192 SNDRV_RAWMIDI_STREAM_OUTPUT,
193 &pisnd_output_ops
194 );
195
196 snd_rawmidi_set_ops(
197 g_rmidi,
198 SNDRV_RAWMIDI_STREAM_INPUT,
199 &pisnd_input_ops
200 );
201
202 return 0;
203}
204
205static void pisnd_midi_uninit(void)
206{
207}
208
209static void *g_recvData;
210static pisnd_spi_recv_cb g_recvCallback;
211
212#define FIFO_SIZE 512
213
214static char g_serial_num[11];
215static char g_id[25];
216static char g_version[5];
217
41409144
GT
218static uint8_t g_ledFlashDuration;
219static bool g_ledFlashDurationChanged;
220
178f845a 221DEFINE_KFIFO(spi_fifo_in, uint8_t, FIFO_SIZE);
222DEFINE_KFIFO(spi_fifo_out, uint8_t, FIFO_SIZE);
223
224static struct gpio_desc *data_available;
225static struct gpio_desc *spi_reset;
226
227static struct spi_device *pisnd_spi_device;
228
229static struct workqueue_struct *pisnd_workqueue;
230static struct work_struct pisnd_work_process;
231
232static void pisnd_work_handler(struct work_struct *work);
233
234static uint16_t spi_transfer16(uint16_t val);
235
236static int pisnd_init_workqueues(void)
237{
238 pisnd_workqueue = create_singlethread_workqueue("pisnd_workqueue");
239 INIT_WORK(&pisnd_work_process, pisnd_work_handler);
240
241 return 0;
242}
243
244static void pisnd_uninit_workqueues(void)
245{
246 flush_workqueue(pisnd_workqueue);
247 destroy_workqueue(pisnd_workqueue);
248
249 pisnd_workqueue = NULL;
250}
251
252static bool pisnd_spi_has_more(void)
253{
254 return gpiod_get_value(data_available);
255}
256
257enum task_e {
258 TASK_PROCESS = 0,
259};
260
261static void pisnd_schedule_process(enum task_e task)
262{
263 if (pisnd_spi_device != NULL &&
264 pisnd_workqueue != NULL &&
265 !work_pending(&pisnd_work_process)
266 ) {
267 printd("schedule: has more = %d\n", pisnd_spi_has_more());
268 if (task == TASK_PROCESS)
269 queue_work(pisnd_workqueue, &pisnd_work_process);
270 }
271}
272
273static irqreturn_t data_available_interrupt_handler(int irq, void *dev_id)
274{
275 if (irq == gpiod_to_irq(data_available) && pisnd_spi_has_more()) {
276 printd("schedule from irq\n");
277 pisnd_schedule_process(TASK_PROCESS);
278 }
279
280 return IRQ_HANDLED;
281}
282
283static DEFINE_SPINLOCK(spilock);
284static unsigned long spilockflags;
285
286static uint16_t spi_transfer16(uint16_t val)
287{
288 int err;
289 struct spi_transfer transfer;
290 struct spi_message msg;
291 uint8_t txbuf[2];
292 uint8_t rxbuf[2];
293
294 if (!pisnd_spi_device) {
295 printe("pisnd_spi_device null, returning\n");
296 return 0;
297 }
298
299 spi_message_init(&msg);
300
301 memset(&transfer, 0, sizeof(transfer));
302 memset(&rxbuf, 0, sizeof(rxbuf));
303
304 txbuf[0] = val >> 8;
305 txbuf[1] = val & 0xff;
306
307 transfer.tx_buf = &txbuf;
308 transfer.rx_buf = &rxbuf;
309 transfer.len = sizeof(txbuf);
310 transfer.speed_hz = 125000;
311 transfer.delay_usecs = 100;
312 spi_message_add_tail(&transfer, &msg);
313
314 spin_lock_irqsave(&spilock, spilockflags);
315 err = spi_sync(pisnd_spi_device, &msg);
316 spin_unlock_irqrestore(&spilock, spilockflags);
317
318 if (err < 0) {
319 printe("spi_sync error %d\n", err);
320 return 0;
321 }
322
323 printd("received: %02x%02x\n", rxbuf[0], rxbuf[1]);
324 printd("hasMore %d\n", pisnd_spi_has_more());
325
326 return (rxbuf[0] << 8) | rxbuf[1];
327}
328
329static int spi_read_bytes(char *dst, size_t length, uint8_t *bytesRead)
330{
331 uint16_t rx;
332 uint8_t size;
333 uint8_t i;
334
335 memset(dst, 0, length);
336 *bytesRead = 0;
337
338 rx = spi_transfer16(0);
339 if (!(rx >> 8))
340 return -EINVAL;
341
342 size = rx & 0xff;
343
344 if (size > length)
345 return -EINVAL;
346
347 for (i = 0; i < size; ++i) {
348 rx = spi_transfer16(0);
349 if (!(rx >> 8))
350 return -EINVAL;
351
352 dst[i] = rx & 0xff;
353 }
354
355 *bytesRead = i;
356
357 return 0;
358}
359
360static int spi_device_match(struct device *dev, void *data)
361{
362 struct spi_device *spi = container_of(dev, struct spi_device, dev);
363
364 printd(" %s %s %dkHz %d bits mode=0x%02X\n",
365 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
366 spi->bits_per_word, spi->mode);
367
368 if (strcmp("pisound-spi", spi->modalias) == 0) {
369 printi("\tFound!\n");
370 return 1;
371 }
372
373 printe("\tNot found!\n");
374 return 0;
375}
376
377static struct spi_device *pisnd_spi_find_device(void)
378{
379 struct device *dev;
380
381 printi("Searching for spi device...\n");
382 dev = bus_find_device(&spi_bus_type, NULL, NULL, spi_device_match);
383 if (dev != NULL)
384 return container_of(dev, struct spi_device, dev);
385 else
386 return NULL;
387}
388
389static void pisnd_work_handler(struct work_struct *work)
390{
391 uint16_t rx;
392 uint16_t tx;
393 uint8_t val;
394
395 if (work == &pisnd_work_process) {
396 if (pisnd_spi_device == NULL)
397 return;
398
399 do {
400 val = 0;
401 tx = 0;
402
41409144
GT
403 if (g_ledFlashDurationChanged) {
404 tx = 0xf000 | g_ledFlashDuration;
405 g_ledFlashDuration = 0;
406 g_ledFlashDurationChanged = false;
407 } else if (kfifo_get(&spi_fifo_out, &val)) {
178f845a 408 tx = 0x0f00 | val;
41409144 409 }
178f845a 410
411 rx = spi_transfer16(tx);
412
413 if (rx & 0xff00) {
414 kfifo_put(&spi_fifo_in, rx & 0xff);
415 if (kfifo_len(&spi_fifo_in) > 16
416 && g_recvCallback)
417 g_recvCallback(g_recvData);
418 }
419 } while (rx != 0
420 || !kfifo_is_empty(&spi_fifo_out)
421 || pisnd_spi_has_more()
41409144 422 || g_ledFlashDurationChanged
178f845a 423 );
424
425 if (!kfifo_is_empty(&spi_fifo_in) && g_recvCallback)
426 g_recvCallback(g_recvData);
427 }
428}
429
430static int pisnd_spi_gpio_init(struct device *dev)
431{
432 spi_reset = gpiod_get_index(dev, "reset", 1, GPIOD_ASIS);
433 data_available = gpiod_get_index(dev, "data_available", 0, GPIOD_ASIS);
434
435 gpiod_direction_output(spi_reset, 1);
436 gpiod_direction_input(data_available);
437
438 /* Reset the slave. */
439 gpiod_set_value(spi_reset, false);
440 mdelay(1);
441 gpiod_set_value(spi_reset, true);
442
443 /* Give time for spi slave to start. */
444 mdelay(64);
445
446 return 0;
447}
448
449static void pisnd_spi_gpio_uninit(void)
450{
451 gpiod_set_value(spi_reset, false);
452 gpiod_put(spi_reset);
453 spi_reset = NULL;
454
455 gpiod_put(data_available);
456 data_available = NULL;
457}
458
459static int pisnd_spi_gpio_irq_init(struct device *dev)
460{
461 return request_irq(
462 gpiod_to_irq(data_available),
463 data_available_interrupt_handler,
464 IRQF_TIMER | IRQF_TRIGGER_RISING,
465 "data_available_int",
466 NULL
467 );
468}
469
470static void pisnd_spi_gpio_irq_uninit(void)
471{
472 free_irq(gpiod_to_irq(data_available), NULL);
473}
474
475static int spi_read_info(void)
476{
477 uint16_t tmp;
478 uint8_t count;
479 uint8_t n;
480 uint8_t i;
481 uint8_t j;
482 char buffer[257];
483 int ret;
484 char *p;
485
486 memset(g_serial_num, 0, sizeof(g_serial_num));
487 memset(g_version, 0, sizeof(g_version));
488 memset(g_id, 0, sizeof(g_id));
489
490 tmp = spi_transfer16(0);
491
492 if (!(tmp >> 8))
493 return -EINVAL;
494
495 count = tmp & 0xff;
496
497 for (i = 0; i < count; ++i) {
498 memset(buffer, 0, sizeof(buffer));
499 ret = spi_read_bytes(buffer, sizeof(buffer)-1, &n);
500
501 if (ret < 0)
502 return ret;
503
504 switch (i) {
505 case 0:
506 if (n != 2)
507 return -EINVAL;
508
509 snprintf(
510 g_version,
511 sizeof(g_version),
512 "%x.%02x",
513 buffer[0],
514 buffer[1]
515 );
516 break;
517 case 1:
518 if (n >= sizeof(g_serial_num))
519 return -EINVAL;
520
521 memcpy(g_serial_num, buffer, sizeof(g_serial_num));
522 break;
523 case 2:
524 {
525 if (n >= sizeof(g_id))
526 return -EINVAL;
527
528 p = g_id;
529 for (j = 0; j < n; ++j)
530 p += sprintf(p, "%02x", buffer[j]);
531 }
532 break;
533 default:
534 break;
535 }
536 }
537
538 return 0;
539}
540
541static int pisnd_spi_init(struct device *dev)
542{
543 int ret;
544 struct spi_device *spi;
545
546 memset(g_serial_num, 0, sizeof(g_serial_num));
547 memset(g_id, 0, sizeof(g_id));
548 memset(g_version, 0, sizeof(g_version));
549
550 spi = pisnd_spi_find_device();
551
552 if (spi != NULL) {
553 printd("initializing spi!\n");
554 pisnd_spi_device = spi;
555 ret = spi_setup(pisnd_spi_device);
556 } else {
557 printe("SPI device not found, deferring!\n");
558 return -EPROBE_DEFER;
559 }
560
561 ret = pisnd_spi_gpio_init(dev);
562
563 if (ret < 0) {
564 printe("SPI GPIO init failed: %d\n", ret);
565 spi_dev_put(pisnd_spi_device);
566 pisnd_spi_device = NULL;
567 pisnd_spi_gpio_uninit();
568 return ret;
569 }
570
571 ret = spi_read_info();
572
573 if (ret < 0) {
574 printe("Reading card info failed: %d\n", ret);
575 spi_dev_put(pisnd_spi_device);
576 pisnd_spi_device = NULL;
577 pisnd_spi_gpio_uninit();
578 return ret;
579 }
580
581 /* Flash the LEDs. */
41409144 582 spi_transfer16(0xf008);
178f845a 583
584 ret = pisnd_spi_gpio_irq_init(dev);
585 if (ret < 0) {
586 printe("SPI irq request failed: %d\n", ret);
587 spi_dev_put(pisnd_spi_device);
588 pisnd_spi_device = NULL;
589 pisnd_spi_gpio_irq_uninit();
590 pisnd_spi_gpio_uninit();
591 }
592
593 ret = pisnd_init_workqueues();
594 if (ret != 0) {
595 printe("Workqueue initialization failed: %d\n", ret);
596 spi_dev_put(pisnd_spi_device);
597 pisnd_spi_device = NULL;
598 pisnd_spi_gpio_irq_uninit();
599 pisnd_spi_gpio_uninit();
600 pisnd_uninit_workqueues();
601 return ret;
602 }
603
604 if (pisnd_spi_has_more()) {
605 printd("data is available, scheduling from init\n");
606 pisnd_schedule_process(TASK_PROCESS);
607 }
608
609 return 0;
610}
611
612static void pisnd_spi_uninit(void)
613{
614 pisnd_uninit_workqueues();
615
616 spi_dev_put(pisnd_spi_device);
617 pisnd_spi_device = NULL;
618
619 pisnd_spi_gpio_irq_uninit();
620 pisnd_spi_gpio_uninit();
621}
622
41409144
GT
623static void pisnd_spi_flash_leds(uint8_t duration)
624{
625 g_ledFlashDuration = duration;
626 g_ledFlashDurationChanged = true;
627 printd("schedule from spi_flash_leds\n");
628 pisnd_schedule_process(TASK_PROCESS);
629}
630
178f845a 631static void pisnd_spi_send(uint8_t val)
632{
633 kfifo_put(&spi_fifo_out, val);
634 printd("schedule from spi_send\n");
635 pisnd_schedule_process(TASK_PROCESS);
636}
637
638static uint8_t pisnd_spi_recv(uint8_t *buffer, uint8_t length)
639{
640 return kfifo_out(&spi_fifo_in, buffer, length);
641}
642
643static void pisnd_spi_set_callback(pisnd_spi_recv_cb cb, void *data)
644{
645 g_recvData = data;
646 g_recvCallback = cb;
647}
648
649static const char *pisnd_spi_get_serial(void)
650{
651 if (strlen(g_serial_num))
652 return g_serial_num;
653
654 return "";
655}
656
657static const char *pisnd_spi_get_id(void)
658{
659 if (strlen(g_id))
660 return g_id;
661
662 return "";
663}
664
665static const char *pisnd_spi_get_version(void)
666{
667 if (strlen(g_version))
668 return g_version;
669
670 return "";
671}
672
673static const struct of_device_id pisound_of_match[] = {
674 { .compatible = "blokaslabs,pisound", },
675 { .compatible = "blokaslabs,pisound-spi", },
676 {},
677};
678
41409144
GT
679enum {
680 SWITCH = 0,
681 VOLUME = 1,
682};
683
684static int pisnd_ctl_info(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_info *uinfo)
686{
687 if (kcontrol->private_value == SWITCH) {
688 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
689 uinfo->count = 1;
690 uinfo->value.integer.min = 0;
691 uinfo->value.integer.max = 1;
692 return 0;
693 } else if (kcontrol->private_value == VOLUME) {
694 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
695 uinfo->count = 1;
696 uinfo->value.integer.min = 0;
697 uinfo->value.integer.max = 100;
698 return 0;
699 }
700 return -EINVAL;
701}
702
703static int pisnd_ctl_get(struct snd_kcontrol *kcontrol,
704 struct snd_ctl_elem_value *ucontrol)
705{
706 if (kcontrol->private_value == SWITCH) {
707 ucontrol->value.integer.value[0] = 1;
708 return 0;
709 } else if (kcontrol->private_value == VOLUME) {
710 ucontrol->value.integer.value[0] = 100;
711 return 0;
712 }
713
714 return -EINVAL;
715}
716
717static struct snd_kcontrol_new pisnd_ctl[] = {
718 {
719 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
720 .name = "PCM Playback Switch",
721 .index = 0,
722 .private_value = SWITCH,
723 .access = SNDRV_CTL_ELEM_ACCESS_READ,
724 .info = pisnd_ctl_info,
725 .get = pisnd_ctl_get,
726 },
727 {
728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
729 .name = "PCM Playback Volume",
730 .index = 0,
731 .private_value = VOLUME,
732 .access = SNDRV_CTL_ELEM_ACCESS_READ,
733 .info = pisnd_ctl_info,
734 .get = pisnd_ctl_get,
735 },
736};
737
738static int pisnd_ctl_init(struct snd_card *card)
739{
740 int err, i;
741
742 for (i = 0; i < ARRAY_SIZE(pisnd_ctl); ++i) {
743 err = snd_ctl_add(card, snd_ctl_new1(&pisnd_ctl[i], NULL));
744 if (err < 0)
745 return err;
746 }
747
748 return 0;
749}
750
751static int pisnd_ctl_uninit(void)
752{
753 return 0;
754}
755
178f845a 756static struct gpio_desc *osr0, *osr1, *osr2;
757static struct gpio_desc *reset;
758static struct gpio_desc *button;
759
760static int pisnd_hw_params(
761 struct snd_pcm_substream *substream,
762 struct snd_pcm_hw_params *params
763 )
764{
41409144
GT
765 struct snd_soc_pcm_runtime *rtd = substream->private_data;
766 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
767
768 /* pisound runs on fixed 32 clock counts per channel,
769 * as generated by the master ADC.
770 */
771 snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2);
772
178f845a 773 printd("rate = %d\n", params_rate(params));
774 printd("ch = %d\n", params_channels(params));
775 printd("bits = %u\n",
776 snd_pcm_format_physical_width(params_format(params)));
777 printd("format = %d\n", params_format(params));
778
779 gpiod_set_value(reset, false);
780
781 switch (params_rate(params)) {
782 case 48000:
783 gpiod_set_value(osr0, true);
784 gpiod_set_value(osr1, false);
785 gpiod_set_value(osr2, false);
786 break;
787 case 96000:
788 gpiod_set_value(osr0, true);
789 gpiod_set_value(osr1, true);
790 gpiod_set_value(osr2, false);
791 break;
792 case 192000:
793 gpiod_set_value(osr0, true);
794 gpiod_set_value(osr1, true);
795 gpiod_set_value(osr2, true);
796 break;
797 default:
798 printe("Unsupported rate %u!\n", params_rate(params));
799 return -EINVAL;
800 }
801
802 gpiod_set_value(reset, true);
803
804 return 0;
805}
806
807static unsigned int rates[3] = {
808 48000, 96000, 192000
809};
810
811static struct snd_pcm_hw_constraint_list constraints_rates = {
812 .count = ARRAY_SIZE(rates),
813 .list = rates,
814 .mask = 0,
815};
816
178f845a 817static int pisnd_startup(struct snd_pcm_substream *substream)
818{
819 int err = snd_pcm_hw_constraint_list(
820 substream->runtime,
821 0,
822 SNDRV_PCM_HW_PARAM_RATE,
823 &constraints_rates
824 );
825
826 if (err < 0)
827 return err;
828
41409144 829 err = snd_pcm_hw_constraint_single(
178f845a 830 substream->runtime,
41409144
GT
831 SNDRV_PCM_HW_PARAM_CHANNELS,
832 2
833 );
834
835 if (err < 0)
836 return err;
837
838 err = snd_pcm_hw_constraint_mask64(
839 substream->runtime,
840 SNDRV_PCM_HW_PARAM_FORMAT,
841 SNDRV_PCM_FMTBIT_S16_LE |
842 SNDRV_PCM_FMTBIT_S24_LE |
843 SNDRV_PCM_FMTBIT_S32_LE
178f845a 844 );
845
846 if (err < 0)
847 return err;
848
849 return 0;
850}
851
852static struct snd_soc_ops pisnd_ops = {
853 .startup = pisnd_startup,
854 .hw_params = pisnd_hw_params,
855};
856
857static struct snd_soc_dai_link pisnd_dai[] = {
858 {
859 .name = "pisound",
860 .stream_name = "pisound",
861 .cpu_dai_name = "bcm2708-i2s.0",
862 .codec_dai_name = "snd-soc-dummy-dai",
863 .platform_name = "bcm2708-i2s.0",
864 .codec_name = "snd-soc-dummy",
865 .dai_fmt =
866 SND_SOC_DAIFMT_I2S |
867 SND_SOC_DAIFMT_NB_NF |
868 SND_SOC_DAIFMT_CBM_CFM,
869 .ops = &pisnd_ops,
870 },
871};
872
873static int pisnd_card_probe(struct snd_soc_card *card)
874{
875 int err = pisnd_midi_init(card->snd_card);
876
41409144 877 if (err < 0) {
178f845a 878 printe("pisnd_midi_init failed: %d\n", err);
41409144
GT
879 return err;
880 }
178f845a 881
41409144
GT
882 err = pisnd_ctl_init(card->snd_card);
883 if (err < 0) {
884 printe("pisnd_ctl_init failed: %d\n", err);
885 return err;
886 }
887
888 return 0;
178f845a 889}
890
891static int pisnd_card_remove(struct snd_soc_card *card)
892{
41409144 893 pisnd_ctl_uninit();
178f845a 894 pisnd_midi_uninit();
895 return 0;
896}
897
898static struct snd_soc_card pisnd_card = {
899 .name = "pisound",
900 .owner = THIS_MODULE,
901 .dai_link = pisnd_dai,
902 .num_links = ARRAY_SIZE(pisnd_dai),
903 .probe = pisnd_card_probe,
904 .remove = pisnd_card_remove,
905};
906
907static int pisnd_init_gpio(struct device *dev)
908{
909 osr0 = gpiod_get_index(dev, "osr", 0, GPIOD_ASIS);
910 osr1 = gpiod_get_index(dev, "osr", 1, GPIOD_ASIS);
911 osr2 = gpiod_get_index(dev, "osr", 2, GPIOD_ASIS);
912
913 reset = gpiod_get_index(dev, "reset", 0, GPIOD_ASIS);
914
915 button = gpiod_get_index(dev, "button", 0, GPIOD_ASIS);
916
917 gpiod_direction_output(osr0, 1);
918 gpiod_direction_output(osr1, 1);
919 gpiod_direction_output(osr2, 1);
920 gpiod_direction_output(reset, 1);
921
922 gpiod_set_value(reset, false);
923 gpiod_set_value(osr0, true);
924 gpiod_set_value(osr1, false);
925 gpiod_set_value(osr2, false);
926 gpiod_set_value(reset, true);
927
928 gpiod_export(button, false);
929
930 return 0;
931}
932
933static int pisnd_uninit_gpio(void)
934{
935 int i;
936
937 struct gpio_desc **gpios[] = {
938 &osr0, &osr1, &osr2, &reset, &button,
939 };
940
941 gpiod_unexport(button);
942
943 for (i = 0; i < ARRAY_SIZE(gpios); ++i) {
944 if (*gpios[i] == NULL) {
945 printd("weird, GPIO[%d] is NULL already\n", i);
946 continue;
947 }
948
949 gpiod_put(*gpios[i]);
950 *gpios[i] = NULL;
951 }
952
953 return 0;
954}
955
956static struct kobject *pisnd_kobj;
957
958static ssize_t pisnd_serial_show(
959 struct kobject *kobj,
960 struct kobj_attribute *attr,
961 char *buf
962 )
963{
964 return sprintf(buf, "%s\n", pisnd_spi_get_serial());
965}
966
967static ssize_t pisnd_id_show(
968 struct kobject *kobj,
969 struct kobj_attribute *attr,
970 char *buf
971 )
972{
973 return sprintf(buf, "%s\n", pisnd_spi_get_id());
974}
975
976static ssize_t pisnd_version_show(
977 struct kobject *kobj,
978 struct kobj_attribute *attr,
979 char *buf
980 )
981{
982 return sprintf(buf, "%s\n", pisnd_spi_get_version());
983}
984
41409144
GT
985static ssize_t pisnd_led_store(
986 struct kobject *kobj,
987 struct kobj_attribute *attr,
988 const char *buf,
989 size_t length
990 )
991{
992 uint32_t timeout;
993 int err;
994
995 err = kstrtou32(buf, 10, &timeout);
996
997 if (err == 0 && timeout <= 255)
998 pisnd_spi_flash_leds(timeout);
999
1000 return length;
1001}
1002
178f845a 1003static struct kobj_attribute pisnd_serial_attribute =
41409144 1004 __ATTR(serial, 0444, pisnd_serial_show, NULL);
178f845a 1005static struct kobj_attribute pisnd_id_attribute =
41409144 1006 __ATTR(id, 0444, pisnd_id_show, NULL);
178f845a 1007static struct kobj_attribute pisnd_version_attribute =
41409144
GT
1008 __ATTR(version, 0444, pisnd_version_show, NULL);
1009static struct kobj_attribute pisnd_led_attribute =
1010 __ATTR(led, 0644, NULL, pisnd_led_store);
178f845a 1011
1012static struct attribute *attrs[] = {
1013 &pisnd_serial_attribute.attr,
1014 &pisnd_id_attribute.attr,
1015 &pisnd_version_attribute.attr,
41409144 1016 &pisnd_led_attribute.attr,
178f845a 1017 NULL
1018};
1019
1020static struct attribute_group attr_group = { .attrs = attrs };
1021
1022static int pisnd_probe(struct platform_device *pdev)
1023{
1024 int ret = 0;
1025 int i;
1026
1027 ret = pisnd_spi_init(&pdev->dev);
1028 if (ret < 0) {
1029 printe("pisnd_spi_init failed: %d\n", ret);
1030 return ret;
1031 }
1032
1033 printi("Detected pisound card:\n");
1034 printi("\tSerial: %s\n", pisnd_spi_get_serial());
1035 printi("\tVersion: %s\n", pisnd_spi_get_version());
1036 printi("\tId: %s\n", pisnd_spi_get_id());
1037
1038 pisnd_kobj = kobject_create_and_add("pisound", kernel_kobj);
1039 if (!pisnd_kobj) {
1040 pisnd_spi_uninit();
1041 return -ENOMEM;
1042 }
1043
1044 ret = sysfs_create_group(pisnd_kobj, &attr_group);
1045 if (ret < 0) {
1046 pisnd_spi_uninit();
1047 kobject_put(pisnd_kobj);
1048 return -ENOMEM;
1049 }
1050
1051 pisnd_init_gpio(&pdev->dev);
1052 pisnd_card.dev = &pdev->dev;
1053
1054 if (pdev->dev.of_node) {
1055 struct device_node *i2s_node;
1056
1057 i2s_node = of_parse_phandle(
1058 pdev->dev.of_node,
1059 "i2s-controller",
1060 0
1061 );
1062
1063 for (i = 0; i < pisnd_card.num_links; ++i) {
1064 struct snd_soc_dai_link *dai = &pisnd_dai[i];
1065
1066 if (i2s_node) {
1067 dai->cpu_dai_name = NULL;
1068 dai->cpu_of_node = i2s_node;
1069 dai->platform_name = NULL;
1070 dai->platform_of_node = i2s_node;
1071 dai->stream_name = pisnd_spi_get_serial();
1072 }
1073 }
1074 }
1075
1076 ret = snd_soc_register_card(&pisnd_card);
1077
1078 if (ret < 0) {
49dbf1af
PE
1079 if (ret != -EPROBE_DEFER)
1080 printe("snd_soc_register_card() failed: %d\n", ret);
178f845a 1081 pisnd_uninit_gpio();
1082 kobject_put(pisnd_kobj);
1083 pisnd_spi_uninit();
1084 }
1085
1086 return ret;
1087}
1088
1089static int pisnd_remove(struct platform_device *pdev)
1090{
1091 printi("Unloading.\n");
1092
1093 if (pisnd_kobj) {
1094 kobject_put(pisnd_kobj);
1095 pisnd_kobj = NULL;
1096 }
1097
1098 pisnd_spi_uninit();
1099
1100 /* Turn off */
1101 gpiod_set_value(reset, false);
1102 pisnd_uninit_gpio();
1103
1104 return snd_soc_unregister_card(&pisnd_card);
1105}
1106
1107MODULE_DEVICE_TABLE(of, pisound_of_match);
1108
1109static struct platform_driver pisnd_driver = {
1110 .driver = {
1111 .name = "snd-rpi-pisound",
1112 .owner = THIS_MODULE,
1113 .of_match_table = pisound_of_match,
1114 },
1115 .probe = pisnd_probe,
1116 .remove = pisnd_remove,
1117};
1118
1119module_platform_driver(pisnd_driver);
1120
1121MODULE_AUTHOR("Giedrius Trainavicius <giedrius@blokas.io>");
1122MODULE_DESCRIPTION("ASoC Driver for pisound, http://blokas.io/pisound");
1123MODULE_LICENSE("GPL v2");