Lines Matching +full:ch3 +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0
3 // peb2466.c -- Infineon PEB2466 ALSA SoC driver
29 #define PEB2466_TLV_SIZE (sizeof((unsigned int []){TLV_DB_SCALE_ITEM(0, 0, 0)}) / \
43 u8 spi_tx_buf[2 + 8]; /* Cannot use stack area for SPI (dma-safe memory) */
44 u8 spi_rx_buf[2 + 8]; /* Cannot use stack area for SPI (dma-safe memory) */
69 #define PEB2466_CMD_W (0 << 5)
71 #define PEB2466_CMD_MASK 0x18
72 #define PEB2466_CMD_XOP 0x18 /* XOP is 0bxxx11xxx */
73 #define PEB2466_CMD_SOP 0x10 /* SOP is 0bxxx10xxx */
74 #define PEB2466_CMD_COP 0x00 /* COP is 0bxxx0xxxx, handle 0bxxx00xxx */
75 #define PEB2466_CMD_COP1 0x08 /* COP is 0bxxx0xxxx, handle 0bxxx01xxx */
81 #define PEB2466_CR0(_ch) PEB2466_MAKE_SOP(_ch, 0x0)
88 #define PEB2466_CR0_THSEL_MASK (0x3 << 0)
89 #define PEB2466_CR0_THSEL(_set) ((_set) << 0)
91 #define PEB2466_CR1(_ch) PEB2466_MAKE_SOP(_ch, 0x1)
97 #define PEB2466_CR1_LAW_ALAW (0 << 3)
99 #define PEB2466_CR1_PU (1 << 0)
101 #define PEB2466_CR2(_ch) PEB2466_MAKE_SOP(_ch, 0x2)
102 #define PEB2466_CR3(_ch) PEB2466_MAKE_SOP(_ch, 0x3)
103 #define PEB2466_CR4(_ch) PEB2466_MAKE_SOP(_ch, 0x4)
104 #define PEB2466_CR5(_ch) PEB2466_MAKE_SOP(_ch, 0x5)
106 #define PEB2466_XR0 PEB2466_MAKE_XOP(0x0)
107 #define PEB2466_XR1 PEB2466_MAKE_XOP(0x1)
108 #define PEB2466_XR2 PEB2466_MAKE_XOP(0x2)
109 #define PEB2466_XR3 PEB2466_MAKE_XOP(0x3)
110 #define PEB2466_XR4 PEB2466_MAKE_XOP(0x4)
111 #define PEB2466_XR5 PEB2466_MAKE_XOP(0x5)
112 #define PEB2466_XR5_MCLK_1536 (0x0 << 6)
113 #define PEB2466_XR5_MCLK_2048 (0x1 << 6)
114 #define PEB2466_XR5_MCLK_4096 (0x2 << 6)
115 #define PEB2466_XR5_MCLK_8192 (0x3 << 6)
117 #define PEB2466_XR6 PEB2466_MAKE_XOP(0x6)
118 #define PEB2466_XR6_PCM_OFFSET(_off) ((_off) << 0)
120 #define PEB2466_XR7 PEB2466_MAKE_XOP(0x7)
122 #define PEB2466_TH_FILTER_P1(_ch) PEB2466_MAKE_COP(_ch, 0x0)
123 #define PEB2466_TH_FILTER_P2(_ch) PEB2466_MAKE_COP(_ch, 0x1)
124 #define PEB2466_TH_FILTER_P3(_ch) PEB2466_MAKE_COP(_ch, 0x2)
125 #define PEB2466_IMR1_FILTER_P1(_ch) PEB2466_MAKE_COP(_ch, 0x4)
126 #define PEB2466_IMR1_FILTER_P2(_ch) PEB2466_MAKE_COP(_ch, 0x5)
127 #define PEB2466_FRX_FILTER(_ch) PEB2466_MAKE_COP(_ch, 0x6)
128 #define PEB2466_FRR_FILTER(_ch) PEB2466_MAKE_COP(_ch, 0x7)
129 #define PEB2466_AX_FILTER(_ch) PEB2466_MAKE_COP(_ch, 0x8)
130 #define PEB2466_AR_FILTER(_ch) PEB2466_MAKE_COP(_ch, 0x9)
131 #define PEB2466_TG1(_ch) PEB2466_MAKE_COP(_ch, 0xc)
132 #define PEB2466_TG2(_ch) PEB2466_MAKE_COP(_ch, 0xd)
137 .tx_buf = &peb2466->spi_tx_buf, in peb2466_write_byte()
141 peb2466->spi_tx_buf[0] = cmd | PEB2466_CMD_W; in peb2466_write_byte()
142 peb2466->spi_tx_buf[1] = val; in peb2466_write_byte()
144 dev_dbg(&peb2466->spi->dev, "write byte (cmd %02x) %02x\n", in peb2466_write_byte()
145 peb2466->spi_tx_buf[0], peb2466->spi_tx_buf[1]); in peb2466_write_byte()
147 return spi_sync_transfer(peb2466->spi, &xfer, 1); in peb2466_write_byte()
153 .tx_buf = &peb2466->spi_tx_buf, in peb2466_read_byte()
154 .rx_buf = &peb2466->spi_rx_buf, in peb2466_read_byte()
159 peb2466->spi_tx_buf[0] = cmd | PEB2466_CMD_R; in peb2466_read_byte()
161 ret = spi_sync_transfer(peb2466->spi, &xfer, 1); in peb2466_read_byte()
165 if (peb2466->spi_rx_buf[1] != 0x81) { in peb2466_read_byte()
166 dev_err(&peb2466->spi->dev, in peb2466_read_byte()
167 "spi xfer rd (cmd %02x) invalid ident byte (0x%02x)\n", in peb2466_read_byte()
168 peb2466->spi_tx_buf[0], peb2466->spi_rx_buf[1]); in peb2466_read_byte()
169 return -EILSEQ; in peb2466_read_byte()
172 *val = peb2466->spi_rx_buf[2]; in peb2466_read_byte()
174 dev_dbg(&peb2466->spi->dev, "read byte (cmd %02x) %02x\n", in peb2466_read_byte()
175 peb2466->spi_tx_buf[0], *val); in peb2466_read_byte()
177 return 0; in peb2466_read_byte()
183 .tx_buf = &peb2466->spi_tx_buf, in peb2466_write_buf()
188 return -EINVAL; in peb2466_write_buf()
190 peb2466->spi_tx_buf[0] = cmd | PEB2466_CMD_W; in peb2466_write_buf()
191 memcpy(&peb2466->spi_tx_buf[1], buf, len); in peb2466_write_buf()
193 dev_dbg(&peb2466->spi->dev, "write buf (cmd %02x, %u) %*ph\n", in peb2466_write_buf()
194 peb2466->spi_tx_buf[0], len, len, &peb2466->spi_tx_buf[1]); in peb2466_write_buf()
196 return spi_sync_transfer(peb2466->spi, &xfer, 1); in peb2466_write_buf()
214 dev_err(&peb2466->spi->dev, "Not a XOP or SOP command\n"); in peb2466_reg_write()
215 ret = -EINVAL; in peb2466_reg_write()
236 dev_err(&peb2466->spi->dev, "Not a XOP or SOP command\n"); in peb2466_reg_read()
237 ret = -EINVAL; in peb2466_reg_read()
246 .max_register = 0xFF,
256 (struct peb2466_lkup_ctrl *)kcontrol->private_value; in peb2466_lkup_ctrl_info()
258 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in peb2466_lkup_ctrl_info()
259 uinfo->count = 1; in peb2466_lkup_ctrl_info()
260 uinfo->value.integer.min = 0; in peb2466_lkup_ctrl_info()
261 uinfo->value.integer.max = lkup_ctrl->lookup->count - 1; in peb2466_lkup_ctrl_info()
262 return 0; in peb2466_lkup_ctrl_info()
269 (struct peb2466_lkup_ctrl *)kcontrol->private_value; in peb2466_lkup_ctrl_get()
271 ucontrol->value.integer.value[0] = lkup_ctrl->index; in peb2466_lkup_ctrl_get()
272 return 0; in peb2466_lkup_ctrl_get()
279 (struct peb2466_lkup_ctrl *)kcontrol->private_value; in peb2466_lkup_ctrl_put()
285 index = ucontrol->value.integer.value[0]; in peb2466_lkup_ctrl_put()
286 if (index >= lkup_ctrl->lookup->count) in peb2466_lkup_ctrl_put()
287 return -EINVAL; in peb2466_lkup_ctrl_put()
289 if (index == lkup_ctrl->index) in peb2466_lkup_ctrl_put()
290 return 0; in peb2466_lkup_ctrl_put()
292 ret = peb2466_write_buf(peb2466, lkup_ctrl->reg, in peb2466_lkup_ctrl_put()
293 lkup_ctrl->lookup->table[index], 4); in peb2466_lkup_ctrl_put()
297 lkup_ctrl->index = index; in peb2466_lkup_ctrl_put()
305 DECLARE_TLV_DB_SCALE(tlv_array, min_val, step, 0); in peb2466_add_lkup_ctrl()
306 struct snd_kcontrol_new control = {0}; in peb2466_add_lkup_ctrl()
308 BUILD_BUG_ON(sizeof(lkup_ctrl->tlv_array) < sizeof(tlv_array)); in peb2466_add_lkup_ctrl()
309 memcpy(lkup_ctrl->tlv_array, tlv_array, sizeof(tlv_array)); in peb2466_add_lkup_ctrl()
315 control.tlv.p = lkup_ctrl->tlv_array; in peb2466_add_lkup_ctrl()
334 [PEB2466_TONE_697HZ] = {0x0a, 0x33, 0x5a, 0x2c},
335 [PEB2466_TONE_800HZ] = {0x12, 0xD6, 0x5a, 0xc0},
336 [PEB2466_TONE_950HZ] = {0x1c, 0xf0, 0x5c, 0xc0},
337 [PEB2466_TONE_1000HZ] = {0}, /* lookup value not used for 1000Hz */
338 [PEB2466_TONE_1008HZ] = {0x1a, 0xae, 0x57, 0x70},
339 [PEB2466_TONE_2000HZ] = {0x00, 0x80, 0x50, 0x09},
352 [0] = {
353 SOC_ENUM_SINGLE(PEB2466_TG1(0), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
355 SOC_ENUM_SINGLE(PEB2466_TG2(0), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
359 SOC_ENUM_SINGLE(PEB2466_TG1(1), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
361 SOC_ENUM_SINGLE(PEB2466_TG2(1), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
365 SOC_ENUM_SINGLE(PEB2466_TG1(2), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
367 SOC_ENUM_SINGLE(PEB2466_TG2(2), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
371 SOC_ENUM_SINGLE(PEB2466_TG1(3), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
373 SOC_ENUM_SINGLE(PEB2466_TG2(3), 0, ARRAY_SIZE(peb2466_tone_freq_txt),
383 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in peb2466_tg_freq_get()
385 switch (e->reg) { in peb2466_tg_freq_get()
386 case PEB2466_TG1(0): in peb2466_tg_freq_get()
387 ucontrol->value.enumerated.item[0] = peb2466->ch[0].tg1_freq_item; in peb2466_tg_freq_get()
389 case PEB2466_TG2(0): in peb2466_tg_freq_get()
390 ucontrol->value.enumerated.item[0] = peb2466->ch[0].tg2_freq_item; in peb2466_tg_freq_get()
393 ucontrol->value.enumerated.item[0] = peb2466->ch[1].tg1_freq_item; in peb2466_tg_freq_get()
396 ucontrol->value.enumerated.item[0] = peb2466->ch[1].tg2_freq_item; in peb2466_tg_freq_get()
399 ucontrol->value.enumerated.item[0] = peb2466->ch[2].tg1_freq_item; in peb2466_tg_freq_get()
402 ucontrol->value.enumerated.item[0] = peb2466->ch[2].tg2_freq_item; in peb2466_tg_freq_get()
405 ucontrol->value.enumerated.item[0] = peb2466->ch[3].tg1_freq_item; in peb2466_tg_freq_get()
408 ucontrol->value.enumerated.item[0] = peb2466->ch[3].tg2_freq_item; in peb2466_tg_freq_get()
411 return -EINVAL; in peb2466_tg_freq_get()
413 return 0; in peb2466_tg_freq_get()
421 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in peb2466_tg_freq_put()
427 index = ucontrol->value.enumerated.item[0]; in peb2466_tg_freq_put()
430 return -EINVAL; in peb2466_tg_freq_put()
432 switch (e->reg) { in peb2466_tg_freq_put()
433 case PEB2466_TG1(0): in peb2466_tg_freq_put()
434 tg_freq_item = &peb2466->ch[0].tg1_freq_item; in peb2466_tg_freq_put()
435 cr1_reg = PEB2466_CR1(0); in peb2466_tg_freq_put()
438 case PEB2466_TG2(0): in peb2466_tg_freq_put()
439 tg_freq_item = &peb2466->ch[0].tg2_freq_item; in peb2466_tg_freq_put()
440 cr1_reg = PEB2466_CR1(0); in peb2466_tg_freq_put()
444 tg_freq_item = &peb2466->ch[1].tg1_freq_item; in peb2466_tg_freq_put()
449 tg_freq_item = &peb2466->ch[1].tg2_freq_item; in peb2466_tg_freq_put()
454 tg_freq_item = &peb2466->ch[2].tg1_freq_item; in peb2466_tg_freq_put()
459 tg_freq_item = &peb2466->ch[2].tg2_freq_item; in peb2466_tg_freq_put()
464 tg_freq_item = &peb2466->ch[3].tg1_freq_item; in peb2466_tg_freq_put()
469 tg_freq_item = &peb2466->ch[3].tg2_freq_item; in peb2466_tg_freq_put()
474 return -EINVAL; in peb2466_tg_freq_put()
478 return 0; in peb2466_tg_freq_put()
481 ret = regmap_update_bits(peb2466->regmap, cr1_reg, cr1_mask, 0); in peb2466_tg_freq_put()
485 ret = peb2466_write_buf(peb2466, e->reg, peb2466_tone_lookup[index], 4); in peb2466_tg_freq_put()
488 ret = regmap_update_bits(peb2466->regmap, cr1_reg, cr1_mask, cr1_mask); in peb2466_tg_freq_put()
498 SOC_DAPM_SINGLE("TG1 Switch", PEB2466_CR1(0), 6, 1, 0),
499 SOC_DAPM_SINGLE("TG2 Switch", PEB2466_CR1(0), 7, 1, 0),
500 SOC_DAPM_SINGLE("Voice Switch", PEB2466_CR2(0), 0, 1, 0)
504 SOC_DAPM_SINGLE("TG1 Switch", PEB2466_CR1(1), 6, 1, 0),
505 SOC_DAPM_SINGLE("TG2 Switch", PEB2466_CR1(1), 7, 1, 0),
506 SOC_DAPM_SINGLE("Voice Switch", PEB2466_CR2(1), 0, 1, 0)
510 SOC_DAPM_SINGLE("TG1 Switch", PEB2466_CR1(2), 6, 1, 0),
511 SOC_DAPM_SINGLE("TG2 Switch", PEB2466_CR1(2), 7, 1, 0),
512 SOC_DAPM_SINGLE("Voice Switch", PEB2466_CR2(2), 0, 1, 0)
516 SOC_DAPM_SINGLE("TG1 Switch", PEB2466_CR1(3), 6, 1, 0),
517 SOC_DAPM_SINGLE("TG2 Switch", PEB2466_CR1(3), 7, 1, 0),
518 SOC_DAPM_SINGLE("Voice Switch", PEB2466_CR2(3), 0, 1, 0)
523 SOC_SINGLE("DAC0 -6dB Playback Switch", PEB2466_CR3(0), 2, 1, 0),
524 SOC_SINGLE("DAC1 -6dB Playback Switch", PEB2466_CR3(1), 2, 1, 0),
525 SOC_SINGLE("DAC2 -6dB Playback Switch", PEB2466_CR3(2), 2, 1, 0),
526 SOC_SINGLE("DAC3 -6dB Playback Switch", PEB2466_CR3(3), 2, 1, 0),
529 SOC_SINGLE("ADC0 +6dB Capture Switch", PEB2466_CR3(0), 3, 1, 0),
530 SOC_SINGLE("ADC1 +6dB Capture Switch", PEB2466_CR3(1), 3, 1, 0),
531 SOC_SINGLE("ADC2 +6dB Capture Switch", PEB2466_CR3(2), 3, 1, 0),
532 SOC_SINGLE("ADC3 +6dB Capture Switch", PEB2466_CR3(3), 3, 1, 0),
535 SOC_ENUM_EXT("DAC0 TG1 Freq", peb2466_tg_freq[0][0],
537 SOC_ENUM_EXT("DAC1 TG1 Freq", peb2466_tg_freq[1][0],
539 SOC_ENUM_EXT("DAC2 TG1 Freq", peb2466_tg_freq[2][0],
541 SOC_ENUM_EXT("DAC3 TG1 Freq", peb2466_tg_freq[3][0],
544 SOC_ENUM_EXT("DAC0 TG2 Freq", peb2466_tg_freq[0][1],
555 SND_SOC_DAPM_SUPPLY("CH0 PWR", PEB2466_CR1(0), 0, 0, NULL, 0),
556 SND_SOC_DAPM_SUPPLY("CH1 PWR", PEB2466_CR1(1), 0, 0, NULL, 0),
557 SND_SOC_DAPM_SUPPLY("CH2 PWR", PEB2466_CR1(2), 0, 0, NULL, 0),
558 SND_SOC_DAPM_SUPPLY("CH3 PWR", PEB2466_CR1(3), 0, 0, NULL, 0),
560 SND_SOC_DAPM_DAC("CH0 DIN", "Playback", SND_SOC_NOPM, 0, 0),
561 SND_SOC_DAPM_DAC("CH1 DIN", "Playback", SND_SOC_NOPM, 0, 0),
562 SND_SOC_DAPM_DAC("CH2 DIN", "Playback", SND_SOC_NOPM, 0, 0),
563 SND_SOC_DAPM_DAC("CH3 DIN", "Playback", SND_SOC_NOPM, 0, 0),
568 SND_SOC_DAPM_SIGGEN("CH3 TG1"),
573 SND_SOC_DAPM_SIGGEN("CH3 TG2"),
575 SND_SOC_DAPM_MIXER("DAC0 Mixer", SND_SOC_NOPM, 0, 0,
578 SND_SOC_DAPM_MIXER("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
581 SND_SOC_DAPM_MIXER("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
584 SND_SOC_DAPM_MIXER("DAC3 Mixer", SND_SOC_NOPM, 0, 0,
588 SND_SOC_DAPM_PGA("DAC0 PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
589 SND_SOC_DAPM_PGA("DAC1 PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
590 SND_SOC_DAPM_PGA("DAC2 PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
591 SND_SOC_DAPM_PGA("DAC3 PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
603 SND_SOC_DAPM_DAC("ADC0", "Capture", SND_SOC_NOPM, 0, 0),
604 SND_SOC_DAPM_DAC("ADC1", "Capture", SND_SOC_NOPM, 0, 0),
605 SND_SOC_DAPM_DAC("ADC2", "Capture", SND_SOC_NOPM, 0, 0),
606 SND_SOC_DAPM_DAC("ADC3", "Capture", SND_SOC_NOPM, 0, 0),
613 { "CH3 DIN", NULL, "CH3 PWR" },
618 { "CH3 TG1", NULL, "CH3 PWR" },
623 { "CH3 TG2", NULL, "CH3 PWR" },
640 { "DAC3 Mixer", "TG1 Switch", "CH3 TG1" },
641 { "DAC3 Mixer", "TG2 Switch", "CH3 TG2" },
642 { "DAC3 Mixer", "Voice Switch", "CH3 DIN" },
643 { "DAC3 Mixer", NULL, "CH3 DIN" },
663 { "ADC3", NULL, "CH3 PWR" },
669 struct peb2466 *peb2466 = snd_soc_component_get_drvdata(dai->component); in peb2466_dai_set_tdm_slot()
676 case 0: in peb2466_dai_set_tdm_slot()
677 /* Not set -> default 8 */ in peb2466_dai_set_tdm_slot()
681 dev_err(dai->dev, "tdm slot width %d not supported\n", width); in peb2466_dai_set_tdm_slot()
682 return -EINVAL; in peb2466_dai_set_tdm_slot()
686 slot = 0; in peb2466_dai_set_tdm_slot()
687 chan = 0; in peb2466_dai_set_tdm_slot()
689 if (mask & 0x1) { in peb2466_dai_set_tdm_slot()
690 ret = regmap_write(peb2466->regmap, PEB2466_CR5(chan), slot); in peb2466_dai_set_tdm_slot()
692 dev_err(dai->dev, "chan %d set tx tdm slot failed (%d)\n", in peb2466_dai_set_tdm_slot()
702 dev_err(dai->dev, "too much tx slots defined (mask = 0x%x) support max %d\n", in peb2466_dai_set_tdm_slot()
704 return -EINVAL; in peb2466_dai_set_tdm_slot()
706 peb2466->max_chan_playback = chan; in peb2466_dai_set_tdm_slot()
709 slot = 0; in peb2466_dai_set_tdm_slot()
710 chan = 0; in peb2466_dai_set_tdm_slot()
712 if (mask & 0x1) { in peb2466_dai_set_tdm_slot()
713 ret = regmap_write(peb2466->regmap, PEB2466_CR4(chan), slot); in peb2466_dai_set_tdm_slot()
715 dev_err(dai->dev, "chan %d set rx tdm slot failed (%d)\n", in peb2466_dai_set_tdm_slot()
725 dev_err(dai->dev, "too much rx slots defined (mask = 0x%x) support max %d\n", in peb2466_dai_set_tdm_slot()
727 return -EINVAL; in peb2466_dai_set_tdm_slot()
729 peb2466->max_chan_capture = chan; in peb2466_dai_set_tdm_slot()
731 return 0; in peb2466_dai_set_tdm_slot()
736 struct peb2466 *peb2466 = snd_soc_component_get_drvdata(dai->component); in peb2466_dai_set_fmt()
744 xr6 = PEB2466_XR6_PCM_OFFSET(0); in peb2466_dai_set_fmt()
747 dev_err(dai->dev, "Unsupported format 0x%x\n", in peb2466_dai_set_fmt()
749 return -EINVAL; in peb2466_dai_set_fmt()
751 return regmap_write(peb2466->regmap, PEB2466_XR6, xr6); in peb2466_dai_set_fmt()
758 struct peb2466 *peb2466 = snd_soc_component_get_drvdata(dai->component); in peb2466_dai_hw_params()
771 dev_err(&peb2466->spi->dev, "Unsupported format 0x%x\n", in peb2466_dai_hw_params()
773 return -EINVAL; in peb2466_dai_hw_params()
776 for (ch = 0; ch < PEB2466_NB_CHANNEL; ch++) { in peb2466_dai_hw_params()
777 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR1(ch), in peb2466_dai_hw_params()
783 return 0; in peb2466_dai_hw_params()
796 struct peb2466 *peb2466 = snd_soc_component_get_drvdata(dai->component); in peb2466_dai_startup()
800 max_ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? in peb2466_dai_startup()
801 peb2466->max_chan_playback : peb2466->max_chan_capture; in peb2466_dai_startup()
804 * Disable stream support (min = 0, max = 0) if no timeslots were in peb2466_dai_startup()
807 ret = snd_pcm_hw_constraint_minmax(substream->runtime, in peb2466_dai_startup()
809 max_ch ? 1 : 0, max_ch); in peb2466_dai_startup()
810 if (ret < 0) in peb2466_dai_startup()
813 return snd_pcm_hw_constraint_list(substream->runtime, 0, in peb2466_dai_startup()
854 { .reg = PEB2466_XR6, .def = 0x00 }, in peb2466_reset_audio()
856 { .reg = PEB2466_CR5(0), .def = 0x00 }, in peb2466_reset_audio()
857 { .reg = PEB2466_CR4(0), .def = 0x00 }, in peb2466_reset_audio()
858 { .reg = PEB2466_CR3(0), .def = 0x00 }, in peb2466_reset_audio()
859 { .reg = PEB2466_CR2(0), .def = 0x00 }, in peb2466_reset_audio()
860 { .reg = PEB2466_CR1(0), .def = 0x00 }, in peb2466_reset_audio()
861 { .reg = PEB2466_CR0(0), .def = PEB2466_CR0_IMR1 }, in peb2466_reset_audio()
863 { .reg = PEB2466_CR5(1), .def = 0x00 }, in peb2466_reset_audio()
864 { .reg = PEB2466_CR4(1), .def = 0x00 }, in peb2466_reset_audio()
865 { .reg = PEB2466_CR3(1), .def = 0x00 }, in peb2466_reset_audio()
866 { .reg = PEB2466_CR2(1), .def = 0x00 }, in peb2466_reset_audio()
867 { .reg = PEB2466_CR1(1), .def = 0x00 }, in peb2466_reset_audio()
870 { .reg = PEB2466_CR5(2), .def = 0x00 }, in peb2466_reset_audio()
871 { .reg = PEB2466_CR4(2), .def = 0x00 }, in peb2466_reset_audio()
872 { .reg = PEB2466_CR3(2), .def = 0x00 }, in peb2466_reset_audio()
873 { .reg = PEB2466_CR2(2), .def = 0x00 }, in peb2466_reset_audio()
874 { .reg = PEB2466_CR1(2), .def = 0x00 }, in peb2466_reset_audio()
877 { .reg = PEB2466_CR5(3), .def = 0x00 }, in peb2466_reset_audio()
878 { .reg = PEB2466_CR4(3), .def = 0x00 }, in peb2466_reset_audio()
879 { .reg = PEB2466_CR3(3), .def = 0x00 }, in peb2466_reset_audio()
880 { .reg = PEB2466_CR2(3), .def = 0x00 }, in peb2466_reset_audio()
881 { .reg = PEB2466_CR1(3), .def = 0x00 }, in peb2466_reset_audio()
884 static const u8 imr1_p1[8] = {0x00, 0x90, 0x09, 0x00, 0x90, 0x09, 0x00, 0x00}; in peb2466_reset_audio()
885 static const u8 imr1_p2[8] = {0x7F, 0xFF, 0x00, 0x00, 0x90, 0x14, 0x40, 0x08}; in peb2466_reset_audio()
886 static const u8 zero[8] = {0}; in peb2466_reset_audio()
890 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_reset_audio()
891 peb2466->ch[i].tg1_freq_item = PEB2466_TONE_1000HZ; in peb2466_reset_audio()
892 peb2466->ch[i].tg2_freq_item = PEB2466_TONE_1000HZ; in peb2466_reset_audio()
932 return regmap_multi_reg_write(peb2466->regmap, reg_reset, ARRAY_SIZE(reg_reset)); in peb2466_reset_audio()
943 dev_info(component->dev, "fw TH filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_thfilter()
944 lng - 1, data + 1); in peb2466_fw_parse_thfilter()
948 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_thfilter()
949 * - @1 8 bytes: TH-Filter coefficients part1 in peb2466_fw_parse_thfilter()
950 * - @9 8 bytes: TH-Filter coefficients part2 in peb2466_fw_parse_thfilter()
951 * - @17 8 bytes: TH-Filter coefficients part3 in peb2466_fw_parse_thfilter()
954 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_thfilter()
958 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_thfilter()
959 PEB2466_CR0_TH, 0); in peb2466_fw_parse_thfilter()
975 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_thfilter()
981 return 0; in peb2466_fw_parse_thfilter()
992 dev_info(component->dev, "fw IM/R1 filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_imr1filter()
993 lng - 1, data + 1); in peb2466_fw_parse_imr1filter()
997 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_imr1filter()
998 * - @1 8 bytes: IM/R1-Filter coefficients part1 in peb2466_fw_parse_imr1filter()
999 * - @9 8 bytes: IM/R1-Filter coefficients part2 in peb2466_fw_parse_imr1filter()
1002 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_imr1filter()
1006 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_imr1filter()
1007 PEB2466_CR0_IMR1, 0); in peb2466_fw_parse_imr1filter()
1019 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_imr1filter()
1024 return 0; in peb2466_fw_parse_imr1filter()
1035 dev_info(component->dev, "fw FRX filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_frxfilter()
1036 lng - 1, data + 1); in peb2466_fw_parse_frxfilter()
1040 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_frxfilter()
1041 * - @1 8 bytes: FRX-Filter coefficients in peb2466_fw_parse_frxfilter()
1044 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_frxfilter()
1048 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_frxfilter()
1049 PEB2466_CR0_FRX, 0); in peb2466_fw_parse_frxfilter()
1057 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_frxfilter()
1062 return 0; in peb2466_fw_parse_frxfilter()
1073 dev_info(component->dev, "fw FRR filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_frrfilter()
1074 lng - 1, data + 1); in peb2466_fw_parse_frrfilter()
1078 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_frrfilter()
1079 * - @1 8 bytes: FRR-Filter coefficients in peb2466_fw_parse_frrfilter()
1082 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_frrfilter()
1086 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_frrfilter()
1087 PEB2466_CR0_FRR, 0); in peb2466_fw_parse_frrfilter()
1095 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_frrfilter()
1100 return 0; in peb2466_fw_parse_frrfilter()
1111 dev_info(component->dev, "fw AX filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_axfilter()
1112 lng - 1, data + 1); in peb2466_fw_parse_axfilter()
1116 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_axfilter()
1117 * - @1 4 bytes: AX-Filter coefficients in peb2466_fw_parse_axfilter()
1120 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_axfilter()
1124 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_axfilter()
1125 PEB2466_CR0_AX, 0); in peb2466_fw_parse_axfilter()
1133 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_axfilter()
1138 return 0; in peb2466_fw_parse_axfilter()
1149 dev_info(component->dev, "fw AR filter: mask %x, %*phN\n", *data, in peb2466_fw_parse_arfilter()
1150 lng - 1, data + 1); in peb2466_fw_parse_arfilter()
1154 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_arfilter()
1155 * - @1 4 bytes: AR-Filter coefficients in peb2466_fw_parse_arfilter()
1158 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_arfilter()
1162 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_arfilter()
1163 PEB2466_CR0_AR, 0); in peb2466_fw_parse_arfilter()
1171 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_arfilter()
1176 return 0; in peb2466_fw_parse_arfilter()
1203 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_axtable()
1204 * - @1 32bits signed: Min table value in centi dB (MinVal) in peb2466_fw_parse_axtable()
1205 * ie -300 means -3.0 dB in peb2466_fw_parse_axtable()
1206 * - @5 32bits signed: Step from on item to other item in centi dB (Step) in peb2466_fw_parse_axtable()
1208 * - @9 32bits unsigned: Item index in the table to use for the initial in peb2466_fw_parse_axtable()
1210 * - @13 N*4 bytes: Table composed of 4 bytes items. in peb2466_fw_parse_axtable()
1214 * dB is: Raw value at index i <-> (MinVal + i * Step) in centi dB. in peb2466_fw_parse_axtable()
1218 if (lng < 13 || ((lng - 13) % 4)) { in peb2466_fw_parse_axtable()
1219 dev_err(component->dev, "fw AX table lng %u invalid\n", lng); in peb2466_fw_parse_axtable()
1220 return -EINVAL; in peb2466_fw_parse_axtable()
1222 table_size = lng - 13; in peb2466_fw_parse_axtable()
1228 dev_err(component->dev, "fw AX table index %u out of table[%u]\n", in peb2466_fw_parse_axtable()
1230 return -EINVAL; in peb2466_fw_parse_axtable()
1233 dev_info(component->dev, in peb2466_fw_parse_axtable()
1239 table = devm_kzalloc(&peb2466->spi->dev, table_size, GFP_KERNEL); in peb2466_fw_parse_axtable()
1241 return -ENOMEM; in peb2466_fw_parse_axtable()
1245 BUILD_BUG_ON(ARRAY_SIZE(peb2466_ax_ctrl_names) != ARRAY_SIZE(peb2466->ch)); in peb2466_fw_parse_axtable()
1246 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_axtable()
1250 lookup = &peb2466->ch[i].ax_lookup; in peb2466_fw_parse_axtable()
1251 lookup->table = table; in peb2466_fw_parse_axtable()
1252 lookup->count = table_size / 4; in peb2466_fw_parse_axtable()
1254 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_axtable()
1255 PEB2466_CR0_AX, 0); in peb2466_fw_parse_axtable()
1260 lookup->table[init_index], 4); in peb2466_fw_parse_axtable()
1264 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_axtable()
1269 lkup_ctrl = &peb2466->ch[i].ax_lkup_ctrl; in peb2466_fw_parse_axtable()
1270 lkup_ctrl->lookup = lookup; in peb2466_fw_parse_axtable()
1271 lkup_ctrl->reg = PEB2466_AX_FILTER(i); in peb2466_fw_parse_axtable()
1272 lkup_ctrl->index = init_index; in peb2466_fw_parse_axtable()
1280 return 0; in peb2466_fw_parse_axtable()
1307 * - @0 1 byte: Chan mask (bit set means related channel is concerned) in peb2466_fw_parse_artable()
1308 * - @1 32bits signed: Min table value in centi dB (MinVal) in peb2466_fw_parse_artable()
1309 * ie -300 means -3.0 dB in peb2466_fw_parse_artable()
1310 * - @5 32bits signed: Step from on item to other item in centi dB (Step) in peb2466_fw_parse_artable()
1312 * - @9 32bits unsigned: Item index in the table to use for the initial in peb2466_fw_parse_artable()
1314 * - @13 N*4 bytes: Table composed of 4 bytes items. in peb2466_fw_parse_artable()
1318 * dB is: Raw value at index i <-> (MinVal + i * Step) in centi dB. in peb2466_fw_parse_artable()
1322 if (lng < 13 || ((lng - 13) % 4)) { in peb2466_fw_parse_artable()
1323 dev_err(component->dev, "fw AR table lng %u invalid\n", lng); in peb2466_fw_parse_artable()
1324 return -EINVAL; in peb2466_fw_parse_artable()
1326 table_size = lng - 13; in peb2466_fw_parse_artable()
1332 dev_err(component->dev, "fw AR table index %u out of table[%u]\n", in peb2466_fw_parse_artable()
1334 return -EINVAL; in peb2466_fw_parse_artable()
1337 dev_info(component->dev, in peb2466_fw_parse_artable()
1343 table = devm_kzalloc(&peb2466->spi->dev, table_size, GFP_KERNEL); in peb2466_fw_parse_artable()
1345 return -ENOMEM; in peb2466_fw_parse_artable()
1349 BUILD_BUG_ON(ARRAY_SIZE(peb2466_ar_ctrl_names) != ARRAY_SIZE(peb2466->ch)); in peb2466_fw_parse_artable()
1350 for (i = 0; i < ARRAY_SIZE(peb2466->ch); i++) { in peb2466_fw_parse_artable()
1354 lookup = &peb2466->ch[i].ar_lookup; in peb2466_fw_parse_artable()
1355 lookup->table = table; in peb2466_fw_parse_artable()
1356 lookup->count = table_size / 4; in peb2466_fw_parse_artable()
1358 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_artable()
1359 PEB2466_CR0_AR, 0); in peb2466_fw_parse_artable()
1364 lookup->table[init_index], 4); in peb2466_fw_parse_artable()
1368 ret = regmap_update_bits(peb2466->regmap, PEB2466_CR0(i), in peb2466_fw_parse_artable()
1373 lkup_ctrl = &peb2466->ch[i].ar_lkup_ctrl; in peb2466_fw_parse_artable()
1374 lkup_ctrl->lookup = lookup; in peb2466_fw_parse_artable()
1375 lkup_ctrl->reg = PEB2466_AR_FILTER(i); in peb2466_fw_parse_artable()
1376 lkup_ctrl->index = init_index; in peb2466_fw_parse_artable()
1384 return 0; in peb2466_fw_parse_artable()
1411 PEB2466_TAG_DEF_LNG_EQ(0x0001, 1 + 3 * 8, peb2466_fw_parse_thfilter),
1413 PEB2466_TAG_DEF_LNG_EQ(0x0002, 1 + 2 * 8, peb2466_fw_parse_imr1filter),
1415 PEB2466_TAG_DEF_LNG_EQ(0x0003, 1 + 8, peb2466_fw_parse_frxfilter),
1417 PEB2466_TAG_DEF_LNG_EQ(0x0004, 1 + 8, peb2466_fw_parse_frrfilter),
1419 PEB2466_TAG_DEF_LNG_EQ(0x0005, 1 + 4, peb2466_fw_parse_axfilter),
1421 PEB2466_TAG_DEF_LNG_EQ(0x0006, 1 + 4, peb2466_fw_parse_arfilter),
1423 PEB2466_TAG_DEF_LNG_MIN(0x0105, 1 + 3 * 4, peb2466_fw_parse_axtable),
1425 PEB2466_TAG_DEF_LNG_MIN(0x0106, 1 + 3 * 4, peb2466_fw_parse_artable),
1432 for (i = 0; i < ARRAY_SIZE(peb2466_fw_tag_defs); i++) { in peb2466_fw_get_tag_def()
1452 * big-endian values). in peb2466_fw_parse()
1454 * @0, 16bits: Magic (0x2466) in peb2466_fw_parse()
1455 * @2, 16bits: Version (0x0100 for version 1.0) in peb2466_fw_parse()
1461 * @0, 16bits: Tag in peb2466_fw_parse()
1473 dev_err(component->dev, "fw size %zu, exp at least 4\n", left); in peb2466_fw_parse()
1474 return -EINVAL; in peb2466_fw_parse()
1479 if (val16 != 0x2466) { in peb2466_fw_parse()
1480 dev_err(component->dev, "fw magic 0x%04x exp 0x2466\n", val16); in peb2466_fw_parse()
1481 return -EINVAL; in peb2466_fw_parse()
1484 left -= 2; in peb2466_fw_parse()
1488 if (val16 != 0x0100) { in peb2466_fw_parse()
1489 dev_err(component->dev, "fw magic 0x%04x exp 0x0100\n", val16); in peb2466_fw_parse()
1490 return -EINVAL; in peb2466_fw_parse()
1493 left -= 2; in peb2466_fw_parse()
1497 dev_err(component->dev, "fw %td/%zu left %zu, exp at least 6\n", in peb2466_fw_parse()
1498 buf - data, size, left); in peb2466_fw_parse()
1499 return -EINVAL; in peb2466_fw_parse()
1506 dev_err(component->dev, "fw %td/%zu tag 0x%04x unknown\n", in peb2466_fw_parse()
1507 buf - data, size, tag); in peb2466_fw_parse()
1508 return -EINVAL; in peb2466_fw_parse()
1510 if (lng < tag_def->lng_min || lng > tag_def->lng_max) { in peb2466_fw_parse()
1511 dev_err(component->dev, "fw %td/%zu tag 0x%04x lng %u, exp [%u;%u]\n", in peb2466_fw_parse()
1512 buf - data, size, tag, lng, tag_def->lng_min, tag_def->lng_max); in peb2466_fw_parse()
1513 return -EINVAL; in peb2466_fw_parse()
1516 left -= 6; in peb2466_fw_parse()
1518 dev_err(component->dev, "fw %td/%zu tag 0x%04x lng %u, left %zu\n", in peb2466_fw_parse()
1519 buf - data, size, tag, lng, left); in peb2466_fw_parse()
1520 return -EINVAL; in peb2466_fw_parse()
1523 /* TLV block is valid -> parse the data part */ in peb2466_fw_parse()
1524 ret = tag_def->parse(component, tag, lng, buf); in peb2466_fw_parse()
1526 dev_err(component->dev, "fw %td/%zu tag 0x%04x lng %u parse failed\n", in peb2466_fw_parse()
1527 buf - data, size, tag, lng); in peb2466_fw_parse()
1532 left -= lng; in peb2466_fw_parse()
1534 return 0; in peb2466_fw_parse()
1542 ret = request_firmware(&fw, fw_name, component->dev); in peb2466_load_coeffs()
1546 ret = peb2466_fw_parse(component, fw->data, fw->size); in peb2466_load_coeffs()
1563 ret = of_property_read_string(peb2466->spi->dev.of_node, in peb2466_component_probe()
1564 "firmware-name", &firmware_name); in peb2466_component_probe()
1566 return (ret == -EINVAL) ? 0 : ret; in peb2466_component_probe()
1587 * 0 SI1_0
1623 * SIx_{0,1} and SOx_{0,1} in peb2466_chip_gpio_offset_to_data_regmask()
1624 * Read accesses read SIx_{0,1} values in peb2466_chip_gpio_offset_to_data_regmask()
1625 * Write accesses write SOx_{0,1} values in peb2466_chip_gpio_offset_to_data_regmask()
1629 return 0; in peb2466_chip_gpio_offset_to_data_regmask()
1632 /* SBx_{0,1} */ in peb2466_chip_gpio_offset_to_data_regmask()
1634 *mask = (1 << (offset - 16)); in peb2466_chip_gpio_offset_to_data_regmask()
1635 return 0; in peb2466_chip_gpio_offset_to_data_regmask()
1640 *mask = (1 << (offset - 24 + 4)); in peb2466_chip_gpio_offset_to_data_regmask()
1641 return 0; in peb2466_chip_gpio_offset_to_data_regmask()
1643 return -EINVAL; in peb2466_chip_gpio_offset_to_data_regmask()
1652 return -EINVAL; in peb2466_chip_gpio_offset_to_dir_regmask()
1656 *mask = (1 << (offset - 16)); in peb2466_chip_gpio_offset_to_dir_regmask()
1657 return 0; in peb2466_chip_gpio_offset_to_dir_regmask()
1661 *mask = (1 << (offset - 24)); in peb2466_chip_gpio_offset_to_dir_regmask()
1662 return 0; in peb2466_chip_gpio_offset_to_dir_regmask()
1664 return -EINVAL; in peb2466_chip_gpio_offset_to_dir_regmask()
1674 cache = &peb2466->gpio.cache.xr0; in peb2466_chip_gpio_get_cache()
1677 cache = &peb2466->gpio.cache.xr1; in peb2466_chip_gpio_get_cache()
1680 cache = &peb2466->gpio.cache.xr2; in peb2466_chip_gpio_get_cache()
1683 cache = &peb2466->gpio.cache.xr3; in peb2466_chip_gpio_get_cache()
1706 mutex_lock(&peb2466->gpio.lock); in peb2466_chip_gpio_update_bits()
1710 ret = -EINVAL; in peb2466_chip_gpio_update_bits()
1718 ret = regmap_write(peb2466->regmap, xr_reg, tmp); in peb2466_chip_gpio_update_bits()
1723 ret = 0; in peb2466_chip_gpio_update_bits()
1726 mutex_unlock(&peb2466->gpio.lock); in peb2466_chip_gpio_update_bits()
1739 * SIx_{0,1} signals cannot be set and writing the related in peb2466_chip_gpio_set()
1740 * register will change the SOx_{0,1} signals in peb2466_chip_gpio_set()
1742 dev_warn(&peb2466->spi->dev, "cannot set gpio %d (read-only)\n", in peb2466_chip_gpio_set()
1749 dev_err(&peb2466->spi->dev, "cannot set gpio %d (%d)\n", in peb2466_chip_gpio_set()
1754 ret = peb2466_chip_gpio_update_bits(peb2466, xr_reg, mask, val ? mask : 0); in peb2466_chip_gpio_set()
1756 dev_err(&peb2466->spi->dev, "set gpio %d (0x%x, 0x%x) failed (%d)\n", in peb2466_chip_gpio_set()
1773 * SOx_{0,1} signals cannot be read. Reading the related in peb2466_chip_gpio_get()
1774 * register will read the SIx_{0,1} signals. in peb2466_chip_gpio_get()
1782 dev_err(&peb2466->spi->dev, "cannot get gpio %d (%d)\n", in peb2466_chip_gpio_get()
1784 return -EINVAL; in peb2466_chip_gpio_get()
1790 return -EINVAL; in peb2466_chip_gpio_get()
1793 ret = regmap_read(peb2466->regmap, xr_reg, &val); in peb2466_chip_gpio_get()
1795 dev_err(&peb2466->spi->dev, "get gpio %d (0x%x, 0x%x) failed (%d)\n", in peb2466_chip_gpio_get()
1813 /* SIx_{0,1} */ in peb2466_chip_get_direction()
1817 /* SOx_{0,1} */ in peb2466_chip_get_direction()
1823 dev_err(&peb2466->spi->dev, "cannot get gpio %d direction (%d)\n", in peb2466_chip_get_direction()
1828 ret = regmap_read(peb2466->regmap, xr_reg, &val); in peb2466_chip_get_direction()
1830 dev_err(&peb2466->spi->dev, "get dir gpio %d (0x%x, 0x%x) failed (%d)\n", in peb2466_chip_get_direction()
1846 /* SIx_{0,1} */ in peb2466_chip_direction_input()
1847 return 0; in peb2466_chip_direction_input()
1850 /* SOx_{0,1} */ in peb2466_chip_direction_input()
1851 return -EINVAL; in peb2466_chip_direction_input()
1856 dev_err(&peb2466->spi->dev, "cannot set gpio %d direction (%d)\n", in peb2466_chip_direction_input()
1861 ret = peb2466_chip_gpio_update_bits(peb2466, xr_reg, mask, 0); in peb2466_chip_direction_input()
1863 dev_err(&peb2466->spi->dev, "Set dir in gpio %d (0x%x, 0x%x) failed (%d)\n", in peb2466_chip_direction_input()
1868 return 0; in peb2466_chip_direction_input()
1879 /* SIx_{0,1} */ in peb2466_chip_direction_output()
1880 return -EINVAL; in peb2466_chip_direction_output()
1886 /* SOx_{0,1} */ in peb2466_chip_direction_output()
1887 return 0; in peb2466_chip_direction_output()
1892 dev_err(&peb2466->spi->dev, "cannot set gpio %d direction (%d)\n", in peb2466_chip_direction_output()
1899 dev_err(&peb2466->spi->dev, "Set dir in gpio %d (0x%x, 0x%x) failed (%d)\n", in peb2466_chip_direction_output()
1904 return 0; in peb2466_chip_direction_output()
1910 /* Output pins at 0, input/output pins as input */ in peb2466_reset_gpio()
1911 { .reg = PEB2466_XR0, .def = 0 }, in peb2466_reset_gpio()
1912 { .reg = PEB2466_XR1, .def = 0 }, in peb2466_reset_gpio()
1913 { .reg = PEB2466_XR2, .def = 0 }, in peb2466_reset_gpio()
1914 { .reg = PEB2466_XR3, .def = 0 }, in peb2466_reset_gpio()
1917 peb2466->gpio.cache.xr0 = 0; in peb2466_reset_gpio()
1918 peb2466->gpio.cache.xr1 = 0; in peb2466_reset_gpio()
1919 peb2466->gpio.cache.xr2 = 0; in peb2466_reset_gpio()
1920 peb2466->gpio.cache.xr3 = 0; in peb2466_reset_gpio()
1922 return regmap_multi_reg_write(peb2466->regmap, reg_reset, ARRAY_SIZE(reg_reset)); in peb2466_reset_gpio()
1929 mutex_init(&peb2466->gpio.lock); in peb2466_gpio_init()
1935 peb2466->gpio.gpio_chip.owner = THIS_MODULE; in peb2466_gpio_init()
1936 peb2466->gpio.gpio_chip.label = dev_name(&peb2466->spi->dev); in peb2466_gpio_init()
1937 peb2466->gpio.gpio_chip.parent = &peb2466->spi->dev; in peb2466_gpio_init()
1938 peb2466->gpio.gpio_chip.base = -1; in peb2466_gpio_init()
1939 peb2466->gpio.gpio_chip.ngpio = 28; in peb2466_gpio_init()
1940 peb2466->gpio.gpio_chip.get_direction = peb2466_chip_get_direction; in peb2466_gpio_init()
1941 peb2466->gpio.gpio_chip.direction_input = peb2466_chip_direction_input; in peb2466_gpio_init()
1942 peb2466->gpio.gpio_chip.direction_output = peb2466_chip_direction_output; in peb2466_gpio_init()
1943 peb2466->gpio.gpio_chip.get = peb2466_chip_gpio_get; in peb2466_gpio_init()
1944 peb2466->gpio.gpio_chip.set = peb2466_chip_gpio_set; in peb2466_gpio_init()
1945 peb2466->gpio.gpio_chip.can_sleep = true; in peb2466_gpio_init()
1947 return devm_gpiochip_add_data(&peb2466->spi->dev, &peb2466->gpio.gpio_chip, in peb2466_gpio_init()
1958 spi->bits_per_word = 8; in peb2466_spi_probe()
1960 if (ret < 0) in peb2466_spi_probe()
1963 peb2466 = devm_kzalloc(&spi->dev, sizeof(*peb2466), GFP_KERNEL); in peb2466_spi_probe()
1965 return -ENOMEM; in peb2466_spi_probe()
1967 peb2466->spi = spi; in peb2466_spi_probe()
1969 peb2466->regmap = devm_regmap_init(&peb2466->spi->dev, NULL, peb2466, in peb2466_spi_probe()
1971 if (IS_ERR(peb2466->regmap)) in peb2466_spi_probe()
1972 return PTR_ERR(peb2466->regmap); in peb2466_spi_probe()
1974 peb2466->reset_gpio = devm_gpiod_get_optional(&peb2466->spi->dev, in peb2466_spi_probe()
1976 if (IS_ERR(peb2466->reset_gpio)) in peb2466_spi_probe()
1977 return PTR_ERR(peb2466->reset_gpio); in peb2466_spi_probe()
1979 peb2466->mclk = devm_clk_get_enabled(&peb2466->spi->dev, "mclk"); in peb2466_spi_probe()
1980 if (IS_ERR(peb2466->mclk)) in peb2466_spi_probe()
1981 return PTR_ERR(peb2466->mclk); in peb2466_spi_probe()
1983 if (peb2466->reset_gpio) { in peb2466_spi_probe()
1984 gpiod_set_value_cansleep(peb2466->reset_gpio, 1); in peb2466_spi_probe()
1986 gpiod_set_value_cansleep(peb2466->reset_gpio, 0); in peb2466_spi_probe()
1992 mclk_rate = clk_get_rate(peb2466->mclk); in peb2466_spi_probe()
2007 dev_err(&peb2466->spi->dev, "Unsupported clock rate %lu\n", in peb2466_spi_probe()
2009 ret = -EINVAL; in peb2466_spi_probe()
2012 ret = regmap_write(peb2466->regmap, PEB2466_XR5, xr5); in peb2466_spi_probe()
2014 dev_err(&peb2466->spi->dev, "Setting MCLK failed (%d)\n", ret); in peb2466_spi_probe()
2018 ret = devm_snd_soc_register_component(&spi->dev, &peb2466_component_driver, in peb2466_spi_probe()
2029 return 0; in peb2466_spi_probe()
2042 { "peb2466", 0 },