1// SPDX-License-Identifier: GPL-2.0
2//
3// IDT821034 ALSA SoC driver
4//
5// Copyright 2022 CS GROUP France
6//
7// Author: Herve Codina <herve.codina@bootlin.com>
8
9#include <linux/bitrev.h>
10#include <linux/gpio/driver.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/spi/spi.h>
14#include <sound/pcm_params.h>
15#include <sound/soc.h>
16#include <sound/tlv.h>
17
18#define IDT821034_NB_CHANNEL 4
19
20struct idt821034_amp {
21 u16 gain;
22 bool is_muted;
23};
24
25struct idt821034 {
26 struct spi_device *spi;
27 struct mutex mutex;
28 u8 spi_tx_buf; /* Cannot use stack area for SPI (dma-safe memory) */
29 u8 spi_rx_buf; /* Cannot use stack area for SPI (dma-safe memory) */
30 struct {
31 u8 codec_conf;
32 struct {
33 u8 power;
34 u8 tx_slot;
35 u8 rx_slot;
36 u8 slic_conf;
37 u8 slic_control;
38 } ch[IDT821034_NB_CHANNEL];
39 } cache;
40 struct {
41 struct {
42 struct idt821034_amp amp_out;
43 struct idt821034_amp amp_in;
44 } ch[IDT821034_NB_CHANNEL];
45 } amps;
46 int max_ch_playback;
47 int max_ch_capture;
48 struct gpio_chip gpio_chip;
49};
50
51static int idt821034_8bit_write(struct idt821034 *idt821034, u8 val)
52{
53 struct spi_transfer xfer[] = {
54 {
55 .tx_buf = &idt821034->spi_tx_buf,
56 .len = 1,
57 }, {
58 .cs_off = 1,
59 .tx_buf = &idt821034->spi_tx_buf,
60 .len = 1,
61 }
62 };
63
64 idt821034->spi_tx_buf = val;
65
66 dev_vdbg(&idt821034->spi->dev, "spi xfer wr 0x%x\n", val);
67
68 return spi_sync_transfer(spi: idt821034->spi, xfers: xfer, num_xfers: 2);
69}
70
71static int idt821034_2x8bit_write(struct idt821034 *idt821034, u8 val1, u8 val2)
72{
73 int ret;
74
75 ret = idt821034_8bit_write(idt821034, val: val1);
76 if (ret)
77 return ret;
78 return idt821034_8bit_write(idt821034, val: val2);
79}
80
81static int idt821034_8bit_read(struct idt821034 *idt821034, u8 valw, u8 *valr)
82{
83 struct spi_transfer xfer[] = {
84 {
85 .tx_buf = &idt821034->spi_tx_buf,
86 .rx_buf = &idt821034->spi_rx_buf,
87 .len = 1,
88 }, {
89 .cs_off = 1,
90 .tx_buf = &idt821034->spi_tx_buf,
91 .len = 1,
92 }
93 };
94 int ret;
95
96 idt821034->spi_tx_buf = valw;
97
98 ret = spi_sync_transfer(spi: idt821034->spi, xfers: xfer, num_xfers: 2);
99 if (ret)
100 return ret;
101
102 *valr = idt821034->spi_rx_buf;
103
104 dev_vdbg(&idt821034->spi->dev, "spi xfer wr 0x%x, rd 0x%x\n",
105 valw, *valr);
106
107 return 0;
108}
109
110/* Available mode for the programming sequence */
111#define IDT821034_MODE_CODEC(_ch) (0x80 | ((_ch) << 2))
112#define IDT821034_MODE_SLIC(_ch) (0xD0 | ((_ch) << 2))
113#define IDT821034_MODE_GAIN(_ch) (0xC0 | ((_ch) << 2))
114
115/* Power values that can be used in 'power' (can be ORed) */
116#define IDT821034_CONF_PWRUP_TX BIT(1) /* from analog input to PCM */
117#define IDT821034_CONF_PWRUP_RX BIT(0) /* from PCM to analog output */
118
119static int idt821034_set_channel_power(struct idt821034 *idt821034, u8 ch, u8 power)
120{
121 u8 conf;
122 int ret;
123
124 dev_dbg(&idt821034->spi->dev, "set_channel_power(%u, 0x%x)\n", ch, power);
125
126 conf = IDT821034_MODE_CODEC(ch) | idt821034->cache.codec_conf;
127
128 if (power & IDT821034_CONF_PWRUP_RX) {
129 ret = idt821034_2x8bit_write(idt821034,
130 val1: conf | IDT821034_CONF_PWRUP_RX,
131 val2: idt821034->cache.ch[ch].rx_slot);
132 if (ret)
133 return ret;
134 }
135 if (power & IDT821034_CONF_PWRUP_TX) {
136 ret = idt821034_2x8bit_write(idt821034,
137 val1: conf | IDT821034_CONF_PWRUP_TX,
138 val2: idt821034->cache.ch[ch].tx_slot);
139 if (ret)
140 return ret;
141 }
142 if (!(power & (IDT821034_CONF_PWRUP_TX | IDT821034_CONF_PWRUP_RX))) {
143 ret = idt821034_2x8bit_write(idt821034, val1: conf, val2: 0);
144 if (ret)
145 return ret;
146 }
147
148 idt821034->cache.ch[ch].power = power;
149
150 return 0;
151}
152
153static u8 idt821034_get_channel_power(struct idt821034 *idt821034, u8 ch)
154{
155 return idt821034->cache.ch[ch].power;
156}
157
158/* Codec configuration values that can be used in 'codec_conf' (can be ORed) */
159#define IDT821034_CONF_ALAW_MODE BIT(5)
160#define IDT821034_CONF_DELAY_MODE BIT(4)
161
162static int idt821034_set_codec_conf(struct idt821034 *idt821034, u8 codec_conf)
163{
164 u8 conf;
165 u8 ts;
166 int ret;
167
168 dev_dbg(&idt821034->spi->dev, "set_codec_conf(0x%x)\n", codec_conf);
169
170 /* codec conf fields are common to all channel.
171 * Arbitrary use of channel 0 for this configuration.
172 */
173
174 /* Set Configuration Register */
175 conf = IDT821034_MODE_CODEC(0) | codec_conf;
176
177 /* Update conf value and timeslot register value according
178 * to cache values
179 */
180 if (idt821034->cache.ch[0].power & IDT821034_CONF_PWRUP_RX) {
181 conf |= IDT821034_CONF_PWRUP_RX;
182 ts = idt821034->cache.ch[0].rx_slot;
183 } else if (idt821034->cache.ch[0].power & IDT821034_CONF_PWRUP_TX) {
184 conf |= IDT821034_CONF_PWRUP_TX;
185 ts = idt821034->cache.ch[0].tx_slot;
186 } else {
187 ts = 0x00;
188 }
189
190 /* Write configuration register and time-slot register */
191 ret = idt821034_2x8bit_write(idt821034, val1: conf, val2: ts);
192 if (ret)
193 return ret;
194
195 idt821034->cache.codec_conf = codec_conf;
196 return 0;
197}
198
199static u8 idt821034_get_codec_conf(struct idt821034 *idt821034)
200{
201 return idt821034->cache.codec_conf;
202}
203
204/* Channel direction values that can be used in 'ch_dir' (can be ORed) */
205#define IDT821034_CH_RX BIT(0) /* from PCM to analog output */
206#define IDT821034_CH_TX BIT(1) /* from analog input to PCM */
207
208static int idt821034_set_channel_ts(struct idt821034 *idt821034, u8 ch, u8 ch_dir, u8 ts_num)
209{
210 u8 conf;
211 int ret;
212
213 dev_dbg(&idt821034->spi->dev, "set_channel_ts(%u, 0x%x, %d)\n", ch, ch_dir, ts_num);
214
215 conf = IDT821034_MODE_CODEC(ch) | idt821034->cache.codec_conf;
216
217 if (ch_dir & IDT821034_CH_RX) {
218 if (idt821034->cache.ch[ch].power & IDT821034_CONF_PWRUP_RX) {
219 ret = idt821034_2x8bit_write(idt821034,
220 val1: conf | IDT821034_CONF_PWRUP_RX,
221 val2: ts_num);
222 if (ret)
223 return ret;
224 }
225 idt821034->cache.ch[ch].rx_slot = ts_num;
226 }
227 if (ch_dir & IDT821034_CH_TX) {
228 if (idt821034->cache.ch[ch].power & IDT821034_CONF_PWRUP_TX) {
229 ret = idt821034_2x8bit_write(idt821034,
230 val1: conf | IDT821034_CONF_PWRUP_TX,
231 val2: ts_num);
232 if (ret)
233 return ret;
234 }
235 idt821034->cache.ch[ch].tx_slot = ts_num;
236 }
237
238 return 0;
239}
240
241/* SLIC direction values that can be used in 'slic_dir' (can be ORed) */
242#define IDT821034_SLIC_IO1_IN BIT(1)
243#define IDT821034_SLIC_IO0_IN BIT(0)
244
245static int idt821034_set_slic_conf(struct idt821034 *idt821034, u8 ch, u8 slic_dir)
246{
247 u8 conf;
248 int ret;
249
250 dev_dbg(&idt821034->spi->dev, "set_slic_conf(%u, 0x%x)\n", ch, slic_dir);
251
252 conf = IDT821034_MODE_SLIC(ch) | slic_dir;
253 ret = idt821034_2x8bit_write(idt821034, val1: conf, val2: idt821034->cache.ch[ch].slic_control);
254 if (ret)
255 return ret;
256
257 idt821034->cache.ch[ch].slic_conf = slic_dir;
258
259 return 0;
260}
261
262static u8 idt821034_get_slic_conf(struct idt821034 *idt821034, u8 ch)
263{
264 return idt821034->cache.ch[ch].slic_conf;
265}
266
267static int idt821034_write_slic_raw(struct idt821034 *idt821034, u8 ch, u8 slic_raw)
268{
269 u8 conf;
270 int ret;
271
272 dev_dbg(&idt821034->spi->dev, "write_slic_raw(%u, 0x%x)\n", ch, slic_raw);
273
274 /*
275 * On write, slic_raw is mapped as follow :
276 * b4: O_4
277 * b3: O_3
278 * b2: O_2
279 * b1: I/O_1
280 * b0: I/O_0
281 */
282
283 conf = IDT821034_MODE_SLIC(ch) | idt821034->cache.ch[ch].slic_conf;
284 ret = idt821034_2x8bit_write(idt821034, val1: conf, val2: slic_raw);
285 if (ret)
286 return ret;
287
288 idt821034->cache.ch[ch].slic_control = slic_raw;
289 return 0;
290}
291
292static u8 idt821034_get_written_slic_raw(struct idt821034 *idt821034, u8 ch)
293{
294 return idt821034->cache.ch[ch].slic_control;
295}
296
297static int idt821034_read_slic_raw(struct idt821034 *idt821034, u8 ch, u8 *slic_raw)
298{
299 u8 val;
300 int ret;
301
302 /*
303 * On read, slic_raw is mapped as follow :
304 * b7: I/O_0
305 * b6: I/O_1
306 * b5: O_2
307 * b4: O_3
308 * b3: O_4
309 * b2: I/O1_0, I/O_0 from channel 1 (no matter ch value)
310 * b1: I/O2_0, I/O_0 from channel 2 (no matter ch value)
311 * b2: I/O3_0, I/O_0 from channel 3 (no matter ch value)
312 */
313
314 val = IDT821034_MODE_SLIC(ch) | idt821034->cache.ch[ch].slic_conf;
315 ret = idt821034_8bit_write(idt821034, val);
316 if (ret)
317 return ret;
318
319 ret = idt821034_8bit_read(idt821034, valw: idt821034->cache.ch[ch].slic_control, valr: slic_raw);
320 if (ret)
321 return ret;
322
323 dev_dbg(&idt821034->spi->dev, "read_slic_raw(%i) 0x%x\n", ch, *slic_raw);
324
325 return 0;
326}
327
328/* Gain type values that can be used in 'gain_type' (cannot be ORed) */
329#define IDT821034_GAIN_RX (0 << 1) /* from PCM to analog output */
330#define IDT821034_GAIN_TX (1 << 1) /* from analog input to PCM */
331
332static int idt821034_set_gain_channel(struct idt821034 *idt821034, u8 ch,
333 u8 gain_type, u16 gain_val)
334{
335 u8 conf;
336 int ret;
337
338 dev_dbg(&idt821034->spi->dev, "set_gain_channel(%u, 0x%x, 0x%x-%d)\n",
339 ch, gain_type, gain_val, gain_val);
340
341 /*
342 * The gain programming coefficients should be calculated as:
343 * Transmit : Coeff_X = round [ gain_X0dB × gain_X ]
344 * Receive: Coeff_R = round [ gain_R0dB × gain_R ]
345 * where:
346 * gain_X0dB = 1820;
347 * gain_X is the target gain;
348 * Coeff_X should be in the range of 0 to 8192.
349 * gain_R0dB = 2506;
350 * gain_R is the target gain;
351 * Coeff_R should be in the range of 0 to 8192.
352 *
353 * A gain programming coefficient is 14-bit wide and in binary format.
354 * The 7 Most Significant Bits of the coefficient is called
355 * GA_MSB_Transmit for transmit path, or is called GA_MSB_Receive for
356 * receive path; The 7 Least Significant Bits of the coefficient is
357 * called GA_LSB_ Transmit for transmit path, or is called
358 * GA_LSB_Receive for receive path.
359 *
360 * An example is given below to clarify the calculation of the
361 * coefficient. To program a +3 dB gain in transmit path and a -3.5 dB
362 * gain in receive path:
363 *
364 * Linear Code of +3dB = 10^(3/20)= 1.412537545
365 * Coeff_X = round (1820 × 1.412537545) = 2571
366 * = 0b001010_00001011
367 * GA_MSB_Transmit = 0b0010100
368 * GA_LSB_Transmit = 0b0001011
369 *
370 * Linear Code of -3.5dB = 10^(-3.5/20) = 0.668343917
371 * Coeff_R= round (2506 × 0.668343917) = 1675
372 * = 0b0001101_0001011
373 * GA_MSB_Receive = 0b0001101
374 * GA_LSB_Receive = 0b0001011
375 */
376
377 conf = IDT821034_MODE_GAIN(ch) | gain_type;
378
379 ret = idt821034_2x8bit_write(idt821034, val1: conf | 0x00, val2: gain_val & 0x007F);
380 if (ret)
381 return ret;
382
383 ret = idt821034_2x8bit_write(idt821034, val1: conf | 0x01, val2: (gain_val >> 7) & 0x7F);
384 if (ret)
385 return ret;
386
387 return 0;
388}
389
390/* Id helpers used in controls and dapm */
391#define IDT821034_DIR_OUT (1 << 3)
392#define IDT821034_DIR_IN (0 << 3)
393#define IDT821034_ID(_ch, _dir) (((_ch) & 0x03) | (_dir))
394#define IDT821034_ID_OUT(_ch) IDT821034_ID(_ch, IDT821034_DIR_OUT)
395#define IDT821034_ID_IN(_ch) IDT821034_ID(_ch, IDT821034_DIR_IN)
396
397#define IDT821034_ID_GET_CHAN(_id) ((_id) & 0x03)
398#define IDT821034_ID_GET_DIR(_id) ((_id) & (1 << 3))
399#define IDT821034_ID_IS_OUT(_id) (IDT821034_ID_GET_DIR(_id) == IDT821034_DIR_OUT)
400
401static int idt821034_kctrl_gain_get(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
403{
404 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
405 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
406 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
407 int min = mc->min;
408 int max = mc->max;
409 unsigned int mask = (1 << fls(x: max)) - 1;
410 unsigned int invert = mc->invert;
411 int val;
412 u8 ch;
413
414 ch = IDT821034_ID_GET_CHAN(mc->reg);
415
416 mutex_lock(&idt821034->mutex);
417 if (IDT821034_ID_IS_OUT(mc->reg))
418 val = idt821034->amps.ch[ch].amp_out.gain;
419 else
420 val = idt821034->amps.ch[ch].amp_in.gain;
421 mutex_unlock(lock: &idt821034->mutex);
422
423 ucontrol->value.integer.value[0] = val & mask;
424 if (invert)
425 ucontrol->value.integer.value[0] = max - ucontrol->value.integer.value[0];
426 else
427 ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] - min;
428
429 return 0;
430}
431
432static int idt821034_kctrl_gain_put(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
434{
435 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
436 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
437 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
438 struct idt821034_amp *amp;
439 int min = mc->min;
440 int max = mc->max;
441 unsigned int mask = (1 << fls(x: max)) - 1;
442 unsigned int invert = mc->invert;
443 unsigned int val;
444 int ret;
445 u8 gain_type;
446 u8 ch;
447
448 val = ucontrol->value.integer.value[0];
449 if (val > max - min)
450 return -EINVAL;
451
452 if (invert)
453 val = (max - val) & mask;
454 else
455 val = (val + min) & mask;
456
457 ch = IDT821034_ID_GET_CHAN(mc->reg);
458
459 mutex_lock(&idt821034->mutex);
460
461 if (IDT821034_ID_IS_OUT(mc->reg)) {
462 amp = &idt821034->amps.ch[ch].amp_out;
463 gain_type = IDT821034_GAIN_RX;
464 } else {
465 amp = &idt821034->amps.ch[ch].amp_in;
466 gain_type = IDT821034_GAIN_TX;
467 }
468
469 if (amp->gain == val) {
470 ret = 0;
471 goto end;
472 }
473
474 if (!amp->is_muted) {
475 ret = idt821034_set_gain_channel(idt821034, ch, gain_type, gain_val: val);
476 if (ret)
477 goto end;
478 }
479
480 amp->gain = val;
481 ret = 1; /* The value changed */
482end:
483 mutex_unlock(lock: &idt821034->mutex);
484 return ret;
485}
486
487static int idt821034_kctrl_mute_get(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
489{
490 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
491 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
492 int id = kcontrol->private_value;
493 bool is_muted;
494 u8 ch;
495
496 ch = IDT821034_ID_GET_CHAN(id);
497
498 mutex_lock(&idt821034->mutex);
499 is_muted = IDT821034_ID_IS_OUT(id) ?
500 idt821034->amps.ch[ch].amp_out.is_muted :
501 idt821034->amps.ch[ch].amp_in.is_muted;
502 mutex_unlock(lock: &idt821034->mutex);
503
504 ucontrol->value.integer.value[0] = !is_muted;
505
506 return 0;
507}
508
509static int idt821034_kctrl_mute_put(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
513 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
514 int id = kcontrol->private_value;
515 struct idt821034_amp *amp;
516 bool is_mute;
517 u8 gain_type;
518 int ret;
519 u8 ch;
520
521 ch = IDT821034_ID_GET_CHAN(id);
522 is_mute = !ucontrol->value.integer.value[0];
523
524 mutex_lock(&idt821034->mutex);
525
526 if (IDT821034_ID_IS_OUT(id)) {
527 amp = &idt821034->amps.ch[ch].amp_out;
528 gain_type = IDT821034_GAIN_RX;
529 } else {
530 amp = &idt821034->amps.ch[ch].amp_in;
531 gain_type = IDT821034_GAIN_TX;
532 }
533
534 if (amp->is_muted == is_mute) {
535 ret = 0;
536 goto end;
537 }
538
539 ret = idt821034_set_gain_channel(idt821034, ch, gain_type,
540 gain_val: is_mute ? 0 : amp->gain);
541 if (ret)
542 goto end;
543
544 amp->is_muted = is_mute;
545 ret = 1; /* The value changed */
546end:
547 mutex_unlock(lock: &idt821034->mutex);
548 return ret;
549}
550
551static const DECLARE_TLV_DB_LINEAR(idt821034_gain_in, -6520, 1306);
552#define IDT821034_GAIN_IN_MIN_RAW 1 /* -65.20 dB -> 10^(-65.2/20.0) * 1820 = 1 */
553#define IDT821034_GAIN_IN_MAX_RAW 8191 /* 13.06 dB -> 10^(13.06/20.0) * 1820 = 8191 */
554#define IDT821034_GAIN_IN_INIT_RAW 1820 /* 0dB -> 10^(0/20) * 1820 = 1820 */
555
556static const DECLARE_TLV_DB_LINEAR(idt821034_gain_out, -6798, 1029);
557#define IDT821034_GAIN_OUT_MIN_RAW 1 /* -67.98 dB -> 10^(-67.98/20.0) * 2506 = 1*/
558#define IDT821034_GAIN_OUT_MAX_RAW 8191 /* 10.29 dB -> 10^(10.29/20.0) * 2506 = 8191 */
559#define IDT821034_GAIN_OUT_INIT_RAW 2506 /* 0dB -> 10^(0/20) * 2506 = 2506 */
560
561static const struct snd_kcontrol_new idt821034_controls[] = {
562 /* DAC volume control */
563 SOC_SINGLE_RANGE_EXT_TLV("DAC0 Playback Volume", IDT821034_ID_OUT(0), 0,
564 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,
565 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
566 idt821034_gain_out),
567 SOC_SINGLE_RANGE_EXT_TLV("DAC1 Playback Volume", IDT821034_ID_OUT(1), 0,
568 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,
569 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
570 idt821034_gain_out),
571 SOC_SINGLE_RANGE_EXT_TLV("DAC2 Playback Volume", IDT821034_ID_OUT(2), 0,
572 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,
573 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
574 idt821034_gain_out),
575 SOC_SINGLE_RANGE_EXT_TLV("DAC3 Playback Volume", IDT821034_ID_OUT(3), 0,
576 IDT821034_GAIN_OUT_MIN_RAW, IDT821034_GAIN_OUT_MAX_RAW,
577 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
578 idt821034_gain_out),
579
580 /* DAC mute control */
581 SOC_SINGLE_BOOL_EXT("DAC0 Playback Switch", IDT821034_ID_OUT(0),
582 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
583 SOC_SINGLE_BOOL_EXT("DAC1 Playback Switch", IDT821034_ID_OUT(1),
584 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
585 SOC_SINGLE_BOOL_EXT("DAC2 Playback Switch", IDT821034_ID_OUT(2),
586 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
587 SOC_SINGLE_BOOL_EXT("DAC3 Playback Switch", IDT821034_ID_OUT(3),
588 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
589
590 /* ADC volume control */
591 SOC_SINGLE_RANGE_EXT_TLV("ADC0 Capture Volume", IDT821034_ID_IN(0), 0,
592 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,
593 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
594 idt821034_gain_in),
595 SOC_SINGLE_RANGE_EXT_TLV("ADC1 Capture Volume", IDT821034_ID_IN(1), 0,
596 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,
597 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
598 idt821034_gain_in),
599 SOC_SINGLE_RANGE_EXT_TLV("ADC2 Capture Volume", IDT821034_ID_IN(2), 0,
600 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,
601 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
602 idt821034_gain_in),
603 SOC_SINGLE_RANGE_EXT_TLV("ADC3 Capture Volume", IDT821034_ID_IN(3), 0,
604 IDT821034_GAIN_IN_MIN_RAW, IDT821034_GAIN_IN_MAX_RAW,
605 0, idt821034_kctrl_gain_get, idt821034_kctrl_gain_put,
606 idt821034_gain_in),
607
608 /* ADC mute control */
609 SOC_SINGLE_BOOL_EXT("ADC0 Capture Switch", IDT821034_ID_IN(0),
610 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
611 SOC_SINGLE_BOOL_EXT("ADC1 Capture Switch", IDT821034_ID_IN(1),
612 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
613 SOC_SINGLE_BOOL_EXT("ADC2 Capture Switch", IDT821034_ID_IN(2),
614 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
615 SOC_SINGLE_BOOL_EXT("ADC3 Capture Switch", IDT821034_ID_IN(3),
616 idt821034_kctrl_mute_get, idt821034_kctrl_mute_put),
617};
618
619static int idt821034_power_event(struct snd_soc_dapm_widget *w,
620 struct snd_kcontrol *kcontrol, int event)
621{
622 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm);
623 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
624 unsigned int id = w->shift;
625 u8 power, mask;
626 int ret;
627 u8 ch;
628
629 ch = IDT821034_ID_GET_CHAN(id);
630 mask = IDT821034_ID_IS_OUT(id) ? IDT821034_CONF_PWRUP_RX : IDT821034_CONF_PWRUP_TX;
631
632 mutex_lock(&idt821034->mutex);
633
634 power = idt821034_get_channel_power(idt821034, ch);
635 if (SND_SOC_DAPM_EVENT_ON(event))
636 power |= mask;
637 else
638 power &= ~mask;
639 ret = idt821034_set_channel_power(idt821034, ch, power);
640
641 mutex_unlock(lock: &idt821034->mutex);
642
643 return ret;
644}
645
646static const struct snd_soc_dapm_widget idt821034_dapm_widgets[] = {
647 SND_SOC_DAPM_DAC_E("DAC0", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(0), 0,
648 idt821034_power_event,
649 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
650 SND_SOC_DAPM_DAC_E("DAC1", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(1), 0,
651 idt821034_power_event,
652 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
653 SND_SOC_DAPM_DAC_E("DAC2", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(2), 0,
654 idt821034_power_event,
655 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
656 SND_SOC_DAPM_DAC_E("DAC3", "Playback", SND_SOC_NOPM, IDT821034_ID_OUT(3), 0,
657 idt821034_power_event,
658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
659
660 SND_SOC_DAPM_OUTPUT("OUT0"),
661 SND_SOC_DAPM_OUTPUT("OUT1"),
662 SND_SOC_DAPM_OUTPUT("OUT2"),
663 SND_SOC_DAPM_OUTPUT("OUT3"),
664
665 SND_SOC_DAPM_DAC_E("ADC0", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(0), 0,
666 idt821034_power_event,
667 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
668 SND_SOC_DAPM_DAC_E("ADC1", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(1), 0,
669 idt821034_power_event,
670 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
671 SND_SOC_DAPM_DAC_E("ADC2", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(2), 0,
672 idt821034_power_event,
673 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
674 SND_SOC_DAPM_DAC_E("ADC3", "Capture", SND_SOC_NOPM, IDT821034_ID_IN(3), 0,
675 idt821034_power_event,
676 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
677
678 SND_SOC_DAPM_INPUT("IN0"),
679 SND_SOC_DAPM_INPUT("IN1"),
680 SND_SOC_DAPM_INPUT("IN2"),
681 SND_SOC_DAPM_INPUT("IN3"),
682};
683
684static const struct snd_soc_dapm_route idt821034_dapm_routes[] = {
685 { "OUT0", NULL, "DAC0" },
686 { "OUT1", NULL, "DAC1" },
687 { "OUT2", NULL, "DAC2" },
688 { "OUT3", NULL, "DAC3" },
689
690 { "ADC0", NULL, "IN0" },
691 { "ADC1", NULL, "IN1" },
692 { "ADC2", NULL, "IN2" },
693 { "ADC3", NULL, "IN3" },
694};
695
696static int idt821034_dai_set_tdm_slot(struct snd_soc_dai *dai,
697 unsigned int tx_mask, unsigned int rx_mask,
698 int slots, int width)
699{
700 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: dai->component);
701 unsigned int mask;
702 u8 slot;
703 int ret;
704 u8 ch;
705
706 switch (width) {
707 case 0: /* Not set -> default 8 */
708 case 8:
709 break;
710 default:
711 dev_err(dai->dev, "tdm slot width %d not supported\n", width);
712 return -EINVAL;
713 }
714
715 mask = tx_mask;
716 slot = 0;
717 ch = 0;
718 while (mask && ch < IDT821034_NB_CHANNEL) {
719 if (mask & 0x1) {
720 mutex_lock(&idt821034->mutex);
721 ret = idt821034_set_channel_ts(idt821034, ch, IDT821034_CH_RX, ts_num: slot);
722 mutex_unlock(lock: &idt821034->mutex);
723 if (ret) {
724 dev_err(dai->dev, "ch%u set tx tdm slot failed (%d)\n",
725 ch, ret);
726 return ret;
727 }
728 ch++;
729 }
730 mask >>= 1;
731 slot++;
732 }
733 if (mask) {
734 dev_err(dai->dev, "too much tx slots defined (mask = 0x%x) support max %d\n",
735 tx_mask, IDT821034_NB_CHANNEL);
736 return -EINVAL;
737 }
738 idt821034->max_ch_playback = ch;
739
740 mask = rx_mask;
741 slot = 0;
742 ch = 0;
743 while (mask && ch < IDT821034_NB_CHANNEL) {
744 if (mask & 0x1) {
745 mutex_lock(&idt821034->mutex);
746 ret = idt821034_set_channel_ts(idt821034, ch, IDT821034_CH_TX, ts_num: slot);
747 mutex_unlock(lock: &idt821034->mutex);
748 if (ret) {
749 dev_err(dai->dev, "ch%u set rx tdm slot failed (%d)\n",
750 ch, ret);
751 return ret;
752 }
753 ch++;
754 }
755 mask >>= 1;
756 slot++;
757 }
758 if (mask) {
759 dev_err(dai->dev, "too much rx slots defined (mask = 0x%x) support max %d\n",
760 rx_mask, IDT821034_NB_CHANNEL);
761 return -EINVAL;
762 }
763 idt821034->max_ch_capture = ch;
764
765 return 0;
766}
767
768static int idt821034_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
769{
770 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: dai->component);
771 u8 conf;
772 int ret;
773
774 mutex_lock(&idt821034->mutex);
775
776 conf = idt821034_get_codec_conf(idt821034);
777
778 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
779 case SND_SOC_DAIFMT_DSP_A:
780 conf |= IDT821034_CONF_DELAY_MODE;
781 break;
782 case SND_SOC_DAIFMT_DSP_B:
783 conf &= ~IDT821034_CONF_DELAY_MODE;
784 break;
785 default:
786 dev_err(dai->dev, "Unsupported DAI format 0x%x\n",
787 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
788 ret = -EINVAL;
789 goto end;
790 }
791 ret = idt821034_set_codec_conf(idt821034, codec_conf: conf);
792end:
793 mutex_unlock(lock: &idt821034->mutex);
794 return ret;
795}
796
797static int idt821034_dai_hw_params(struct snd_pcm_substream *substream,
798 struct snd_pcm_hw_params *params,
799 struct snd_soc_dai *dai)
800{
801 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: dai->component);
802 u8 conf;
803 int ret;
804
805 mutex_lock(&idt821034->mutex);
806
807 conf = idt821034_get_codec_conf(idt821034);
808
809 switch (params_format(p: params)) {
810 case SNDRV_PCM_FORMAT_A_LAW:
811 conf |= IDT821034_CONF_ALAW_MODE;
812 break;
813 case SNDRV_PCM_FORMAT_MU_LAW:
814 conf &= ~IDT821034_CONF_ALAW_MODE;
815 break;
816 default:
817 dev_err(dai->dev, "Unsupported PCM format 0x%x\n",
818 params_format(params));
819 ret = -EINVAL;
820 goto end;
821 }
822 ret = idt821034_set_codec_conf(idt821034, codec_conf: conf);
823end:
824 mutex_unlock(lock: &idt821034->mutex);
825 return ret;
826}
827
828static const unsigned int idt821034_sample_bits[] = {8};
829
830static struct snd_pcm_hw_constraint_list idt821034_sample_bits_constr = {
831 .list = idt821034_sample_bits,
832 .count = ARRAY_SIZE(idt821034_sample_bits),
833};
834
835static int idt821034_dai_startup(struct snd_pcm_substream *substream,
836 struct snd_soc_dai *dai)
837{
838 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: dai->component);
839 unsigned int max_ch = 0;
840 int ret;
841
842 max_ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
843 idt821034->max_ch_playback : idt821034->max_ch_capture;
844
845 /*
846 * Disable stream support (min = 0, max = 0) if no timeslots were
847 * configured otherwise, limit the number of channels to those
848 * configured.
849 */
850 ret = snd_pcm_hw_constraint_minmax(runtime: substream->runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
851 min: max_ch ? 1 : 0, max: max_ch);
852 if (ret < 0)
853 return ret;
854
855 ret = snd_pcm_hw_constraint_list(runtime: substream->runtime, cond: 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
856 l: &idt821034_sample_bits_constr);
857 if (ret)
858 return ret;
859
860 return 0;
861}
862
863static u64 idt821034_dai_formats[] = {
864 SND_SOC_POSSIBLE_DAIFMT_DSP_A |
865 SND_SOC_POSSIBLE_DAIFMT_DSP_B,
866};
867
868static const struct snd_soc_dai_ops idt821034_dai_ops = {
869 .startup = idt821034_dai_startup,
870 .hw_params = idt821034_dai_hw_params,
871 .set_tdm_slot = idt821034_dai_set_tdm_slot,
872 .set_fmt = idt821034_dai_set_fmt,
873 .auto_selectable_formats = idt821034_dai_formats,
874 .num_auto_selectable_formats = ARRAY_SIZE(idt821034_dai_formats),
875};
876
877static struct snd_soc_dai_driver idt821034_dai_driver = {
878 .name = "idt821034",
879 .playback = {
880 .stream_name = "Playback",
881 .channels_min = 1,
882 .channels_max = IDT821034_NB_CHANNEL,
883 .rates = SNDRV_PCM_RATE_8000,
884 .formats = SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
885 },
886 .capture = {
887 .stream_name = "Capture",
888 .channels_min = 1,
889 .channels_max = IDT821034_NB_CHANNEL,
890 .rates = SNDRV_PCM_RATE_8000,
891 .formats = SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
892 },
893 .ops = &idt821034_dai_ops,
894};
895
896static int idt821034_reset_audio(struct idt821034 *idt821034)
897{
898 int ret;
899 u8 i;
900
901 mutex_lock(&idt821034->mutex);
902
903 ret = idt821034_set_codec_conf(idt821034, codec_conf: 0);
904 if (ret)
905 goto end;
906
907 for (i = 0; i < IDT821034_NB_CHANNEL; i++) {
908 idt821034->amps.ch[i].amp_out.gain = IDT821034_GAIN_OUT_INIT_RAW;
909 idt821034->amps.ch[i].amp_out.is_muted = false;
910 ret = idt821034_set_gain_channel(idt821034, ch: i, IDT821034_GAIN_RX,
911 gain_val: idt821034->amps.ch[i].amp_out.gain);
912 if (ret)
913 goto end;
914
915 idt821034->amps.ch[i].amp_in.gain = IDT821034_GAIN_IN_INIT_RAW;
916 idt821034->amps.ch[i].amp_in.is_muted = false;
917 ret = idt821034_set_gain_channel(idt821034, ch: i, IDT821034_GAIN_TX,
918 gain_val: idt821034->amps.ch[i].amp_in.gain);
919 if (ret)
920 goto end;
921
922 ret = idt821034_set_channel_power(idt821034, ch: i, power: 0);
923 if (ret)
924 goto end;
925 }
926
927 ret = 0;
928end:
929 mutex_unlock(lock: &idt821034->mutex);
930 return ret;
931}
932
933static int idt821034_component_probe(struct snd_soc_component *component)
934{
935 struct idt821034 *idt821034 = snd_soc_component_get_drvdata(c: component);
936 int ret;
937
938 /* reset idt821034 audio part*/
939 ret = idt821034_reset_audio(idt821034);
940 if (ret)
941 return ret;
942
943 return 0;
944}
945
946static const struct snd_soc_component_driver idt821034_component_driver = {
947 .probe = idt821034_component_probe,
948 .controls = idt821034_controls,
949 .num_controls = ARRAY_SIZE(idt821034_controls),
950 .dapm_widgets = idt821034_dapm_widgets,
951 .num_dapm_widgets = ARRAY_SIZE(idt821034_dapm_widgets),
952 .dapm_routes = idt821034_dapm_routes,
953 .num_dapm_routes = ARRAY_SIZE(idt821034_dapm_routes),
954 .endianness = 1,
955};
956
957#define IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(_offset) (((_offset) / 5) % 4)
958#define IDT821034_GPIO_OFFSET_TO_SLIC_MASK(_offset) BIT((_offset) % 5)
959
960static void idt821034_chip_gpio_set(struct gpio_chip *c, unsigned int offset, int val)
961{
962 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);
963 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);
964 struct idt821034 *idt821034 = gpiochip_get_data(gc: c);
965 u8 slic_raw;
966 int ret;
967
968 mutex_lock(&idt821034->mutex);
969
970 slic_raw = idt821034_get_written_slic_raw(idt821034, ch);
971 if (val)
972 slic_raw |= mask;
973 else
974 slic_raw &= ~mask;
975 ret = idt821034_write_slic_raw(idt821034, ch, slic_raw);
976 if (ret) {
977 dev_err(&idt821034->spi->dev, "set gpio %d (%u, 0x%x) failed (%d)\n",
978 offset, ch, mask, ret);
979 }
980
981 mutex_unlock(lock: &idt821034->mutex);
982}
983
984static int idt821034_chip_gpio_get(struct gpio_chip *c, unsigned int offset)
985{
986 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);
987 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);
988 struct idt821034 *idt821034 = gpiochip_get_data(gc: c);
989 u8 slic_raw;
990 int ret;
991
992 mutex_lock(&idt821034->mutex);
993 ret = idt821034_read_slic_raw(idt821034, ch, slic_raw: &slic_raw);
994 mutex_unlock(lock: &idt821034->mutex);
995 if (ret) {
996 dev_err(&idt821034->spi->dev, "get gpio %d (%u, 0x%x) failed (%d)\n",
997 offset, ch, mask, ret);
998 return ret;
999 }
1000
1001 /*
1002 * SLIC IOs are read in reverse order compared to write.
1003 * Reverse the read value here in order to have IO0 at lsb (ie same
1004 * order as write)
1005 */
1006 return !!(bitrev8(slic_raw) & mask);
1007}
1008
1009static int idt821034_chip_get_direction(struct gpio_chip *c, unsigned int offset)
1010{
1011 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);
1012 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);
1013 struct idt821034 *idt821034 = gpiochip_get_data(gc: c);
1014 u8 slic_dir;
1015
1016 mutex_lock(&idt821034->mutex);
1017 slic_dir = idt821034_get_slic_conf(idt821034, ch);
1018 mutex_unlock(lock: &idt821034->mutex);
1019
1020 return slic_dir & mask ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
1021}
1022
1023static int idt821034_chip_direction_input(struct gpio_chip *c, unsigned int offset)
1024{
1025 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);
1026 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);
1027 struct idt821034 *idt821034 = gpiochip_get_data(gc: c);
1028 u8 slic_conf;
1029 int ret;
1030
1031 /* Only IO0 and IO1 can be set as input */
1032 if (mask & ~(IDT821034_SLIC_IO1_IN | IDT821034_SLIC_IO0_IN))
1033 return -EPERM;
1034
1035 mutex_lock(&idt821034->mutex);
1036
1037 slic_conf = idt821034_get_slic_conf(idt821034, ch) | mask;
1038
1039 ret = idt821034_set_slic_conf(idt821034, ch, slic_dir: slic_conf);
1040 if (ret) {
1041 dev_err(&idt821034->spi->dev, "dir in gpio %d (%u, 0x%x) failed (%d)\n",
1042 offset, ch, mask, ret);
1043 }
1044
1045 mutex_unlock(lock: &idt821034->mutex);
1046 return ret;
1047}
1048
1049static int idt821034_chip_direction_output(struct gpio_chip *c, unsigned int offset, int val)
1050{
1051 u8 ch = IDT821034_GPIO_OFFSET_TO_SLIC_CHANNEL(offset);
1052 u8 mask = IDT821034_GPIO_OFFSET_TO_SLIC_MASK(offset);
1053 struct idt821034 *idt821034 = gpiochip_get_data(gc: c);
1054 u8 slic_conf;
1055 int ret;
1056
1057 idt821034_chip_gpio_set(c, offset, val);
1058
1059 mutex_lock(&idt821034->mutex);
1060
1061 slic_conf = idt821034_get_slic_conf(idt821034, ch) & ~mask;
1062
1063 ret = idt821034_set_slic_conf(idt821034, ch, slic_dir: slic_conf);
1064 if (ret) {
1065 dev_err(&idt821034->spi->dev, "dir in gpio %d (%u, 0x%x) failed (%d)\n",
1066 offset, ch, mask, ret);
1067 }
1068
1069 mutex_unlock(lock: &idt821034->mutex);
1070 return ret;
1071}
1072
1073static int idt821034_reset_gpio(struct idt821034 *idt821034)
1074{
1075 int ret;
1076 u8 i;
1077
1078 mutex_lock(&idt821034->mutex);
1079
1080 /* IO0 and IO1 as input for all channels and output IO set to 0 */
1081 for (i = 0; i < IDT821034_NB_CHANNEL; i++) {
1082 ret = idt821034_set_slic_conf(idt821034, ch: i,
1083 IDT821034_SLIC_IO1_IN | IDT821034_SLIC_IO0_IN);
1084 if (ret)
1085 goto end;
1086
1087 ret = idt821034_write_slic_raw(idt821034, ch: i, slic_raw: 0);
1088 if (ret)
1089 goto end;
1090
1091 }
1092 ret = 0;
1093end:
1094 mutex_unlock(lock: &idt821034->mutex);
1095 return ret;
1096}
1097
1098static int idt821034_gpio_init(struct idt821034 *idt821034)
1099{
1100 int ret;
1101
1102 ret = idt821034_reset_gpio(idt821034);
1103 if (ret)
1104 return ret;
1105
1106 idt821034->gpio_chip.owner = THIS_MODULE;
1107 idt821034->gpio_chip.label = dev_name(dev: &idt821034->spi->dev);
1108 idt821034->gpio_chip.parent = &idt821034->spi->dev;
1109 idt821034->gpio_chip.base = -1;
1110 idt821034->gpio_chip.ngpio = 5 * 4; /* 5 GPIOs on 4 channels */
1111 idt821034->gpio_chip.get_direction = idt821034_chip_get_direction;
1112 idt821034->gpio_chip.direction_input = idt821034_chip_direction_input;
1113 idt821034->gpio_chip.direction_output = idt821034_chip_direction_output;
1114 idt821034->gpio_chip.get = idt821034_chip_gpio_get;
1115 idt821034->gpio_chip.set = idt821034_chip_gpio_set;
1116 idt821034->gpio_chip.can_sleep = true;
1117
1118 return devm_gpiochip_add_data(&idt821034->spi->dev, &idt821034->gpio_chip,
1119 idt821034);
1120}
1121
1122static int idt821034_spi_probe(struct spi_device *spi)
1123{
1124 struct idt821034 *idt821034;
1125 int ret;
1126
1127 spi->bits_per_word = 8;
1128 ret = spi_setup(spi);
1129 if (ret < 0)
1130 return ret;
1131
1132 idt821034 = devm_kzalloc(dev: &spi->dev, size: sizeof(*idt821034), GFP_KERNEL);
1133 if (!idt821034)
1134 return -ENOMEM;
1135
1136 idt821034->spi = spi;
1137
1138 mutex_init(&idt821034->mutex);
1139
1140 spi_set_drvdata(spi, data: idt821034);
1141
1142 ret = devm_snd_soc_register_component(dev: &spi->dev, component_driver: &idt821034_component_driver,
1143 dai_drv: &idt821034_dai_driver, num_dai: 1);
1144 if (ret)
1145 return ret;
1146
1147 if (IS_ENABLED(CONFIG_GPIOLIB))
1148 return idt821034_gpio_init(idt821034);
1149
1150 return 0;
1151}
1152
1153static const struct of_device_id idt821034_of_match[] = {
1154 { .compatible = "renesas,idt821034", },
1155 { }
1156};
1157MODULE_DEVICE_TABLE(of, idt821034_of_match);
1158
1159static const struct spi_device_id idt821034_id_table[] = {
1160 { "idt821034", 0 },
1161 { }
1162};
1163MODULE_DEVICE_TABLE(spi, idt821034_id_table);
1164
1165static struct spi_driver idt821034_spi_driver = {
1166 .driver = {
1167 .name = "idt821034",
1168 .of_match_table = idt821034_of_match,
1169 },
1170 .id_table = idt821034_id_table,
1171 .probe = idt821034_spi_probe,
1172};
1173
1174module_spi_driver(idt821034_spi_driver);
1175
1176MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
1177MODULE_DESCRIPTION("IDT821034 ALSA SoC driver");
1178MODULE_LICENSE("GPL");
1179

source code of linux/sound/soc/codecs/idt821034.c