1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2019, Linaro Limited
5 #include <linux/clk-provider.h>
6 #include <linux/gpio.h>
7 #include <linux/interrupt.h>
8 #include <linux/kernel.h>
9 #include <linux/mfd/wcd934x/registers.h>
10 #include <linux/mfd/wcd934x/wcd934x.h>
11 #include <linux/module.h>
12 #include <linux/mutex.h>
13 #include <linux/of_clk.h>
14 #include <linux/of_device.h>
15 #include <linux/of_gpio.h>
17 #include <linux/of_irq.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/slab.h>
22 #include <linux/slimbus.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
25 #include <sound/soc-dapm.h>
26 #include <sound/tlv.h>
27 #include "wcd-clsh-v2.h"
29 #define WCD934X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
30 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
31 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
32 /* Fractional Rates */
33 #define WCD934X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
34 SNDRV_PCM_RATE_176400)
35 #define WCD934X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
36 SNDRV_PCM_FMTBIT_S24_LE)
38 /* slave port water mark level
39 * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
41 #define SLAVE_PORT_WATER_MARK_6BYTES 0
42 #define SLAVE_PORT_WATER_MARK_9BYTES 1
43 #define SLAVE_PORT_WATER_MARK_12BYTES 2
44 #define SLAVE_PORT_WATER_MARK_15BYTES 3
45 #define SLAVE_PORT_WATER_MARK_SHIFT 1
46 #define SLAVE_PORT_ENABLE 1
47 #define SLAVE_PORT_DISABLE 0
48 #define WCD934X_SLIM_WATER_MARK_VAL \
49 ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \
52 #define WCD934X_SLIM_NUM_PORT_REG 3
53 #define WCD934X_SLIM_PGD_PORT_INT_TX_EN0 (WCD934X_SLIM_PGD_PORT_INT_EN0 + 2)
54 #define WCD934X_SLIM_IRQ_OVERFLOW BIT(0)
55 #define WCD934X_SLIM_IRQ_UNDERFLOW BIT(1)
56 #define WCD934X_SLIM_IRQ_PORT_CLOSED BIT(2)
58 #define WCD934X_MCLK_CLK_12P288MHZ 12288000
59 #define WCD934X_MCLK_CLK_9P6MHZ 9600000
61 /* Only valid for 9.6 MHz mclk */
62 #define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000
63 #define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000
65 /* Only valid for 12.288 MHz mclk */
66 #define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000
68 #define WCD934X_DMIC_CLK_DIV_2 0x0
69 #define WCD934X_DMIC_CLK_DIV_3 0x1
70 #define WCD934X_DMIC_CLK_DIV_4 0x2
71 #define WCD934X_DMIC_CLK_DIV_6 0x3
72 #define WCD934X_DMIC_CLK_DIV_8 0x4
73 #define WCD934X_DMIC_CLK_DIV_16 0x5
74 #define WCD934X_DMIC_CLK_DRIVE_DEFAULT 0x02
76 #define TX_HPF_CUT_OFF_FREQ_MASK 0x60
77 #define CF_MIN_3DB_4HZ 0x0
78 #define CF_MIN_3DB_75HZ 0x1
79 #define CF_MIN_3DB_150HZ 0x2
81 #define WCD934X_RX_START 16
82 #define WCD934X_NUM_INTERPOLATORS 9
83 #define WCD934X_RX_PATH_CTL_OFFSET 20
84 #define WCD934X_MAX_VALID_ADC_MUX 13
85 #define WCD934X_INVALID_ADC_MUX 9
87 #define WCD934X_SLIM_RX_CH(p) \
88 {.port = p + WCD934X_RX_START, .shift = p,}
90 #define WCD934X_SLIM_TX_CH(p) \
91 {.port = p, .shift = p,}
93 /* Feature masks to distinguish codec version */
94 #define DSD_DISABLED_MASK 0
95 #define SLNQ_DISABLED_MASK 1
97 #define DSD_DISABLED BIT(DSD_DISABLED_MASK)
98 #define SLNQ_DISABLED BIT(SLNQ_DISABLED_MASK)
100 /* As fine version info cannot be retrieved before wcd probe.
101 * Define three coarse versions for possible future use before wcd probe.
103 #define WCD_VERSION_WCD9340_1_0 0x400
104 #define WCD_VERSION_WCD9341_1_0 0x410
105 #define WCD_VERSION_WCD9340_1_1 0x401
106 #define WCD_VERSION_WCD9341_1_1 0x411
107 #define WCD934X_AMIC_PWR_LEVEL_LP 0
108 #define WCD934X_AMIC_PWR_LEVEL_DEFAULT 1
109 #define WCD934X_AMIC_PWR_LEVEL_HP 2
110 #define WCD934X_AMIC_PWR_LEVEL_HYBRID 3
111 #define WCD934X_AMIC_PWR_LVL_MASK 0x60
112 #define WCD934X_AMIC_PWR_LVL_SHIFT 0x5
114 #define WCD934X_DEC_PWR_LVL_MASK 0x06
115 #define WCD934X_DEC_PWR_LVL_LP 0x02
116 #define WCD934X_DEC_PWR_LVL_HP 0x04
117 #define WCD934X_DEC_PWR_LVL_DF 0x00
118 #define WCD934X_DEC_PWR_LVL_HYBRID WCD934X_DEC_PWR_LVL_DF
120 #define WCD934X_DEF_MICBIAS_MV 1800
121 #define WCD934X_MAX_MICBIAS_MV 2850
124 SIDO_SOURCE_INTERNAL,
134 INTERP_LO3_NA, /* LO3 not avalible in Tavil */
136 INTERP_SPKR1, /*INT7 WSA Speakers via soundwire */
137 INTERP_SPKR2, /*INT8 WSA Speakers via soundwire */
178 struct wcd934x_slim_ch {
182 struct list_head list;
185 static const struct wcd934x_slim_ch wcd934x_tx_chs[WCD934X_TX_MAX] = {
186 WCD934X_SLIM_TX_CH(0),
187 WCD934X_SLIM_TX_CH(1),
188 WCD934X_SLIM_TX_CH(2),
189 WCD934X_SLIM_TX_CH(3),
190 WCD934X_SLIM_TX_CH(4),
191 WCD934X_SLIM_TX_CH(5),
192 WCD934X_SLIM_TX_CH(6),
193 WCD934X_SLIM_TX_CH(7),
194 WCD934X_SLIM_TX_CH(8),
195 WCD934X_SLIM_TX_CH(9),
196 WCD934X_SLIM_TX_CH(10),
197 WCD934X_SLIM_TX_CH(11),
198 WCD934X_SLIM_TX_CH(12),
199 WCD934X_SLIM_TX_CH(13),
200 WCD934X_SLIM_TX_CH(14),
201 WCD934X_SLIM_TX_CH(15),
204 static const struct wcd934x_slim_ch wcd934x_rx_chs[WCD934X_RX_MAX] = {
205 WCD934X_SLIM_RX_CH(0), /* 16 */
206 WCD934X_SLIM_RX_CH(1), /* 17 */
207 WCD934X_SLIM_RX_CH(2),
208 WCD934X_SLIM_RX_CH(3),
209 WCD934X_SLIM_RX_CH(4),
210 WCD934X_SLIM_RX_CH(5),
211 WCD934X_SLIM_RX_CH(6),
212 WCD934X_SLIM_RX_CH(7),
213 WCD934X_SLIM_RX_CH(8),
214 WCD934X_SLIM_RX_CH(9),
215 WCD934X_SLIM_RX_CH(10),
216 WCD934X_SLIM_RX_CH(11),
217 WCD934X_SLIM_RX_CH(12),
234 INTn_1_INP_SEL_ZERO = 0,
250 INTn_2_INP_SEL_ZERO = 0,
259 INTn_2_INP_SEL_PROXIMITY,
267 struct interp_sample_rate {
272 static struct interp_sample_rate sr_val_tbl[] = {
286 struct wcd_slim_codec_dai_data {
287 struct list_head slim_ch_list;
288 struct slim_stream_config sconfig;
289 struct slim_stream_runtime *sruntime;
292 static const struct regmap_range_cfg wcd934x_ifc_ranges[] = {
294 .name = "WCD9335-IFC-DEV",
297 .selector_reg = 0x800,
298 .selector_mask = 0xfff,
300 .window_start = 0x800,
305 static struct regmap_config wcd934x_ifc_regmap_config = {
308 .max_register = 0xffff,
309 .ranges = wcd934x_ifc_ranges,
310 .num_ranges = ARRAY_SIZE(wcd934x_ifc_ranges),
313 struct wcd934x_codec {
317 struct regmap *regmap;
318 struct regmap *if_regmap;
319 struct slim_device *sdev;
320 struct slim_device *sidev;
321 struct wcd_clsh_ctrl *clsh_ctrl;
322 struct snd_soc_component *component;
323 struct wcd934x_slim_ch rx_chs[WCD934X_RX_MAX];
324 struct wcd934x_slim_ch tx_chs[WCD934X_TX_MAX];
325 struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS];
331 u32 tx_port_value[WCD934X_TX_MAX];
332 u32 rx_port_value[WCD934X_RX_MAX];
334 int dmic_0_1_clk_cnt;
335 int dmic_2_3_clk_cnt;
336 int dmic_4_5_clk_cnt;
337 int dmic_sample_rate;
339 struct mutex sysclk_mutex;
342 #define to_wcd934x_codec(_hw) container_of(_hw, struct wcd934x_codec, hw)
344 static int wcd934x_set_sido_input_src(struct wcd934x_codec *wcd,
347 if (sido_src == wcd->sido_input_src)
350 if (sido_src == SIDO_SOURCE_INTERNAL) {
351 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL,
352 WCD934X_ANA_BUCK_HI_ACCU_EN_MASK, 0);
353 usleep_range(100, 110);
354 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL,
355 WCD934X_ANA_BUCK_HI_ACCU_PRE_ENX_MASK, 0x0);
356 usleep_range(100, 110);
357 regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO,
358 WCD934X_ANA_RCO_BG_EN_MASK, 0);
359 usleep_range(100, 110);
360 } else if (sido_src == SIDO_SOURCE_RCO_BG) {
361 regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO,
362 WCD934X_ANA_RCO_BG_EN_MASK,
363 WCD934X_ANA_RCO_BG_ENABLE);
364 usleep_range(100, 110);
365 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL,
366 WCD934X_ANA_BUCK_PRE_EN1_MASK,
367 WCD934X_ANA_BUCK_PRE_EN1_ENABLE);
368 usleep_range(100, 110);
369 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL,
370 WCD934X_ANA_BUCK_PRE_EN2_MASK,
371 WCD934X_ANA_BUCK_PRE_EN2_ENABLE);
372 usleep_range(100, 110);
373 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL,
374 WCD934X_ANA_BUCK_HI_ACCU_EN_MASK,
375 WCD934X_ANA_BUCK_HI_ACCU_ENABLE);
376 usleep_range(100, 110);
378 wcd->sido_input_src = sido_src;
383 static int wcd934x_enable_ana_bias_and_sysclk(struct wcd934x_codec *wcd)
385 mutex_lock(&wcd->sysclk_mutex);
387 if (++wcd->sysclk_users != 1) {
388 mutex_unlock(&wcd->sysclk_mutex);
391 mutex_unlock(&wcd->sysclk_mutex);
393 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
394 WCD934X_ANA_BIAS_EN_MASK,
395 WCD934X_ANA_BIAS_EN);
396 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
397 WCD934X_ANA_PRECHRG_EN_MASK,
398 WCD934X_ANA_PRECHRG_EN);
400 * 1ms delay is required after pre-charge is enabled
401 * as per HW requirement
403 usleep_range(1000, 1100);
404 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
405 WCD934X_ANA_PRECHRG_EN_MASK, 0);
406 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
407 WCD934X_ANA_PRECHRG_MODE_MASK, 0);
410 * In data clock contrl register is changed
411 * to CLK_SYS_MCLK_PRG
414 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
415 WCD934X_EXT_CLK_BUF_EN_MASK,
416 WCD934X_EXT_CLK_BUF_EN);
417 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
418 WCD934X_EXT_CLK_DIV_RATIO_MASK,
419 WCD934X_EXT_CLK_DIV_BY_2);
420 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
421 WCD934X_MCLK_SRC_MASK,
422 WCD934X_MCLK_SRC_EXT_CLK);
423 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
424 WCD934X_MCLK_EN_MASK, WCD934X_MCLK_EN);
425 regmap_update_bits(wcd->regmap,
426 WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
427 WCD934X_CDC_FS_MCLK_CNT_EN_MASK,
428 WCD934X_CDC_FS_MCLK_CNT_ENABLE);
429 regmap_update_bits(wcd->regmap,
430 WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL,
431 WCD934X_MCLK_EN_MASK,
433 regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_GATE,
434 WCD934X_CODEC_RPM_CLK_GATE_MASK, 0x0);
436 * 10us sleep is required after clock is enabled
437 * as per HW requirement
439 usleep_range(10, 15);
441 wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_RCO_BG);
446 static int wcd934x_disable_ana_bias_and_syclk(struct wcd934x_codec *wcd)
448 mutex_lock(&wcd->sysclk_mutex);
449 if (--wcd->sysclk_users != 0) {
450 mutex_unlock(&wcd->sysclk_mutex);
453 mutex_unlock(&wcd->sysclk_mutex);
455 regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG,
456 WCD934X_EXT_CLK_BUF_EN_MASK |
457 WCD934X_MCLK_EN_MASK, 0x0);
458 wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_INTERNAL);
460 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
461 WCD934X_ANA_BIAS_EN_MASK, 0);
462 regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS,
463 WCD934X_ANA_PRECHRG_EN_MASK, 0);
468 static int __wcd934x_cdc_mclk_enable(struct wcd934x_codec *wcd, bool enable)
473 ret = clk_prepare_enable(wcd->extclk);
476 dev_err(wcd->dev, "%s: ext clk enable failed\n",
480 ret = wcd934x_enable_ana_bias_and_sysclk(wcd);
484 regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL,
487 /* Don't disable clock if soundwire using it.*/
488 if (val & WCD934X_CDC_SWR_CLK_EN_MASK)
491 wcd934x_disable_ana_bias_and_syclk(wcd);
492 clk_disable_unprepare(wcd->extclk);
498 static int wcd934x_get_version(struct wcd934x_codec *wcd)
500 int val1, val2, ver, ret;
501 struct regmap *regmap;
503 u32 version_mask = 0;
505 regmap = wcd->regmap;
508 ret = regmap_bulk_read(regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
509 (u8 *)&id_minor, sizeof(u16));
514 regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14, &val1);
515 regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15, &val2);
517 version_mask |= (!!((u8)val1 & 0x80)) << DSD_DISABLED_MASK;
518 version_mask |= (!!((u8)val2 & 0x01)) << SLNQ_DISABLED_MASK;
520 switch (version_mask) {
521 case DSD_DISABLED | SLNQ_DISABLED:
523 ver = WCD_VERSION_WCD9340_1_0;
524 else if (id_minor == 0x01)
525 ver = WCD_VERSION_WCD9340_1_1;
529 ver = WCD_VERSION_WCD9341_1_0;
530 else if (id_minor == 0x01)
531 ver = WCD_VERSION_WCD9341_1_1;
536 dev_info(wcd->dev, "WCD934X Minor:0x%x Version:0x%x\n", id_minor, ver);
541 static void wcd934x_enable_efuse_sensing(struct wcd934x_codec *wcd)
545 __wcd934x_cdc_mclk_enable(wcd, true);
547 regmap_update_bits(wcd->regmap,
548 WCD934X_CHIP_TIER_CTRL_EFUSE_CTL,
549 WCD934X_EFUSE_SENSE_STATE_MASK,
550 WCD934X_EFUSE_SENSE_STATE_DEF);
551 regmap_update_bits(wcd->regmap,
552 WCD934X_CHIP_TIER_CTRL_EFUSE_CTL,
553 WCD934X_EFUSE_SENSE_EN_MASK,
554 WCD934X_EFUSE_SENSE_ENABLE);
556 * 5ms sleep required after enabling efuse control
557 * before checking the status.
559 usleep_range(5000, 5500);
560 wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_RCO_BG);
562 rc = regmap_read(wcd->regmap,
563 WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
564 if (rc || (!(val & 0x01)))
565 WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n",
568 __wcd934x_cdc_mclk_enable(wcd, false);
571 static int wcd934x_swrm_clock(struct wcd934x_codec *wcd, bool enable)
574 __wcd934x_cdc_mclk_enable(wcd, true);
575 regmap_update_bits(wcd->regmap,
576 WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL,
577 WCD934X_CDC_SWR_CLK_EN_MASK,
578 WCD934X_CDC_SWR_CLK_ENABLE);
580 regmap_update_bits(wcd->regmap,
581 WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL,
582 WCD934X_CDC_SWR_CLK_EN_MASK, 0);
583 __wcd934x_cdc_mclk_enable(wcd, false);
589 static int wcd934x_set_prim_interpolator_rate(struct snd_soc_dai *dai,
590 u8 rate_val, u32 rate)
592 struct snd_soc_component *comp = dai->component;
593 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
594 struct wcd934x_slim_ch *ch;
595 u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel;
598 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
599 inp = ch->shift + INTn_1_INP_SEL_RX0;
601 * Loop through all interpolator MUX inputs and find out
602 * to which interpolator input, the slim rx port
605 for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) {
606 /* Interpolators 5 and 6 are not aviliable in Tavil */
607 if (j == INTERP_LO3_NA || j == INTERP_LO4_NA)
610 cfg0 = snd_soc_component_read32(comp,
611 WCD934X_CDC_RX_INP_MUX_RX_INT_CFG0(j));
612 cfg1 = snd_soc_component_read32(comp,
613 WCD934X_CDC_RX_INP_MUX_RX_INT_CFG1(j));
616 WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
617 inp1_sel = (cfg0 >> 4) &
618 WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
619 inp2_sel = (cfg1 >> 4) &
620 WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
622 if ((inp0_sel == inp) || (inp1_sel == inp) ||
626 * Ear and speaker primary path does not support
627 * native sample rates
629 if ((j == INTERP_EAR || j == INTERP_SPKR1 ||
630 j == INTERP_SPKR2) && rate == 44100)
632 "Cannot set 44.1KHz on INT%d\n",
635 snd_soc_component_update_bits(comp,
636 WCD934X_CDC_RX_PATH_CTL(j),
637 WCD934X_CDC_MIX_PCM_RATE_MASK,
646 static int wcd934x_set_mix_interpolator_rate(struct snd_soc_dai *dai,
647 int rate_val, u32 rate)
649 struct snd_soc_component *component = dai->component;
650 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
651 struct wcd934x_slim_ch *ch;
654 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
655 for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) {
656 /* Interpolators 5 and 6 are not aviliable in Tavil */
657 if (j == INTERP_LO3_NA || j == INTERP_LO4_NA)
659 val = snd_soc_component_read32(component,
660 WCD934X_CDC_RX_INP_MUX_RX_INT_CFG1(j)) &
661 WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
663 if (val == (ch->shift + INTn_2_INP_SEL_RX0)) {
665 * Ear mix path supports only 48, 96, 192,
668 if ((j == INTERP_EAR) &&
671 dev_err(component->dev,
672 "Invalid rate for AIF_PB DAI(%d)\n",
677 snd_soc_component_update_bits(component,
678 WCD934X_CDC_RX_PATH_MIX_CTL(j),
679 WCD934X_CDC_MIX_PCM_RATE_MASK,
688 static int wcd934x_set_interpolator_rate(struct snd_soc_dai *dai,
694 for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
695 if (sample_rate == sr_val_tbl[i].sample_rate) {
696 rate_val = sr_val_tbl[i].rate_val;
700 if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
701 dev_err(dai->dev, "Unsupported sample rate: %d\n", sample_rate);
705 ret = wcd934x_set_prim_interpolator_rate(dai, (u8)rate_val,
709 ret = wcd934x_set_mix_interpolator_rate(dai, (u8)rate_val,
717 static int wcd934x_set_decimator_rate(struct snd_soc_dai *dai,
718 u8 rate_val, u32 rate)
720 struct snd_soc_component *comp = dai->component;
721 struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp);
722 u8 shift = 0, shift_val = 0, tx_mux_sel;
723 struct wcd934x_slim_ch *ch;
724 int tx_port, tx_port_reg;
727 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
729 /* Find the SB TX MUX input - which decimator is connected */
732 tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0;
733 shift = (tx_port << 1);
737 tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1;
738 shift = ((tx_port - 4) << 1);
742 tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2;
743 shift = ((tx_port - 8) << 1);
747 tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3;
752 tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3;
757 dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n",
762 tx_mux_sel = snd_soc_component_read32(comp, tx_port_reg) &
763 (shift_val << shift);
765 tx_mux_sel = tx_mux_sel >> shift;
768 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
772 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
773 decimator = ((tx_port == 9) ? 7 : 6);
776 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
777 decimator = tx_mux_sel - 1;
780 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
784 dev_err(wcd->dev, "ERROR: Invalid tx_port: %d\n",
789 snd_soc_component_update_bits(comp,
790 WCD934X_CDC_TX_PATH_CTL(decimator),
791 WCD934X_CDC_TX_PATH_CTL_PCM_RATE_MASK,
798 static int wcd934x_slim_set_hw_params(struct wcd934x_codec *wcd,
799 struct wcd_slim_codec_dai_data *dai_data,
802 struct list_head *slim_ch_list = &dai_data->slim_ch_list;
803 struct slim_stream_config *cfg = &dai_data->sconfig;
804 struct wcd934x_slim_ch *ch;
809 cfg->direction = direction;
812 /* Configure slave interface device */
813 list_for_each_entry(ch, slim_ch_list, list) {
815 payload |= 1 << ch->shift;
816 cfg->port_mask |= BIT(ch->port);
819 cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL);
824 list_for_each_entry(ch, slim_ch_list, list) {
825 cfg->chs[i++] = ch->ch_num;
826 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
827 /* write to interface device */
828 ret = regmap_write(wcd->if_regmap,
829 WCD934X_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port),
835 /* configure the slave port for water mark and enable*/
836 ret = regmap_write(wcd->if_regmap,
837 WCD934X_SLIM_PGD_RX_PORT_CFG(ch->port),
838 WCD934X_SLIM_WATER_MARK_VAL);
842 ret = regmap_write(wcd->if_regmap,
843 WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port),
849 ret = regmap_write(wcd->if_regmap,
850 WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port),
851 (payload & 0xFF00) >> 8);
855 /* configure the slave port for water mark and enable*/
856 ret = regmap_write(wcd->if_regmap,
857 WCD934X_SLIM_PGD_TX_PORT_CFG(ch->port),
858 WCD934X_SLIM_WATER_MARK_VAL);
865 dai_data->sruntime = slim_stream_allocate(wcd->sdev, "WCD934x-SLIM");
870 dev_err(wcd->dev, "Error Setting slim hw params\n");
877 static int wcd934x_hw_params(struct snd_pcm_substream *substream,
878 struct snd_pcm_hw_params *params,
879 struct snd_soc_dai *dai)
881 struct wcd934x_codec *wcd;
882 int ret, tx_fs_rate = 0;
884 wcd = snd_soc_component_get_drvdata(dai->component);
886 switch (substream->stream) {
887 case SNDRV_PCM_STREAM_PLAYBACK:
888 ret = wcd934x_set_interpolator_rate(dai, params_rate(params));
890 dev_err(wcd->dev, "cannot set sample rate: %u\n",
891 params_rate(params));
894 switch (params_width(params)) {
896 wcd->dai[dai->id].sconfig.bps = params_width(params);
899 dev_err(wcd->dev, "Invalid format 0x%x\n",
900 params_width(params));
905 case SNDRV_PCM_STREAM_CAPTURE:
906 switch (params_rate(params)) {
929 dev_err(wcd->dev, "Invalid TX sample rate: %d\n",
930 params_rate(params));
935 ret = wcd934x_set_decimator_rate(dai, tx_fs_rate,
936 params_rate(params));
938 dev_err(wcd->dev, "Cannot set TX Decimator rate\n");
941 switch (params_width(params)) {
943 wcd->dai[dai->id].sconfig.bps = params_width(params);
946 dev_err(wcd->dev, "Invalid format 0x%x\n",
947 params_width(params));
952 dev_err(wcd->dev, "Invalid stream type %d\n",
957 wcd->dai[dai->id].sconfig.rate = params_rate(params);
958 wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
963 static int wcd934x_hw_free(struct snd_pcm_substream *substream,
964 struct snd_soc_dai *dai)
966 struct wcd_slim_codec_dai_data *dai_data;
967 struct wcd934x_codec *wcd;
969 wcd = snd_soc_component_get_drvdata(dai->component);
971 dai_data = &wcd->dai[dai->id];
973 kfree(dai_data->sconfig.chs);
978 static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd,
979 struct snd_soc_dai *dai)
981 struct wcd_slim_codec_dai_data *dai_data;
982 struct wcd934x_codec *wcd;
983 struct slim_stream_config *cfg;
985 wcd = snd_soc_component_get_drvdata(dai->component);
987 dai_data = &wcd->dai[dai->id];
990 case SNDRV_PCM_TRIGGER_START:
991 case SNDRV_PCM_TRIGGER_RESUME:
992 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
993 cfg = &dai_data->sconfig;
994 slim_stream_prepare(dai_data->sruntime, cfg);
995 slim_stream_enable(dai_data->sruntime);
997 case SNDRV_PCM_TRIGGER_STOP:
998 case SNDRV_PCM_TRIGGER_SUSPEND:
999 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1000 slim_stream_unprepare(dai_data->sruntime);
1001 slim_stream_disable(dai_data->sruntime);
1010 static int wcd934x_set_channel_map(struct snd_soc_dai *dai,
1011 unsigned int tx_num, unsigned int *tx_slot,
1012 unsigned int rx_num, unsigned int *rx_slot)
1014 struct wcd934x_codec *wcd;
1017 wcd = snd_soc_component_get_drvdata(dai->component);
1019 if (!tx_slot || !rx_slot) {
1020 dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n",
1026 wcd->num_rx_port = rx_num;
1027 for (i = 0; i < rx_num; i++) {
1028 wcd->rx_chs[i].ch_num = rx_slot[i];
1029 INIT_LIST_HEAD(&wcd->rx_chs[i].list);
1034 wcd->num_tx_port = tx_num;
1035 for (i = 0; i < tx_num; i++) {
1036 wcd->tx_chs[i].ch_num = tx_slot[i];
1037 INIT_LIST_HEAD(&wcd->tx_chs[i].list);
1044 static int wcd934x_get_channel_map(struct snd_soc_dai *dai,
1045 unsigned int *tx_num, unsigned int *tx_slot,
1046 unsigned int *rx_num, unsigned int *rx_slot)
1048 struct wcd934x_slim_ch *ch;
1049 struct wcd934x_codec *wcd;
1052 wcd = snd_soc_component_get_drvdata(dai->component);
1059 if (!rx_slot || !rx_num) {
1060 dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n",
1065 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
1066 rx_slot[i++] = ch->ch_num;
1073 if (!tx_slot || !tx_num) {
1074 dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n",
1079 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
1080 tx_slot[i++] = ch->ch_num;
1085 dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id);
1092 static struct snd_soc_dai_ops wcd934x_dai_ops = {
1093 .hw_params = wcd934x_hw_params,
1094 .hw_free = wcd934x_hw_free,
1095 .trigger = wcd934x_trigger,
1096 .set_channel_map = wcd934x_set_channel_map,
1097 .get_channel_map = wcd934x_get_channel_map,
1100 static struct snd_soc_dai_driver wcd934x_slim_dais[] = {
1102 .name = "wcd934x_rx1",
1105 .stream_name = "AIF1 Playback",
1106 .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK,
1107 .formats = WCD934X_FORMATS_S16_S24_LE,
1113 .ops = &wcd934x_dai_ops,
1116 .name = "wcd934x_tx1",
1119 .stream_name = "AIF1 Capture",
1120 .rates = WCD934X_RATES_MASK,
1121 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1127 .ops = &wcd934x_dai_ops,
1130 .name = "wcd934x_rx2",
1133 .stream_name = "AIF2 Playback",
1134 .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK,
1135 .formats = WCD934X_FORMATS_S16_S24_LE,
1141 .ops = &wcd934x_dai_ops,
1144 .name = "wcd934x_tx2",
1147 .stream_name = "AIF2 Capture",
1148 .rates = WCD934X_RATES_MASK,
1149 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1155 .ops = &wcd934x_dai_ops,
1158 .name = "wcd934x_rx3",
1161 .stream_name = "AIF3 Playback",
1162 .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK,
1163 .formats = WCD934X_FORMATS_S16_S24_LE,
1169 .ops = &wcd934x_dai_ops,
1172 .name = "wcd934x_tx3",
1175 .stream_name = "AIF3 Capture",
1176 .rates = WCD934X_RATES_MASK,
1177 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1183 .ops = &wcd934x_dai_ops,
1186 .name = "wcd934x_rx4",
1189 .stream_name = "AIF4 Playback",
1190 .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK,
1191 .formats = WCD934X_FORMATS_S16_S24_LE,
1197 .ops = &wcd934x_dai_ops,
1201 static int swclk_gate_enable(struct clk_hw *hw)
1203 return wcd934x_swrm_clock(to_wcd934x_codec(hw), true);
1206 static void swclk_gate_disable(struct clk_hw *hw)
1208 wcd934x_swrm_clock(to_wcd934x_codec(hw), false);
1211 static int swclk_gate_is_enabled(struct clk_hw *hw)
1213 struct wcd934x_codec *wcd = to_wcd934x_codec(hw);
1216 regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, &val);
1217 ret = val & WCD934X_CDC_SWR_CLK_EN_MASK;
1222 static unsigned long swclk_recalc_rate(struct clk_hw *hw,
1223 unsigned long parent_rate)
1225 return parent_rate / 2;
1228 static const struct clk_ops swclk_gate_ops = {
1229 .prepare = swclk_gate_enable,
1230 .unprepare = swclk_gate_disable,
1231 .is_enabled = swclk_gate_is_enabled,
1232 .recalc_rate = swclk_recalc_rate,
1236 static struct clk *wcd934x_register_mclk_output(struct wcd934x_codec *wcd)
1238 struct clk *parent = wcd->extclk;
1239 struct device *dev = wcd->dev;
1240 struct device_node *np = dev->parent->of_node;
1241 const char *parent_clk_name = NULL;
1242 const char *clk_name = "mclk";
1244 struct clk_init_data init;
1247 if (of_property_read_u32(np, "clock-frequency", &wcd->rate))
1250 parent_clk_name = __clk_get_name(parent);
1252 of_property_read_string(np, "clock-output-names", &clk_name);
1254 init.name = clk_name;
1255 init.ops = &swclk_gate_ops;
1257 init.parent_names = &parent_clk_name;
1258 init.num_parents = 1;
1259 wcd->hw.init = &init;
1262 ret = clk_hw_register(wcd->dev->parent, hw);
1264 return ERR_PTR(ret);
1266 of_clk_add_provider(np, of_clk_src_simple_get, hw->clk);
1271 static int wcd934x_get_micbias_val(struct device *dev, const char *micbias)
1275 if (of_property_read_u32(dev->parent->of_node, micbias, &mv)) {
1276 dev_err(dev, "%s value not found, using default\n", micbias);
1277 mv = WCD934X_DEF_MICBIAS_MV;
1279 /* convert it to milli volts */
1283 if (mv < 1000 || mv > 2850) {
1284 dev_err(dev, "%s value not in valid range, using default\n",
1286 mv = WCD934X_DEF_MICBIAS_MV;
1289 return (mv - 1000) / 50;
1292 static int wcd934x_init_dmic(struct snd_soc_component *comp)
1294 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
1295 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
1296 u32 def_dmic_rate, dmic_clk_drv;
1298 vout_ctl_1 = wcd934x_get_micbias_val(comp->dev,
1299 "qcom,micbias1-microvolt");
1300 vout_ctl_2 = wcd934x_get_micbias_val(comp->dev,
1301 "qcom,micbias2-microvolt");
1302 vout_ctl_3 = wcd934x_get_micbias_val(comp->dev,
1303 "qcom,micbias3-microvolt");
1304 vout_ctl_4 = wcd934x_get_micbias_val(comp->dev,
1305 "qcom,micbias4-microvolt");
1307 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB1,
1308 WCD934X_MICB_VAL_MASK, vout_ctl_1);
1309 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB2,
1310 WCD934X_MICB_VAL_MASK, vout_ctl_2);
1311 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB3,
1312 WCD934X_MICB_VAL_MASK, vout_ctl_3);
1313 snd_soc_component_update_bits(comp, WCD934X_ANA_MICB4,
1314 WCD934X_MICB_VAL_MASK, vout_ctl_4);
1316 if (wcd->rate == WCD934X_MCLK_CLK_9P6MHZ)
1317 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
1319 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
1321 wcd->dmic_sample_rate = def_dmic_rate;
1324 snd_soc_component_update_bits(comp, WCD934X_TEST_DEBUG_PAD_DRVCTL_0,
1325 0x0C, dmic_clk_drv << 2);
1330 static void wcd934x_hw_init(struct wcd934x_codec *wcd)
1332 struct regmap *rm = wcd->regmap;
1334 /* set SPKR rate to FS_2P4_3P072 */
1335 regmap_update_bits(rm, WCD934X_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08);
1336 regmap_update_bits(rm, WCD934X_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08);
1338 /* Take DMICs out of reset */
1339 regmap_update_bits(rm, WCD934X_CPE_SS_DMIC_CFG, 0x80, 0x00);
1342 static int wcd934x_comp_init(struct snd_soc_component *component)
1344 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
1346 wcd934x_hw_init(wcd);
1347 wcd934x_enable_efuse_sensing(wcd);
1348 wcd934x_get_version(wcd);
1353 static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
1355 struct wcd934x_codec *wcd = data;
1356 unsigned long status = 0;
1358 unsigned int val, int_val = 0;
1359 irqreturn_t ret = IRQ_NONE;
1361 unsigned short reg = 0;
1363 for (i = WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
1364 i <= WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
1365 regmap_read(wcd->if_regmap, i, &val);
1366 status |= ((u32)val << (8 * j));
1369 for_each_set_bit(j, &status, 32) {
1378 regmap_read(wcd->if_regmap,
1379 WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val);
1382 reg = WCD934X_SLIM_PGD_PORT_INT_EN0 +
1385 reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 +
1387 regmap_read(wcd->if_regmap, reg, &int_val);
1390 if (val & WCD934X_SLIM_IRQ_OVERFLOW)
1391 dev_err_ratelimited(wcd->dev,
1392 "overflow error on %s port %d, value %x\n",
1393 (tx ? "TX" : "RX"), port_id, val);
1395 if (val & WCD934X_SLIM_IRQ_UNDERFLOW)
1396 dev_err_ratelimited(wcd->dev,
1397 "underflow error on %s port %d, value %x\n",
1398 (tx ? "TX" : "RX"), port_id, val);
1400 if ((val & WCD934X_SLIM_IRQ_OVERFLOW) ||
1401 (val & WCD934X_SLIM_IRQ_UNDERFLOW)) {
1403 reg = WCD934X_SLIM_PGD_PORT_INT_EN0 +
1406 reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 +
1409 wcd->if_regmap, reg, &int_val);
1410 if (int_val & (1 << (port_id % 8))) {
1411 int_val = int_val ^ (1 << (port_id % 8));
1412 regmap_write(wcd->if_regmap,
1417 if (val & WCD934X_SLIM_IRQ_PORT_CLOSED)
1418 dev_err_ratelimited(wcd->dev,
1419 "Port Closed %s port %d, value %x\n",
1420 (tx ? "TX" : "RX"), port_id, val);
1422 regmap_write(wcd->if_regmap,
1423 WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8),
1431 static int wcd934x_comp_probe(struct snd_soc_component *component)
1433 struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
1436 snd_soc_component_init_regmap(component, wcd->regmap);
1437 wcd->component = component;
1440 wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version);
1441 if (IS_ERR(wcd->clsh_ctrl))
1442 return PTR_ERR(wcd->clsh_ctrl);
1444 /* Default HPH Mode to Class-H Low HiFi */
1445 wcd->hph_mode = CLS_H_LOHIFI;
1447 wcd934x_comp_init(component);
1449 for (i = 0; i < NUM_CODEC_DAIS; i++)
1450 INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
1452 wcd934x_init_dmic(component);
1456 static void wcd934x_comp_remove(struct snd_soc_component *comp)
1458 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
1460 wcd_clsh_ctrl_free(wcd->clsh_ctrl);
1463 static int wcd934x_comp_set_sysclk(struct snd_soc_component *comp,
1464 int clk_id, int source,
1465 unsigned int freq, int dir)
1467 struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
1468 int val = WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ;
1472 if (wcd->rate == WCD934X_MCLK_CLK_12P288MHZ)
1473 val = WCD934X_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ;
1475 snd_soc_component_update_bits(comp, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
1476 WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
1479 return clk_set_rate(wcd->extclk, freq);
1482 static const struct snd_soc_component_driver wcd934x_component_drv = {
1483 .probe = wcd934x_comp_probe,
1484 .remove = wcd934x_comp_remove,
1485 .set_sysclk = wcd934x_comp_set_sysclk,
1488 static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
1490 struct device *dev = &wcd->sdev->dev;
1491 struct device_node *ifc_dev_np;
1493 ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0);
1495 dev_err(dev, "No Interface device found\n");
1499 wcd->sidev = of_slim_get_device(wcd->sdev->ctrl, ifc_dev_np);
1501 dev_err(dev, "Unable to get SLIM Interface device\n");
1505 slim_get_logical_addr(wcd->sidev);
1506 wcd->if_regmap = regmap_init_slimbus(wcd->sidev,
1507 &wcd934x_ifc_regmap_config);
1508 if (IS_ERR(wcd->if_regmap)) {
1509 dev_err(dev, "Failed to allocate ifc register map\n");
1510 return PTR_ERR(wcd->if_regmap);
1513 of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate",
1514 &wcd->dmic_sample_rate);
1519 static int wcd934x_codec_probe(struct platform_device *pdev)
1521 struct wcd934x_ddata *data = dev_get_drvdata(pdev->dev.parent);
1522 struct wcd934x_codec *wcd;
1523 struct device *dev = &pdev->dev;
1526 wcd = devm_kzalloc(&pdev->dev, sizeof(*wcd), GFP_KERNEL);
1531 wcd->regmap = data->regmap;
1532 wcd->extclk = data->extclk;
1533 wcd->sdev = to_slim_device(data->dev);
1534 mutex_init(&wcd->sysclk_mutex);
1536 ret = wcd934x_codec_parse_data(wcd);
1538 dev_err(wcd->dev, "Failed to get SLIM IRQ\n");
1542 /* set default rate 9P6MHz */
1543 regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
1544 WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
1545 WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
1546 memcpy(wcd->rx_chs, wcd934x_rx_chs, sizeof(wcd934x_rx_chs));
1547 memcpy(wcd->tx_chs, wcd934x_tx_chs, sizeof(wcd934x_tx_chs));
1549 irq = regmap_irq_get_virq(data->irq_data, WCD934X_IRQ_SLIMBUS);
1551 dev_err(wcd->dev, "Failed to get SLIM IRQ\n");
1555 ret = devm_request_threaded_irq(dev, irq, NULL,
1556 wcd934x_slim_irq_handler,
1557 IRQF_TRIGGER_RISING,
1560 dev_err(dev, "Failed to request slimbus irq\n");
1564 wcd934x_register_mclk_output(wcd);
1565 platform_set_drvdata(pdev, wcd);
1567 return devm_snd_soc_register_component(dev, &wcd934x_component_drv,
1569 ARRAY_SIZE(wcd934x_slim_dais));
1572 static const struct platform_device_id wcd934x_driver_id[] = {
1574 .name = "wcd934x-codec",
1578 MODULE_DEVICE_TABLE(platform, wcd934x_driver_id);
1580 static struct platform_driver wcd934x_codec_driver = {
1581 .probe = &wcd934x_codec_probe,
1582 .id_table = wcd934x_driver_id,
1584 .name = "wcd934x-codec",
1588 MODULE_ALIAS("platform:wcd934x-codec");
1589 module_platform_driver(wcd934x_codec_driver);
1590 MODULE_DESCRIPTION("WCD934x codec driver");
1591 MODULE_LICENSE("GPL v2");