cs42l42.c (bdfa75ad70e93633e18b1ed2b3866c01aa9bf9d2) cs42l42.c (2003c44e28ac9759200a78dda20c5f695949e3f4)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * cs42l42.c -- CS42L42 ALSA SoC audio driver
4 *
5 * Copyright 2016 Cirrus Logic, Inc.
6 *
7 * Author: James Schulman <james.schulman@cirrus.com>
8 * Author: Brian Austin <brian.austin@cirrus.com>

--- 11 unchanged lines hidden (view full) ---

20#include <linux/regmap.h>
21#include <linux/slab.h>
22#include <linux/acpi.h>
23#include <linux/platform_device.h>
24#include <linux/property.h>
25#include <linux/regulator/consumer.h>
26#include <linux/gpio/consumer.h>
27#include <linux/of_device.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * cs42l42.c -- CS42L42 ALSA SoC audio driver
4 *
5 * Copyright 2016 Cirrus Logic, Inc.
6 *
7 * Author: James Schulman <james.schulman@cirrus.com>
8 * Author: Brian Austin <brian.austin@cirrus.com>

--- 11 unchanged lines hidden (view full) ---

20#include <linux/regmap.h>
21#include <linux/slab.h>
22#include <linux/acpi.h>
23#include <linux/platform_device.h>
24#include <linux/property.h>
25#include <linux/regulator/consumer.h>
26#include <linux/gpio/consumer.h>
27#include <linux/of_device.h>
28#include <linux/pm_runtime.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/initval.h>
35#include <sound/tlv.h>
36#include <dt-bindings/sound/cs42l42.h>
37
38#include "cs42l42.h"
39#include "cirrus_legacy.h"
40
41static const struct reg_default cs42l42_reg_defaults[] = {
42 { CS42L42_FRZ_CTL, 0x00 },
43 { CS42L42_SRC_CTL, 0x10 },
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h>
34#include <sound/tlv.h>
35#include <dt-bindings/sound/cs42l42.h>
36
37#include "cs42l42.h"
38#include "cirrus_legacy.h"
39
40static const struct reg_default cs42l42_reg_defaults[] = {
41 { CS42L42_FRZ_CTL, 0x00 },
42 { CS42L42_SRC_CTL, 0x10 },
44 { CS42L42_MCLK_STATUS, 0x02 },
45 { CS42L42_MCLK_CTL, 0x02 },
46 { CS42L42_SFTRAMP_RATE, 0xA4 },
47 { CS42L42_I2C_DEBOUNCE, 0x88 },
48 { CS42L42_I2C_STRETCH, 0x03 },
49 { CS42L42_I2C_TIMEOUT, 0xB7 },
50 { CS42L42_PWR_CTL1, 0xFF },
51 { CS42L42_PWR_CTL2, 0x84 },
52 { CS42L42_PWR_CTL3, 0x20 },
53 { CS42L42_RSENSE_CTL1, 0x40 },
54 { CS42L42_RSENSE_CTL2, 0x00 },
55 { CS42L42_OSC_SWITCH, 0x00 },
43 { CS42L42_MCLK_CTL, 0x02 },
44 { CS42L42_SFTRAMP_RATE, 0xA4 },
45 { CS42L42_I2C_DEBOUNCE, 0x88 },
46 { CS42L42_I2C_STRETCH, 0x03 },
47 { CS42L42_I2C_TIMEOUT, 0xB7 },
48 { CS42L42_PWR_CTL1, 0xFF },
49 { CS42L42_PWR_CTL2, 0x84 },
50 { CS42L42_PWR_CTL3, 0x20 },
51 { CS42L42_RSENSE_CTL1, 0x40 },
52 { CS42L42_RSENSE_CTL2, 0x00 },
53 { CS42L42_OSC_SWITCH, 0x00 },
56 { CS42L42_OSC_SWITCH_STATUS, 0x05 },
57 { CS42L42_RSENSE_CTL3, 0x1B },
58 { CS42L42_TSENSE_CTL, 0x1B },
59 { CS42L42_TSRS_INT_DISABLE, 0x00 },
54 { CS42L42_RSENSE_CTL3, 0x1B },
55 { CS42L42_TSENSE_CTL, 0x1B },
56 { CS42L42_TSRS_INT_DISABLE, 0x00 },
60 { CS42L42_TRSENSE_STATUS, 0x00 },
61 { CS42L42_HSDET_CTL1, 0x77 },
62 { CS42L42_HSDET_CTL2, 0x00 },
63 { CS42L42_HS_SWITCH_CTL, 0xF3 },
57 { CS42L42_HSDET_CTL1, 0x77 },
58 { CS42L42_HSDET_CTL2, 0x00 },
59 { CS42L42_HS_SWITCH_CTL, 0xF3 },
64 { CS42L42_HS_DET_STATUS, 0x00 },
65 { CS42L42_HS_CLAMP_DISABLE, 0x00 },
66 { CS42L42_MCLK_SRC_SEL, 0x00 },
67 { CS42L42_SPDIF_CLK_CFG, 0x00 },
68 { CS42L42_FSYNC_PW_LOWER, 0x00 },
69 { CS42L42_FSYNC_PW_UPPER, 0x00 },
70 { CS42L42_FSYNC_P_LOWER, 0xF9 },
71 { CS42L42_FSYNC_P_UPPER, 0x00 },
72 { CS42L42_ASP_CLK_CFG, 0x00 },
73 { CS42L42_ASP_FRM_CFG, 0x10 },
74 { CS42L42_FS_RATE_EN, 0x00 },
75 { CS42L42_IN_ASRC_CLK, 0x00 },
76 { CS42L42_OUT_ASRC_CLK, 0x00 },
77 { CS42L42_PLL_DIV_CFG1, 0x00 },
60 { CS42L42_HS_CLAMP_DISABLE, 0x00 },
61 { CS42L42_MCLK_SRC_SEL, 0x00 },
62 { CS42L42_SPDIF_CLK_CFG, 0x00 },
63 { CS42L42_FSYNC_PW_LOWER, 0x00 },
64 { CS42L42_FSYNC_PW_UPPER, 0x00 },
65 { CS42L42_FSYNC_P_LOWER, 0xF9 },
66 { CS42L42_FSYNC_P_UPPER, 0x00 },
67 { CS42L42_ASP_CLK_CFG, 0x00 },
68 { CS42L42_ASP_FRM_CFG, 0x10 },
69 { CS42L42_FS_RATE_EN, 0x00 },
70 { CS42L42_IN_ASRC_CLK, 0x00 },
71 { CS42L42_OUT_ASRC_CLK, 0x00 },
72 { CS42L42_PLL_DIV_CFG1, 0x00 },
78 { CS42L42_ADC_OVFL_STATUS, 0x00 },
79 { CS42L42_MIXER_STATUS, 0x00 },
80 { CS42L42_SRC_STATUS, 0x00 },
81 { CS42L42_ASP_RX_STATUS, 0x00 },
82 { CS42L42_ASP_TX_STATUS, 0x00 },
83 { CS42L42_CODEC_STATUS, 0x00 },
84 { CS42L42_DET_INT_STATUS1, 0x00 },
85 { CS42L42_DET_INT_STATUS2, 0x00 },
86 { CS42L42_SRCPL_INT_STATUS, 0x00 },
87 { CS42L42_VPMON_STATUS, 0x00 },
88 { CS42L42_PLL_LOCK_STATUS, 0x00 },
89 { CS42L42_TSRS_PLUG_STATUS, 0x00 },
90 { CS42L42_ADC_OVFL_INT_MASK, 0x01 },
91 { CS42L42_MIXER_INT_MASK, 0x0F },
92 { CS42L42_SRC_INT_MASK, 0x0F },
93 { CS42L42_ASP_RX_INT_MASK, 0x1F },
94 { CS42L42_ASP_TX_INT_MASK, 0x0F },
95 { CS42L42_CODEC_INT_MASK, 0x03 },
73 { CS42L42_ADC_OVFL_INT_MASK, 0x01 },
74 { CS42L42_MIXER_INT_MASK, 0x0F },
75 { CS42L42_SRC_INT_MASK, 0x0F },
76 { CS42L42_ASP_RX_INT_MASK, 0x1F },
77 { CS42L42_ASP_TX_INT_MASK, 0x0F },
78 { CS42L42_CODEC_INT_MASK, 0x03 },
96 { CS42L42_SRCPL_INT_MASK, 0xFF },
79 { CS42L42_SRCPL_INT_MASK, 0x7F },
97 { CS42L42_VPMON_INT_MASK, 0x01 },
98 { CS42L42_PLL_LOCK_INT_MASK, 0x01 },
99 { CS42L42_TSRS_PLUG_INT_MASK, 0x0F },
100 { CS42L42_PLL_CTL1, 0x00 },
101 { CS42L42_PLL_DIV_FRAC0, 0x00 },
102 { CS42L42_PLL_DIV_FRAC1, 0x00 },
103 { CS42L42_PLL_DIV_FRAC2, 0x00 },
104 { CS42L42_PLL_DIV_INT, 0x40 },
105 { CS42L42_PLL_CTL3, 0x10 },
106 { CS42L42_PLL_CAL_RATIO, 0x80 },
107 { CS42L42_PLL_CTL4, 0x03 },
80 { CS42L42_VPMON_INT_MASK, 0x01 },
81 { CS42L42_PLL_LOCK_INT_MASK, 0x01 },
82 { CS42L42_TSRS_PLUG_INT_MASK, 0x0F },
83 { CS42L42_PLL_CTL1, 0x00 },
84 { CS42L42_PLL_DIV_FRAC0, 0x00 },
85 { CS42L42_PLL_DIV_FRAC1, 0x00 },
86 { CS42L42_PLL_DIV_FRAC2, 0x00 },
87 { CS42L42_PLL_DIV_INT, 0x40 },
88 { CS42L42_PLL_CTL3, 0x10 },
89 { CS42L42_PLL_CAL_RATIO, 0x80 },
90 { CS42L42_PLL_CTL4, 0x03 },
108 { CS42L42_LOAD_DET_RCSTAT, 0x00 },
109 { CS42L42_LOAD_DET_DONE, 0x00 },
110 { CS42L42_LOAD_DET_EN, 0x00 },
111 { CS42L42_HSBIAS_SC_AUTOCTL, 0x03 },
112 { CS42L42_WAKE_CTL, 0xC0 },
113 { CS42L42_ADC_DISABLE_MUTE, 0x00 },
114 { CS42L42_TIPSENSE_CTL, 0x02 },
115 { CS42L42_MISC_DET_CTL, 0x03 },
116 { CS42L42_MIC_DET_CTL1, 0x1F },
117 { CS42L42_MIC_DET_CTL2, 0x2F },
91 { CS42L42_LOAD_DET_EN, 0x00 },
92 { CS42L42_HSBIAS_SC_AUTOCTL, 0x03 },
93 { CS42L42_WAKE_CTL, 0xC0 },
94 { CS42L42_ADC_DISABLE_MUTE, 0x00 },
95 { CS42L42_TIPSENSE_CTL, 0x02 },
96 { CS42L42_MISC_DET_CTL, 0x03 },
97 { CS42L42_MIC_DET_CTL1, 0x1F },
98 { CS42L42_MIC_DET_CTL2, 0x2F },
118 { CS42L42_DET_STATUS1, 0x00 },
119 { CS42L42_DET_STATUS2, 0x00 },
120 { CS42L42_DET_INT1_MASK, 0xE0 },
121 { CS42L42_DET_INT2_MASK, 0xFF },
122 { CS42L42_HS_BIAS_CTL, 0xC2 },
123 { CS42L42_ADC_CTL, 0x00 },
124 { CS42L42_ADC_VOLUME, 0x00 },
125 { CS42L42_ADC_WNF_HPF_CTL, 0x71 },
126 { CS42L42_DAC_CTL1, 0x00 },
127 { CS42L42_DAC_CTL2, 0x02 },
128 { CS42L42_HP_CTL, 0x0D },
129 { CS42L42_CLASSH_CTL, 0x07 },
130 { CS42L42_MIXER_CHA_VOL, 0x3F },
131 { CS42L42_MIXER_ADC_VOL, 0x3F },
132 { CS42L42_MIXER_CHB_VOL, 0x3F },
99 { CS42L42_DET_INT1_MASK, 0xE0 },
100 { CS42L42_DET_INT2_MASK, 0xFF },
101 { CS42L42_HS_BIAS_CTL, 0xC2 },
102 { CS42L42_ADC_CTL, 0x00 },
103 { CS42L42_ADC_VOLUME, 0x00 },
104 { CS42L42_ADC_WNF_HPF_CTL, 0x71 },
105 { CS42L42_DAC_CTL1, 0x00 },
106 { CS42L42_DAC_CTL2, 0x02 },
107 { CS42L42_HP_CTL, 0x0D },
108 { CS42L42_CLASSH_CTL, 0x07 },
109 { CS42L42_MIXER_CHA_VOL, 0x3F },
110 { CS42L42_MIXER_ADC_VOL, 0x3F },
111 { CS42L42_MIXER_CHB_VOL, 0x3F },
133 { CS42L42_EQ_COEF_IN0, 0x22 },
112 { CS42L42_EQ_COEF_IN0, 0x00 },
134 { CS42L42_EQ_COEF_IN1, 0x00 },
135 { CS42L42_EQ_COEF_IN2, 0x00 },
136 { CS42L42_EQ_COEF_IN3, 0x00 },
137 { CS42L42_EQ_COEF_RW, 0x00 },
138 { CS42L42_EQ_COEF_OUT0, 0x00 },
139 { CS42L42_EQ_COEF_OUT1, 0x00 },
140 { CS42L42_EQ_COEF_OUT2, 0x00 },
141 { CS42L42_EQ_COEF_OUT3, 0x00 },

--- 35 unchanged lines hidden (view full) ---

177 { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 },
178 { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0x00 },
179 { CS42L42_ASP_RX_DAI1_CH1_AP_RES, 0x03 },
180 { CS42L42_ASP_RX_DAI1_CH1_BIT_MSB, 0x00 },
181 { CS42L42_ASP_RX_DAI1_CH1_BIT_LSB, 0x00 },
182 { CS42L42_ASP_RX_DAI1_CH2_AP_RES, 0x03 },
183 { CS42L42_ASP_RX_DAI1_CH2_BIT_MSB, 0x00 },
184 { CS42L42_ASP_RX_DAI1_CH2_BIT_LSB, 0x00 },
113 { CS42L42_EQ_COEF_IN1, 0x00 },
114 { CS42L42_EQ_COEF_IN2, 0x00 },
115 { CS42L42_EQ_COEF_IN3, 0x00 },
116 { CS42L42_EQ_COEF_RW, 0x00 },
117 { CS42L42_EQ_COEF_OUT0, 0x00 },
118 { CS42L42_EQ_COEF_OUT1, 0x00 },
119 { CS42L42_EQ_COEF_OUT2, 0x00 },
120 { CS42L42_EQ_COEF_OUT3, 0x00 },

--- 35 unchanged lines hidden (view full) ---

156 { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 },
157 { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0x00 },
158 { CS42L42_ASP_RX_DAI1_CH1_AP_RES, 0x03 },
159 { CS42L42_ASP_RX_DAI1_CH1_BIT_MSB, 0x00 },
160 { CS42L42_ASP_RX_DAI1_CH1_BIT_LSB, 0x00 },
161 { CS42L42_ASP_RX_DAI1_CH2_AP_RES, 0x03 },
162 { CS42L42_ASP_RX_DAI1_CH2_BIT_MSB, 0x00 },
163 { CS42L42_ASP_RX_DAI1_CH2_BIT_LSB, 0x00 },
185 { CS42L42_SUB_REVID, 0x03 },
186};
187
188static bool cs42l42_readable_register(struct device *dev, unsigned int reg)
189{
190 switch (reg) {
191 case CS42L42_PAGE_REGISTER:
192 case CS42L42_DEVID_AB:
193 case CS42L42_DEVID_CD:

--- 152 unchanged lines hidden (view full) ---

346
347static bool cs42l42_volatile_register(struct device *dev, unsigned int reg)
348{
349 switch (reg) {
350 case CS42L42_DEVID_AB:
351 case CS42L42_DEVID_CD:
352 case CS42L42_DEVID_E:
353 case CS42L42_MCLK_STATUS:
164};
165
166static bool cs42l42_readable_register(struct device *dev, unsigned int reg)
167{
168 switch (reg) {
169 case CS42L42_PAGE_REGISTER:
170 case CS42L42_DEVID_AB:
171 case CS42L42_DEVID_CD:

--- 152 unchanged lines hidden (view full) ---

324
325static bool cs42l42_volatile_register(struct device *dev, unsigned int reg)
326{
327 switch (reg) {
328 case CS42L42_DEVID_AB:
329 case CS42L42_DEVID_CD:
330 case CS42L42_DEVID_E:
331 case CS42L42_MCLK_STATUS:
332 case CS42L42_OSC_SWITCH_STATUS:
354 case CS42L42_TRSENSE_STATUS:
355 case CS42L42_HS_DET_STATUS:
356 case CS42L42_ADC_OVFL_STATUS:
357 case CS42L42_MIXER_STATUS:
358 case CS42L42_SRC_STATUS:
359 case CS42L42_ASP_RX_STATUS:
360 case CS42L42_ASP_TX_STATUS:
361 case CS42L42_CODEC_STATUS:

--- 88 unchanged lines hidden (view full) ---

450 CS42L42_DACB_INV_SHIFT, true, false),
451 SOC_SINGLE("DAC HPF Switch", CS42L42_DAC_CTL2,
452 CS42L42_DAC_HPF_EN_SHIFT, true, false),
453 SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL,
454 CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT,
455 0x3f, 1, mixer_tlv)
456};
457
333 case CS42L42_TRSENSE_STATUS:
334 case CS42L42_HS_DET_STATUS:
335 case CS42L42_ADC_OVFL_STATUS:
336 case CS42L42_MIXER_STATUS:
337 case CS42L42_SRC_STATUS:
338 case CS42L42_ASP_RX_STATUS:
339 case CS42L42_ASP_TX_STATUS:
340 case CS42L42_CODEC_STATUS:

--- 88 unchanged lines hidden (view full) ---

429 CS42L42_DACB_INV_SHIFT, true, false),
430 SOC_SINGLE("DAC HPF Switch", CS42L42_DAC_CTL2,
431 CS42L42_DAC_HPF_EN_SHIFT, true, false),
432 SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL,
433 CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT,
434 0x3f, 1, mixer_tlv)
435};
436
437static int cs42l42_hp_adc_ev(struct snd_soc_dapm_widget *w,
438 struct snd_kcontrol *kcontrol, int event)
439{
440 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
441 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
442
443 switch (event) {
444 case SND_SOC_DAPM_PRE_PMU:
445 cs42l42->hp_adc_up_pending = true;
446 break;
447 case SND_SOC_DAPM_POST_PMU:
448 /* Only need one delay if HP and ADC are both powering-up */
449 if (cs42l42->hp_adc_up_pending) {
450 usleep_range(CS42L42_HP_ADC_EN_TIME_US,
451 CS42L42_HP_ADC_EN_TIME_US + 1000);
452 cs42l42->hp_adc_up_pending = false;
453 }
454 break;
455 default:
456 break;
457 }
458
459 return 0;
460}
461
458static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = {
459 /* Playback Path */
460 SND_SOC_DAPM_OUTPUT("HP"),
462static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = {
463 /* Playback Path */
464 SND_SOC_DAPM_OUTPUT("HP"),
461 SND_SOC_DAPM_DAC("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1),
465 SND_SOC_DAPM_DAC_E("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1,
466 cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
462 SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0),
463 SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0),
464 SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0),
465
466 /* Playback Requirements */
467 SND_SOC_DAPM_SUPPLY("ASP DAI0", CS42L42_PWR_CTL1, CS42L42_ASP_DAI_PDN_SHIFT, 1, NULL, 0),
468
469 /* Capture Path */
470 SND_SOC_DAPM_INPUT("HS"),
467 SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0),
468 SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0),
469 SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0),
470
471 /* Playback Requirements */
472 SND_SOC_DAPM_SUPPLY("ASP DAI0", CS42L42_PWR_CTL1, CS42L42_ASP_DAI_PDN_SHIFT, 1, NULL, 0),
473
474 /* Capture Path */
475 SND_SOC_DAPM_INPUT("HS"),
471 SND_SOC_DAPM_ADC("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1),
476 SND_SOC_DAPM_ADC_E("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1,
477 cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
472 SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0),
473 SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0),
474
475 /* Capture Requirements */
476 SND_SOC_DAPM_SUPPLY("ASP DAO0", CS42L42_PWR_CTL1, CS42L42_ASP_DAO_PDN_SHIFT, 1, NULL, 0),
477 SND_SOC_DAPM_SUPPLY("ASP TX EN", CS42L42_ASP_TX_SZ_EN, CS42L42_ASP_TX_EN_SHIFT, 0, NULL, 0),
478
479 /* Playback/Capture Requirements */

--- 32 unchanged lines hidden (view full) ---

512};
513
514static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d)
515{
516 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
517
518 cs42l42->jack = jk;
519
478 SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0),
479 SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0),
480
481 /* Capture Requirements */
482 SND_SOC_DAPM_SUPPLY("ASP DAO0", CS42L42_PWR_CTL1, CS42L42_ASP_DAO_PDN_SHIFT, 1, NULL, 0),
483 SND_SOC_DAPM_SUPPLY("ASP TX EN", CS42L42_ASP_TX_SZ_EN, CS42L42_ASP_TX_EN_SHIFT, 0, NULL, 0),
484
485 /* Playback/Capture Requirements */

--- 32 unchanged lines hidden (view full) ---

518};
519
520static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d)
521{
522 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
523
524 cs42l42->jack = jk;
525
520 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
521 CS42L42_RS_PLUG_MASK | CS42L42_RS_UNPLUG_MASK |
522 CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK,
523 (1 << CS42L42_RS_PLUG_SHIFT) | (1 << CS42L42_RS_UNPLUG_SHIFT) |
524 (0 << CS42L42_TS_PLUG_SHIFT) | (0 << CS42L42_TS_UNPLUG_SHIFT));
525
526 return 0;
527}
528
526 return 0;
527}
528
529static int cs42l42_component_probe(struct snd_soc_component *component)
530{
531 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
532
533 cs42l42->component = component;
534
535 return 0;
536}
537
538static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
529static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
539 .probe = cs42l42_component_probe,
540 .set_jack = cs42l42_set_jack,
541 .dapm_widgets = cs42l42_dapm_widgets,
542 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
543 .dapm_routes = cs42l42_audio_map,
544 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),
545 .controls = cs42l42_snd_controls,
546 .num_controls = ARRAY_SIZE(cs42l42_snd_controls),
547 .idle_bias_on = 1,

--- 16 unchanged lines hidden (view full) ---

564 .reg = CS42L42_OSC_SWITCH,
565 .def = 0,
566 .delay_us = CS42L42_CLOCK_SWITCH_DELAY_US,
567 },
568};
569
570struct cs42l42_pll_params {
571 u32 sclk;
530 .set_jack = cs42l42_set_jack,
531 .dapm_widgets = cs42l42_dapm_widgets,
532 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
533 .dapm_routes = cs42l42_audio_map,
534 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),
535 .controls = cs42l42_snd_controls,
536 .num_controls = ARRAY_SIZE(cs42l42_snd_controls),
537 .idle_bias_on = 1,

--- 16 unchanged lines hidden (view full) ---

554 .reg = CS42L42_OSC_SWITCH,
555 .def = 0,
556 .delay_us = CS42L42_CLOCK_SWITCH_DELAY_US,
557 },
558};
559
560struct cs42l42_pll_params {
561 u32 sclk;
572 u8 mclk_div;
573 u8 mclk_src_sel;
574 u8 sclk_prediv;
575 u8 pll_div_int;
576 u32 pll_div_frac;
577 u8 pll_mode;
578 u8 pll_divout;
579 u32 mclk_int;
580 u8 pll_cal_ratio;
581 u8 n;
582};
583
584/*
585 * Common PLL Settings for given SCLK
586 * Table 4-5 from the Datasheet
587 */
588static const struct cs42l42_pll_params pll_ratio_table[] = {
562 u8 mclk_src_sel;
563 u8 sclk_prediv;
564 u8 pll_div_int;
565 u32 pll_div_frac;
566 u8 pll_mode;
567 u8 pll_divout;
568 u32 mclk_int;
569 u8 pll_cal_ratio;
570 u8 n;
571};
572
573/*
574 * Common PLL Settings for given SCLK
575 * Table 4-5 from the Datasheet
576 */
577static const struct cs42l42_pll_params pll_ratio_table[] = {
589 { 1411200, 0, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2},
590 { 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
591 { 2304000, 0, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2},
592 { 2400000, 0, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2},
593 { 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
594 { 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
595 { 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
596 { 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1},
597 { 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1},
598 { 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
599 { 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
600 { 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
601 { 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
602 { 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
603 { 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
604 { 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1},
605 { 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1},
606 { 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1}
578 { 1411200, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2},
579 { 1536000, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
580 { 2304000, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2},
581 { 2400000, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2},
582 { 2822400, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
583 { 3000000, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
584 { 3072000, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
585 { 4000000, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1},
586 { 4096000, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1},
587 { 5644800, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
588 { 6000000, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
589 { 6144000, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
590 { 11289600, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
591 { 12000000, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
592 { 12288000, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
593 { 22579200, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
594 { 24000000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
595 { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1}
607};
608
609static int cs42l42_pll_config(struct snd_soc_component *component)
610{
611 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
612 int i;
613 u32 clk;
614 u32 fsync;
615
616 if (!cs42l42->sclk)
617 clk = cs42l42->bclk;
618 else
619 clk = cs42l42->sclk;
620
596};
597
598static int cs42l42_pll_config(struct snd_soc_component *component)
599{
600 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
601 int i;
602 u32 clk;
603 u32 fsync;
604
605 if (!cs42l42->sclk)
606 clk = cs42l42->bclk;
607 else
608 clk = cs42l42->sclk;
609
610 /* Don't reconfigure if there is an audio stream running */
611 if (cs42l42->stream_use) {
612 if (pll_ratio_table[cs42l42->pll_config].sclk == clk)
613 return 0;
614 else
615 return -EBUSY;
616 }
617
621 for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
622 if (pll_ratio_table[i].sclk == clk) {
623 cs42l42->pll_config = i;
624
625 /* Configure the internal sample rate */
626 snd_soc_component_update_bits(component, CS42L42_MCLK_CTL,
627 CS42L42_INTERNAL_FS_MASK,
628 ((pll_ratio_table[i].mclk_int !=
629 12000000) &&
630 (pll_ratio_table[i].mclk_int !=
631 24000000)) <<
632 CS42L42_INTERNAL_FS_SHIFT);
633
618 for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
619 if (pll_ratio_table[i].sclk == clk) {
620 cs42l42->pll_config = i;
621
622 /* Configure the internal sample rate */
623 snd_soc_component_update_bits(component, CS42L42_MCLK_CTL,
624 CS42L42_INTERNAL_FS_MASK,
625 ((pll_ratio_table[i].mclk_int !=
626 12000000) &&
627 (pll_ratio_table[i].mclk_int !=
628 24000000)) <<
629 CS42L42_INTERNAL_FS_SHIFT);
630
634 snd_soc_component_update_bits(component, CS42L42_MCLK_SRC_SEL,
635 CS42L42_MCLKDIV_MASK,
636 (pll_ratio_table[i].mclk_div <<
637 CS42L42_MCLKDIV_SHIFT));
638 /* Set up the LRCLK */
639 fsync = clk / cs42l42->srate;
640 if (((fsync * cs42l42->srate) != clk)
641 || ((fsync % 2) != 0)) {
642 dev_err(component->dev,
643 "Unsupported sclk %d/sample rate %d\n",
644 clk,
645 cs42l42->srate);

--- 17 unchanged lines hidden (view full) ---

663 CS42L42_FSYNC_PULSE_WIDTH_MASK,
664 CS42L42_FRAC0_VAL(fsync - 1) <<
665 CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
666 snd_soc_component_update_bits(component,
667 CS42L42_FSYNC_PW_UPPER,
668 CS42L42_FSYNC_PULSE_WIDTH_MASK,
669 CS42L42_FRAC1_VAL(fsync - 1) <<
670 CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
631 /* Set up the LRCLK */
632 fsync = clk / cs42l42->srate;
633 if (((fsync * cs42l42->srate) != clk)
634 || ((fsync % 2) != 0)) {
635 dev_err(component->dev,
636 "Unsupported sclk %d/sample rate %d\n",
637 clk,
638 cs42l42->srate);

--- 17 unchanged lines hidden (view full) ---

656 CS42L42_FSYNC_PULSE_WIDTH_MASK,
657 CS42L42_FRAC0_VAL(fsync - 1) <<
658 CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
659 snd_soc_component_update_bits(component,
660 CS42L42_FSYNC_PW_UPPER,
661 CS42L42_FSYNC_PULSE_WIDTH_MASK,
662 CS42L42_FRAC1_VAL(fsync - 1) <<
663 CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
671 /* Set the sample rates (96k or lower) */
672 snd_soc_component_update_bits(component, CS42L42_FS_RATE_EN,
673 CS42L42_FS_EN_MASK,
674 (CS42L42_FS_EN_IASRC_96K |
675 CS42L42_FS_EN_OASRC_96K) <<
676 CS42L42_FS_EN_SHIFT);
677 /* Set the input/output internal MCLK clock ~12 MHz */
678 snd_soc_component_update_bits(component, CS42L42_IN_ASRC_CLK,
679 CS42L42_CLK_IASRC_SEL_MASK,
680 CS42L42_CLK_IASRC_SEL_12 <<
681 CS42L42_CLK_IASRC_SEL_SHIFT);
682 snd_soc_component_update_bits(component,
683 CS42L42_OUT_ASRC_CLK,
684 CS42L42_CLK_OASRC_SEL_MASK,
685 CS42L42_CLK_OASRC_SEL_12 <<
686 CS42L42_CLK_OASRC_SEL_SHIFT);
687 if (pll_ratio_table[i].mclk_src_sel == 0) {
688 /* Pass the clock straight through */
689 snd_soc_component_update_bits(component,
690 CS42L42_PLL_CTL1,
691 CS42L42_PLL_START_MASK, 0);
692 } else {
693 /* Configure PLL per table 4-5 */
694 snd_soc_component_update_bits(component,

--- 46 unchanged lines hidden (view full) ---

741 }
742 return 0;
743 }
744 }
745
746 return -EINVAL;
747}
748
664 if (pll_ratio_table[i].mclk_src_sel == 0) {
665 /* Pass the clock straight through */
666 snd_soc_component_update_bits(component,
667 CS42L42_PLL_CTL1,
668 CS42L42_PLL_START_MASK, 0);
669 } else {
670 /* Configure PLL per table 4-5 */
671 snd_soc_component_update_bits(component,

--- 46 unchanged lines hidden (view full) ---

718 }
719 return 0;
720 }
721 }
722
723 return -EINVAL;
724}
725
726static void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate)
727{
728 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
729 unsigned int fs;
730
731 /* Don't reconfigure if there is an audio stream running */
732 if (cs42l42->stream_use)
733 return;
734
735 /* SRC MCLK must be as close as possible to 125 * sample rate */
736 if (sample_rate <= 48000)
737 fs = CS42L42_CLK_IASRC_SEL_6;
738 else
739 fs = CS42L42_CLK_IASRC_SEL_12;
740
741 /* Set the sample rates (96k or lower) */
742 snd_soc_component_update_bits(component,
743 CS42L42_FS_RATE_EN,
744 CS42L42_FS_EN_MASK,
745 (CS42L42_FS_EN_IASRC_96K |
746 CS42L42_FS_EN_OASRC_96K) <<
747 CS42L42_FS_EN_SHIFT);
748
749 snd_soc_component_update_bits(component,
750 CS42L42_IN_ASRC_CLK,
751 CS42L42_CLK_IASRC_SEL_MASK,
752 fs << CS42L42_CLK_IASRC_SEL_SHIFT);
753 snd_soc_component_update_bits(component,
754 CS42L42_OUT_ASRC_CLK,
755 CS42L42_CLK_OASRC_SEL_MASK,
756 fs << CS42L42_CLK_OASRC_SEL_SHIFT);
757}
758
749static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
750{
751 struct snd_soc_component *component = codec_dai->component;
752 u32 asp_cfg_val = 0;
753
754 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
755 case SND_SOC_DAIFMT_CBS_CFM:
756 asp_cfg_val |= CS42L42_ASP_MASTER_MODE <<

--- 62 unchanged lines hidden (view full) ---

819 * legal.
820 */
821 if (cs42l42->sclk)
822 return 0;
823
824 /* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */
825 return snd_pcm_hw_constraint_minmax(substream->runtime,
826 SNDRV_PCM_HW_PARAM_RATE,
759static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
760{
761 struct snd_soc_component *component = codec_dai->component;
762 u32 asp_cfg_val = 0;
763
764 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
765 case SND_SOC_DAIFMT_CBS_CFM:
766 asp_cfg_val |= CS42L42_ASP_MASTER_MODE <<

--- 62 unchanged lines hidden (view full) ---

829 * legal.
830 */
831 if (cs42l42->sclk)
832 return 0;
833
834 /* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */
835 return snd_pcm_hw_constraint_minmax(substream->runtime,
836 SNDRV_PCM_HW_PARAM_RATE,
827 44100, 192000);
837 44100, 96000);
828}
829
830static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
831 struct snd_pcm_hw_params *params,
832 struct snd_soc_dai *dai)
833{
834 struct snd_soc_component *component = dai->component;
835 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
836 unsigned int channels = params_channels(params);
837 unsigned int width = (params_width(params) / 8) - 1;
838 unsigned int val = 0;
838}
839
840static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
841 struct snd_pcm_hw_params *params,
842 struct snd_soc_dai *dai)
843{
844 struct snd_soc_component *component = dai->component;
845 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
846 unsigned int channels = params_channels(params);
847 unsigned int width = (params_width(params) / 8) - 1;
848 unsigned int val = 0;
849 int ret;
839
840 cs42l42->srate = params_rate(params);
841 cs42l42->bclk = snd_soc_params_to_bclk(params);
842
843 /* I2S frame always has 2 channels even for mono audio */
844 if (channels == 1)
845 cs42l42->bclk *= 2;
846
847 /*
848 * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
849 * more than assumed (which would result in overclocking).
850 */
851 if (params_width(params) == 24)
852 cs42l42->bclk = (cs42l42->bclk / 3) * 4;
853
850
851 cs42l42->srate = params_rate(params);
852 cs42l42->bclk = snd_soc_params_to_bclk(params);
853
854 /* I2S frame always has 2 channels even for mono audio */
855 if (channels == 1)
856 cs42l42->bclk *= 2;
857
858 /*
859 * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
860 * more than assumed (which would result in overclocking).
861 */
862 if (params_width(params) == 24)
863 cs42l42->bclk = (cs42l42->bclk / 3) * 4;
864
854 switch(substream->stream) {
865 switch (substream->stream) {
855 case SNDRV_PCM_STREAM_CAPTURE:
866 case SNDRV_PCM_STREAM_CAPTURE:
856 if (channels == 2) {
857 val |= CS42L42_ASP_TX_CH2_AP_MASK;
858 val |= width << CS42L42_ASP_TX_CH2_RES_SHIFT;
859 }
860 val |= width << CS42L42_ASP_TX_CH1_RES_SHIFT;
867 /* channel 2 on high LRCLK */
868 val = CS42L42_ASP_TX_CH2_AP_MASK |
869 (width << CS42L42_ASP_TX_CH2_RES_SHIFT) |
870 (width << CS42L42_ASP_TX_CH1_RES_SHIFT);
861
862 snd_soc_component_update_bits(component, CS42L42_ASP_TX_CH_AP_RES,
863 CS42L42_ASP_TX_CH1_AP_MASK | CS42L42_ASP_TX_CH2_AP_MASK |
864 CS42L42_ASP_TX_CH2_RES_MASK | CS42L42_ASP_TX_CH1_RES_MASK, val);
865 break;
866 case SNDRV_PCM_STREAM_PLAYBACK:
867 val |= width << CS42L42_ASP_RX_CH_RES_SHIFT;
868 /* channel 1 on low LRCLK */

--- 16 unchanged lines hidden (view full) ---

885 CS42L42_ASP_RX0_CH_EN_MASK,
886 BIT(CS42L42_ASP_RX0_CH1_SHIFT) |
887 BIT(CS42L42_ASP_RX0_CH2_SHIFT));
888 break;
889 default:
890 break;
891 }
892
871
872 snd_soc_component_update_bits(component, CS42L42_ASP_TX_CH_AP_RES,
873 CS42L42_ASP_TX_CH1_AP_MASK | CS42L42_ASP_TX_CH2_AP_MASK |
874 CS42L42_ASP_TX_CH2_RES_MASK | CS42L42_ASP_TX_CH1_RES_MASK, val);
875 break;
876 case SNDRV_PCM_STREAM_PLAYBACK:
877 val |= width << CS42L42_ASP_RX_CH_RES_SHIFT;
878 /* channel 1 on low LRCLK */

--- 16 unchanged lines hidden (view full) ---

895 CS42L42_ASP_RX0_CH_EN_MASK,
896 BIT(CS42L42_ASP_RX0_CH1_SHIFT) |
897 BIT(CS42L42_ASP_RX0_CH2_SHIFT));
898 break;
899 default:
900 break;
901 }
902
893 return cs42l42_pll_config(component);
903 ret = cs42l42_pll_config(component);
904 if (ret)
905 return ret;
906
907 cs42l42_src_config(component, params_rate(params));
908
909 return 0;
894}
895
896static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
897 int clk_id, unsigned int freq, int dir)
898{
899 struct snd_soc_component *component = dai->component;
900 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
901 int i;

--- 27 unchanged lines hidden (view full) ---

929 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
930 snd_soc_component_update_bits(component, CS42L42_HP_CTL,
931 CS42L42_HP_ANA_AMUTE_MASK |
932 CS42L42_HP_ANA_BMUTE_MASK,
933 CS42L42_HP_ANA_AMUTE_MASK |
934 CS42L42_HP_ANA_BMUTE_MASK);
935
936 cs42l42->stream_use &= ~(1 << stream);
910}
911
912static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
913 int clk_id, unsigned int freq, int dir)
914{
915 struct snd_soc_component *component = dai->component;
916 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
917 int i;

--- 27 unchanged lines hidden (view full) ---

945 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
946 snd_soc_component_update_bits(component, CS42L42_HP_CTL,
947 CS42L42_HP_ANA_AMUTE_MASK |
948 CS42L42_HP_ANA_BMUTE_MASK,
949 CS42L42_HP_ANA_AMUTE_MASK |
950 CS42L42_HP_ANA_BMUTE_MASK);
951
952 cs42l42->stream_use &= ~(1 << stream);
937 if(!cs42l42->stream_use) {
953 if (!cs42l42->stream_use) {
938 /*
939 * Switch to the internal oscillator.
940 * SCLK must remain running until after this clock switch.
941 * Without a source of clock the I2C bus doesn't work.
942 */
943 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_osc_seq,
944 ARRAY_SIZE(cs42l42_to_osc_seq));
945

--- 54 unchanged lines hidden (view full) ---

1000 }
1001 }
1002
1003 return 0;
1004}
1005
1006#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1007 SNDRV_PCM_FMTBIT_S24_LE |\
954 /*
955 * Switch to the internal oscillator.
956 * SCLK must remain running until after this clock switch.
957 * Without a source of clock the I2C bus doesn't work.
958 */
959 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_osc_seq,
960 ARRAY_SIZE(cs42l42_to_osc_seq));
961

--- 54 unchanged lines hidden (view full) ---

1016 }
1017 }
1018
1019 return 0;
1020}
1021
1022#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1023 SNDRV_PCM_FMTBIT_S24_LE |\
1008 SNDRV_PCM_FMTBIT_S32_LE )
1024 SNDRV_PCM_FMTBIT_S32_LE)
1009
1010static const struct snd_soc_dai_ops cs42l42_ops = {
1011 .startup = cs42l42_dai_startup,
1012 .hw_params = cs42l42_pcm_hw_params,
1013 .set_fmt = cs42l42_set_dai_fmt,
1014 .set_sysclk = cs42l42_set_sysclk,
1015 .mute_stream = cs42l42_mute_stream,
1016};
1017
1018static struct snd_soc_dai_driver cs42l42_dai = {
1019 .name = "cs42l42",
1020 .playback = {
1021 .stream_name = "Playback",
1022 .channels_min = 1,
1023 .channels_max = 2,
1025
1026static const struct snd_soc_dai_ops cs42l42_ops = {
1027 .startup = cs42l42_dai_startup,
1028 .hw_params = cs42l42_pcm_hw_params,
1029 .set_fmt = cs42l42_set_dai_fmt,
1030 .set_sysclk = cs42l42_set_sysclk,
1031 .mute_stream = cs42l42_mute_stream,
1032};
1033
1034static struct snd_soc_dai_driver cs42l42_dai = {
1035 .name = "cs42l42",
1036 .playback = {
1037 .stream_name = "Playback",
1038 .channels_min = 1,
1039 .channels_max = 2,
1024 .rates = SNDRV_PCM_RATE_8000_192000,
1040 .rates = SNDRV_PCM_RATE_8000_96000,
1025 .formats = CS42L42_FORMATS,
1026 },
1027 .capture = {
1028 .stream_name = "Capture",
1029 .channels_min = 1,
1030 .channels_max = 2,
1041 .formats = CS42L42_FORMATS,
1042 },
1043 .capture = {
1044 .stream_name = "Capture",
1045 .channels_min = 1,
1046 .channels_max = 2,
1031 .rates = SNDRV_PCM_RATE_8000_192000,
1047 .rates = SNDRV_PCM_RATE_8000_96000,
1032 .formats = CS42L42_FORMATS,
1033 },
1034 .symmetric_rate = 1,
1035 .symmetric_sample_bits = 1,
1036 .ops = &cs42l42_ops,
1037};
1038
1048 .formats = CS42L42_FORMATS,
1049 },
1050 .symmetric_rate = 1,
1051 .symmetric_sample_bits = 1,
1052 .ops = &cs42l42_ops,
1053};
1054
1055static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42)
1056{
1057 unsigned int hs_det_status;
1058 unsigned int hs_det_comp1;
1059 unsigned int hs_det_comp2;
1060 unsigned int hs_det_sw;
1061
1062 /* Set hs detect to manual, active mode */
1063 regmap_update_bits(cs42l42->regmap,
1064 CS42L42_HSDET_CTL2,
1065 CS42L42_HSDET_CTRL_MASK |
1066 CS42L42_HSDET_SET_MASK |
1067 CS42L42_HSBIAS_REF_MASK |
1068 CS42L42_HSDET_AUTO_TIME_MASK,
1069 (1 << CS42L42_HSDET_CTRL_SHIFT) |
1070 (0 << CS42L42_HSDET_SET_SHIFT) |
1071 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1072 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1073
1074 /* Configure HS DET comparator reference levels. */
1075 regmap_update_bits(cs42l42->regmap,
1076 CS42L42_HSDET_CTL1,
1077 CS42L42_HSDET_COMP1_LVL_MASK |
1078 CS42L42_HSDET_COMP2_LVL_MASK,
1079 (CS42L42_HSDET_COMP1_LVL_VAL << CS42L42_HSDET_COMP1_LVL_SHIFT) |
1080 (CS42L42_HSDET_COMP2_LVL_VAL << CS42L42_HSDET_COMP2_LVL_SHIFT));
1081
1082 /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */
1083 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1);
1084
1085 msleep(100);
1086
1087 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1088
1089 hs_det_comp1 = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >>
1090 CS42L42_HSDET_COMP1_OUT_SHIFT;
1091 hs_det_comp2 = (hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >>
1092 CS42L42_HSDET_COMP2_OUT_SHIFT;
1093
1094 /* Close the SW_HSB_HS3 switch for a Type 2 headset. */
1095 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2);
1096
1097 msleep(100);
1098
1099 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1100
1101 hs_det_comp1 |= ((hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >>
1102 CS42L42_HSDET_COMP1_OUT_SHIFT) << 1;
1103 hs_det_comp2 |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >>
1104 CS42L42_HSDET_COMP2_OUT_SHIFT) << 1;
1105
1106 /* Use Comparator 1 with 1.25V Threshold. */
1107 switch (hs_det_comp1) {
1108 case CS42L42_HSDET_COMP_TYPE1:
1109 cs42l42->hs_type = CS42L42_PLUG_CTIA;
1110 hs_det_sw = CS42L42_HSDET_SW_TYPE1;
1111 break;
1112 case CS42L42_HSDET_COMP_TYPE2:
1113 cs42l42->hs_type = CS42L42_PLUG_OMTP;
1114 hs_det_sw = CS42L42_HSDET_SW_TYPE2;
1115 break;
1116 default:
1117 /* Fallback to Comparator 2 with 1.75V Threshold. */
1118 switch (hs_det_comp2) {
1119 case CS42L42_HSDET_COMP_TYPE1:
1120 cs42l42->hs_type = CS42L42_PLUG_CTIA;
1121 hs_det_sw = CS42L42_HSDET_SW_TYPE1;
1122 break;
1123 case CS42L42_HSDET_COMP_TYPE2:
1124 cs42l42->hs_type = CS42L42_PLUG_OMTP;
1125 hs_det_sw = CS42L42_HSDET_SW_TYPE2;
1126 break;
1127 case CS42L42_HSDET_COMP_TYPE3:
1128 cs42l42->hs_type = CS42L42_PLUG_HEADPHONE;
1129 hs_det_sw = CS42L42_HSDET_SW_TYPE3;
1130 break;
1131 default:
1132 cs42l42->hs_type = CS42L42_PLUG_INVALID;
1133 hs_det_sw = CS42L42_HSDET_SW_TYPE4;
1134 break;
1135 }
1136 }
1137
1138 /* Set Switches */
1139 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, hs_det_sw);
1140
1141 /* Set HSDET mode to Manual—Disabled */
1142 regmap_update_bits(cs42l42->regmap,
1143 CS42L42_HSDET_CTL2,
1144 CS42L42_HSDET_CTRL_MASK |
1145 CS42L42_HSDET_SET_MASK |
1146 CS42L42_HSBIAS_REF_MASK |
1147 CS42L42_HSDET_AUTO_TIME_MASK,
1148 (0 << CS42L42_HSDET_CTRL_SHIFT) |
1149 (0 << CS42L42_HSDET_SET_SHIFT) |
1150 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1151 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1152
1153 /* Configure HS DET comparator reference levels. */
1154 regmap_update_bits(cs42l42->regmap,
1155 CS42L42_HSDET_CTL1,
1156 CS42L42_HSDET_COMP1_LVL_MASK |
1157 CS42L42_HSDET_COMP2_LVL_MASK,
1158 (CS42L42_HSDET_COMP1_LVL_DEFAULT << CS42L42_HSDET_COMP1_LVL_SHIFT) |
1159 (CS42L42_HSDET_COMP2_LVL_DEFAULT << CS42L42_HSDET_COMP2_LVL_SHIFT));
1160}
1161
1039static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42)
1040{
1041 unsigned int hs_det_status;
1042 unsigned int int_status;
1043
1162static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42)
1163{
1164 unsigned int hs_det_status;
1165 unsigned int int_status;
1166
1167 /* Read and save the hs detection result */
1168 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1169
1044 /* Mask the auto detect interrupt */
1045 regmap_update_bits(cs42l42->regmap,
1046 CS42L42_CODEC_INT_MASK,
1047 CS42L42_PDN_DONE_MASK |
1048 CS42L42_HSDET_AUTO_DONE_MASK,
1049 (1 << CS42L42_PDN_DONE_SHIFT) |
1050 (1 << CS42L42_HSDET_AUTO_DONE_SHIFT));
1051
1170 /* Mask the auto detect interrupt */
1171 regmap_update_bits(cs42l42->regmap,
1172 CS42L42_CODEC_INT_MASK,
1173 CS42L42_PDN_DONE_MASK |
1174 CS42L42_HSDET_AUTO_DONE_MASK,
1175 (1 << CS42L42_PDN_DONE_SHIFT) |
1176 (1 << CS42L42_HSDET_AUTO_DONE_SHIFT));
1177
1178
1179 cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >>
1180 CS42L42_HSDET_TYPE_SHIFT;
1181
1052 /* Set hs detect to automatic, disabled mode */
1053 regmap_update_bits(cs42l42->regmap,
1054 CS42L42_HSDET_CTL2,
1055 CS42L42_HSDET_CTRL_MASK |
1056 CS42L42_HSDET_SET_MASK |
1057 CS42L42_HSBIAS_REF_MASK |
1058 CS42L42_HSDET_AUTO_TIME_MASK,
1059 (2 << CS42L42_HSDET_CTRL_SHIFT) |
1060 (2 << CS42L42_HSDET_SET_SHIFT) |
1061 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1062 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1063
1182 /* Set hs detect to automatic, disabled mode */
1183 regmap_update_bits(cs42l42->regmap,
1184 CS42L42_HSDET_CTL2,
1185 CS42L42_HSDET_CTRL_MASK |
1186 CS42L42_HSDET_SET_MASK |
1187 CS42L42_HSBIAS_REF_MASK |
1188 CS42L42_HSDET_AUTO_TIME_MASK,
1189 (2 << CS42L42_HSDET_CTRL_SHIFT) |
1190 (2 << CS42L42_HSDET_SET_SHIFT) |
1191 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1192 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1193
1064 /* Read and save the hs detection result */
1065 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1194 /* Run Manual detection if auto detect has not found a headset.
1195 * We Re-Run with Manual Detection if the original detection was invalid or headphones,
1196 * to ensure that a headset mic is detected in all cases.
1197 */
1198 if (cs42l42->hs_type == CS42L42_PLUG_INVALID ||
1199 cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) {
1200 dev_dbg(cs42l42->dev, "Running Manual Detection Fallback\n");
1201 cs42l42_manual_hs_type_detect(cs42l42);
1202 }
1066
1203
1067 cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >>
1068 CS42L42_HSDET_TYPE_SHIFT;
1069
1070 /* Set up button detection */
1071 if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) ||
1072 (cs42l42->hs_type == CS42L42_PLUG_OMTP)) {
1073 /* Set auto HS bias settings to default */
1074 regmap_update_bits(cs42l42->regmap,
1075 CS42L42_HSBIAS_SC_AUTOCTL,
1076 CS42L42_HSBIAS_SENSE_EN_MASK |
1077 CS42L42_AUTO_HSBIAS_HIZ_MASK |

--- 279 unchanged lines hidden (view full) ---

1357 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2,
1358 &detect_status);
1359 } while ((detect_status & CS42L42_HS_TRUE_MASK) &&
1360 (++bias_level < CS42L42_NUM_BIASES));
1361
1362 switch (bias_level) {
1363 case 1: /* Function C button press */
1364 bias_level = SND_JACK_BTN_2;
1204 /* Set up button detection */
1205 if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) ||
1206 (cs42l42->hs_type == CS42L42_PLUG_OMTP)) {
1207 /* Set auto HS bias settings to default */
1208 regmap_update_bits(cs42l42->regmap,
1209 CS42L42_HSBIAS_SC_AUTOCTL,
1210 CS42L42_HSBIAS_SENSE_EN_MASK |
1211 CS42L42_AUTO_HSBIAS_HIZ_MASK |

--- 279 unchanged lines hidden (view full) ---

1491 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2,
1492 &detect_status);
1493 } while ((detect_status & CS42L42_HS_TRUE_MASK) &&
1494 (++bias_level < CS42L42_NUM_BIASES));
1495
1496 switch (bias_level) {
1497 case 1: /* Function C button press */
1498 bias_level = SND_JACK_BTN_2;
1365 dev_dbg(cs42l42->component->dev, "Function C button press\n");
1499 dev_dbg(cs42l42->dev, "Function C button press\n");
1366 break;
1367 case 2: /* Function B button press */
1368 bias_level = SND_JACK_BTN_1;
1500 break;
1501 case 2: /* Function B button press */
1502 bias_level = SND_JACK_BTN_1;
1369 dev_dbg(cs42l42->component->dev, "Function B button press\n");
1503 dev_dbg(cs42l42->dev, "Function B button press\n");
1370 break;
1371 case 3: /* Function D button press */
1372 bias_level = SND_JACK_BTN_3;
1504 break;
1505 case 3: /* Function D button press */
1506 bias_level = SND_JACK_BTN_3;
1373 dev_dbg(cs42l42->component->dev, "Function D button press\n");
1507 dev_dbg(cs42l42->dev, "Function D button press\n");
1374 break;
1375 case 4: /* Function A button press */
1376 bias_level = SND_JACK_BTN_0;
1508 break;
1509 case 4: /* Function A button press */
1510 bias_level = SND_JACK_BTN_0;
1377 dev_dbg(cs42l42->component->dev, "Function A button press\n");
1511 dev_dbg(cs42l42->dev, "Function A button press\n");
1378 break;
1379 default:
1380 bias_level = 0;
1381 break;
1382 }
1383
1384 /* Set button detect level sensitivity back to default */
1385 regmap_update_bits(cs42l42->regmap,

--- 57 unchanged lines hidden (view full) ---

1443 CS42L42_PLL_LOCK_VAL_MASK},
1444 {CS42L42_TSRS_PLUG_STATUS, CS42L42_TSRS_PLUG_INT_MASK,
1445 CS42L42_TSRS_PLUG_VAL_MASK}
1446};
1447
1448static irqreturn_t cs42l42_irq_thread(int irq, void *data)
1449{
1450 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
1512 break;
1513 default:
1514 bias_level = 0;
1515 break;
1516 }
1517
1518 /* Set button detect level sensitivity back to default */
1519 regmap_update_bits(cs42l42->regmap,

--- 57 unchanged lines hidden (view full) ---

1577 CS42L42_PLL_LOCK_VAL_MASK},
1578 {CS42L42_TSRS_PLUG_STATUS, CS42L42_TSRS_PLUG_INT_MASK,
1579 CS42L42_TSRS_PLUG_VAL_MASK}
1580};
1581
1582static irqreturn_t cs42l42_irq_thread(int irq, void *data)
1583{
1584 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
1451 struct snd_soc_component *component = cs42l42->component;
1452 unsigned int stickies[12];
1453 unsigned int masks[12];
1454 unsigned int current_plug_status;
1455 unsigned int current_button_status;
1456 unsigned int i;
1457 int report = 0;
1458
1459

--- 17 unchanged lines hidden (view full) ---

1477 (CS42L42_M_DETECT_TF_MASK |
1478 CS42L42_M_DETECT_FT_MASK |
1479 CS42L42_M_HSBIAS_HIZ_MASK);
1480
1481 /* Check auto-detect status */
1482 if ((~masks[5]) & irq_params_table[5].mask) {
1483 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
1484 cs42l42_process_hs_type_detect(cs42l42);
1585 unsigned int stickies[12];
1586 unsigned int masks[12];
1587 unsigned int current_plug_status;
1588 unsigned int current_button_status;
1589 unsigned int i;
1590 int report = 0;
1591
1592

--- 17 unchanged lines hidden (view full) ---

1610 (CS42L42_M_DETECT_TF_MASK |
1611 CS42L42_M_DETECT_FT_MASK |
1612 CS42L42_M_HSBIAS_HIZ_MASK);
1613
1614 /* Check auto-detect status */
1615 if ((~masks[5]) & irq_params_table[5].mask) {
1616 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
1617 cs42l42_process_hs_type_detect(cs42l42);
1485 switch(cs42l42->hs_type){
1618 switch (cs42l42->hs_type) {
1486 case CS42L42_PLUG_CTIA:
1487 case CS42L42_PLUG_OMTP:
1488 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET,
1489 SND_JACK_HEADSET);
1490 break;
1491 case CS42L42_PLUG_HEADPHONE:
1492 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE,
1493 SND_JACK_HEADPHONE);
1494 break;
1495 default:
1496 break;
1497 }
1619 case CS42L42_PLUG_CTIA:
1620 case CS42L42_PLUG_OMTP:
1621 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET,
1622 SND_JACK_HEADSET);
1623 break;
1624 case CS42L42_PLUG_HEADPHONE:
1625 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE,
1626 SND_JACK_HEADPHONE);
1627 break;
1628 default:
1629 break;
1630 }
1498 dev_dbg(component->dev, "Auto detect done (%d)\n", cs42l42->hs_type);
1631 dev_dbg(cs42l42->dev, "Auto detect done (%d)\n", cs42l42->hs_type);
1499 }
1500 }
1501
1502 /* Check tip sense status */
1503 if ((~masks[11]) & irq_params_table[11].mask) {
1504 switch (current_plug_status) {
1505 case CS42L42_TS_PLUG:
1506 if (cs42l42->plug_state != CS42L42_TS_PLUG) {
1507 cs42l42->plug_state = CS42L42_TS_PLUG;
1508 cs42l42_init_hs_type_detect(cs42l42);
1509 }
1510 break;
1511
1512 case CS42L42_TS_UNPLUG:
1513 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
1514 cs42l42->plug_state = CS42L42_TS_UNPLUG;
1515 cs42l42_cancel_hs_type_detect(cs42l42);
1516
1632 }
1633 }
1634
1635 /* Check tip sense status */
1636 if ((~masks[11]) & irq_params_table[11].mask) {
1637 switch (current_plug_status) {
1638 case CS42L42_TS_PLUG:
1639 if (cs42l42->plug_state != CS42L42_TS_PLUG) {
1640 cs42l42->plug_state = CS42L42_TS_PLUG;
1641 cs42l42_init_hs_type_detect(cs42l42);
1642 }
1643 break;
1644
1645 case CS42L42_TS_UNPLUG:
1646 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
1647 cs42l42->plug_state = CS42L42_TS_UNPLUG;
1648 cs42l42_cancel_hs_type_detect(cs42l42);
1649
1517 switch(cs42l42->hs_type){
1650 switch (cs42l42->hs_type) {
1518 case CS42L42_PLUG_CTIA:
1519 case CS42L42_PLUG_OMTP:
1520 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET);
1521 break;
1522 case CS42L42_PLUG_HEADPHONE:
1523 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE);
1524 break;
1525 default:
1526 break;
1527 }
1528 snd_soc_jack_report(cs42l42->jack, 0,
1529 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1530 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1531
1651 case CS42L42_PLUG_CTIA:
1652 case CS42L42_PLUG_OMTP:
1653 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET);
1654 break;
1655 case CS42L42_PLUG_HEADPHONE:
1656 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE);
1657 break;
1658 default:
1659 break;
1660 }
1661 snd_soc_jack_report(cs42l42->jack, 0,
1662 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1663 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1664
1532 dev_dbg(component->dev, "Unplug event\n");
1665 dev_dbg(cs42l42->dev, "Unplug event\n");
1533 }
1534 break;
1535
1536 default:
1537 if (cs42l42->plug_state != CS42L42_TS_TRANS)
1538 cs42l42->plug_state = CS42L42_TS_TRANS;
1539 }
1540 }
1541
1542 /* Check button detect status */
1543 if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) {
1544 if (!(current_button_status &
1545 CS42L42_M_HSBIAS_HIZ_MASK)) {
1546
1547 if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
1666 }
1667 break;
1668
1669 default:
1670 if (cs42l42->plug_state != CS42L42_TS_TRANS)
1671 cs42l42->plug_state = CS42L42_TS_TRANS;
1672 }
1673 }
1674
1675 /* Check button detect status */
1676 if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) {
1677 if (!(current_button_status &
1678 CS42L42_M_HSBIAS_HIZ_MASK)) {
1679
1680 if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
1548 dev_dbg(component->dev, "Button released\n");
1681 dev_dbg(cs42l42->dev, "Button released\n");
1549 report = 0;
1550 } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
1551 report = cs42l42_handle_button_press(cs42l42);
1552
1553 }
1554 snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1555 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1556 }

--- 96 unchanged lines hidden (view full) ---

1653
1654 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
1655 CS42L42_RS_PLUG_MASK |
1656 CS42L42_RS_UNPLUG_MASK |
1657 CS42L42_TS_PLUG_MASK |
1658 CS42L42_TS_UNPLUG_MASK,
1659 (1 << CS42L42_RS_PLUG_SHIFT) |
1660 (1 << CS42L42_RS_UNPLUG_SHIFT) |
1682 report = 0;
1683 } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
1684 report = cs42l42_handle_button_press(cs42l42);
1685
1686 }
1687 snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1688 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1689 }

--- 96 unchanged lines hidden (view full) ---

1786
1787 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
1788 CS42L42_RS_PLUG_MASK |
1789 CS42L42_RS_UNPLUG_MASK |
1790 CS42L42_TS_PLUG_MASK |
1791 CS42L42_TS_UNPLUG_MASK,
1792 (1 << CS42L42_RS_PLUG_SHIFT) |
1793 (1 << CS42L42_RS_UNPLUG_SHIFT) |
1661 (1 << CS42L42_TS_PLUG_SHIFT) |
1662 (1 << CS42L42_TS_UNPLUG_SHIFT));
1794 (0 << CS42L42_TS_PLUG_SHIFT) |
1795 (0 << CS42L42_TS_UNPLUG_SHIFT));
1663}
1664
1665static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42)
1666{
1667 unsigned int reg;
1668
1669 cs42l42->hs_type = CS42L42_PLUG_INVALID;
1670

--- 223 unchanged lines hidden (view full) ---

1894 int ret, i, devid;
1895 unsigned int reg;
1896
1897 cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private),
1898 GFP_KERNEL);
1899 if (!cs42l42)
1900 return -ENOMEM;
1901
1796}
1797
1798static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42)
1799{
1800 unsigned int reg;
1801
1802 cs42l42->hs_type = CS42L42_PLUG_INVALID;
1803

--- 223 unchanged lines hidden (view full) ---

2027 int ret, i, devid;
2028 unsigned int reg;
2029
2030 cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private),
2031 GFP_KERNEL);
2032 if (!cs42l42)
2033 return -ENOMEM;
2034
2035 cs42l42->dev = &i2c_client->dev;
1902 i2c_set_clientdata(i2c_client, cs42l42);
1903
1904 cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap);
1905 if (IS_ERR(cs42l42->regmap)) {
1906 ret = PTR_ERR(cs42l42->regmap);
1907 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1908 return ret;
1909 }

--- 27 unchanged lines hidden (view full) ---

1937 }
1938
1939 if (cs42l42->reset_gpio) {
1940 dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
1941 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
1942 }
1943 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2);
1944
2036 i2c_set_clientdata(i2c_client, cs42l42);
2037
2038 cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap);
2039 if (IS_ERR(cs42l42->regmap)) {
2040 ret = PTR_ERR(cs42l42->regmap);
2041 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
2042 return ret;
2043 }

--- 27 unchanged lines hidden (view full) ---

2071 }
2072
2073 if (cs42l42->reset_gpio) {
2074 dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
2075 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
2076 }
2077 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2);
2078
1945 /* Request IRQ */
1946 ret = devm_request_threaded_irq(&i2c_client->dev,
1947 i2c_client->irq,
1948 NULL, cs42l42_irq_thread,
1949 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
1950 "cs42l42", cs42l42);
2079 /* Request IRQ if one was specified */
2080 if (i2c_client->irq) {
2081 ret = devm_request_threaded_irq(&i2c_client->dev,
2082 i2c_client->irq,
2083 NULL, cs42l42_irq_thread,
2084 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
2085 "cs42l42", cs42l42);
2086 if (ret == -EPROBE_DEFER) {
2087 goto err_disable;
2088 } else if (ret != 0) {
2089 dev_err(&i2c_client->dev,
2090 "Failed to request IRQ: %d\n", ret);
2091 goto err_disable;
2092 }
2093 }
1951
2094
1952 if (ret != 0)
1953 dev_err(&i2c_client->dev,
1954 "Failed to request IRQ: %d\n", ret);
1955
1956 /* initialize codec */
1957 devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB);
1958 if (devid < 0) {
1959 ret = devid;
1960 dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
1961 goto err_disable;
1962 }
1963

--- 53 unchanged lines hidden (view full) ---

2017 cs42l42->supplies);
2018 return ret;
2019}
2020
2021static int cs42l42_i2c_remove(struct i2c_client *i2c_client)
2022{
2023 struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client);
2024
2095 /* initialize codec */
2096 devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB);
2097 if (devid < 0) {
2098 ret = devid;
2099 dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
2100 goto err_disable;
2101 }
2102

--- 53 unchanged lines hidden (view full) ---

2156 cs42l42->supplies);
2157 return ret;
2158}
2159
2160static int cs42l42_i2c_remove(struct i2c_client *i2c_client)
2161{
2162 struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client);
2163
2025 devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42);
2026 pm_runtime_suspend(&i2c_client->dev);
2027 pm_runtime_disable(&i2c_client->dev);
2164 if (i2c_client->irq)
2165 devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42);
2028
2166
2029 return 0;
2030}
2031
2032#ifdef CONFIG_PM
2033static int cs42l42_runtime_suspend(struct device *dev)
2034{
2035 struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
2036
2037 regcache_cache_only(cs42l42->regmap, true);
2038 regcache_mark_dirty(cs42l42->regmap);
2039
2040 /* Hold down reset */
2041 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2167 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2168 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies);
2042
2169
2043 /* remove power */
2044 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies),
2045 cs42l42->supplies);
2046
2047 return 0;
2048}
2049
2170 return 0;
2171}
2172
2050static int cs42l42_runtime_resume(struct device *dev)
2051{
2052 struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
2053 int ret;
2054
2055 /* Enable power */
2056 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies),
2057 cs42l42->supplies);
2058 if (ret != 0) {
2059 dev_err(dev, "Failed to enable supplies: %d\n",
2060 ret);
2061 return ret;
2062 }
2063
2064 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
2065 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2);
2066
2067 regcache_cache_only(cs42l42->regmap, false);
2068 regcache_sync(cs42l42->regmap);
2069
2070 return 0;
2071}
2072#endif
2073
2074static const struct dev_pm_ops cs42l42_runtime_pm = {
2075 SET_RUNTIME_PM_OPS(cs42l42_runtime_suspend, cs42l42_runtime_resume,
2076 NULL)
2077};
2078
2079#ifdef CONFIG_OF
2080static const struct of_device_id cs42l42_of_match[] = {
2081 { .compatible = "cirrus,cs42l42", },
2082 {}
2083};
2084MODULE_DEVICE_TABLE(of, cs42l42_of_match);
2085#endif
2086

--- 10 unchanged lines hidden (view full) ---

2097 {}
2098};
2099
2100MODULE_DEVICE_TABLE(i2c, cs42l42_id);
2101
2102static struct i2c_driver cs42l42_i2c_driver = {
2103 .driver = {
2104 .name = "cs42l42",
2173#ifdef CONFIG_OF
2174static const struct of_device_id cs42l42_of_match[] = {
2175 { .compatible = "cirrus,cs42l42", },
2176 {}
2177};
2178MODULE_DEVICE_TABLE(of, cs42l42_of_match);
2179#endif
2180

--- 10 unchanged lines hidden (view full) ---

2191 {}
2192};
2193
2194MODULE_DEVICE_TABLE(i2c, cs42l42_id);
2195
2196static struct i2c_driver cs42l42_i2c_driver = {
2197 .driver = {
2198 .name = "cs42l42",
2105 .pm = &cs42l42_runtime_pm,
2106 .of_match_table = of_match_ptr(cs42l42_of_match),
2107 .acpi_match_table = ACPI_PTR(cs42l42_acpi_match),
2108 },
2109 .id_table = cs42l42_id,
2110 .probe = cs42l42_i2c_probe,
2111 .remove = cs42l42_i2c_remove,
2112};
2113
2114module_i2c_driver(cs42l42_i2c_driver);
2115
2116MODULE_DESCRIPTION("ASoC CS42L42 driver");
2117MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
2118MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
2119MODULE_AUTHOR("Michael White, Cirrus Logic Inc, <michael.white@cirrus.com>");
2120MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
2121MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
2122MODULE_AUTHOR("Vitaly Rodionov <vitalyr@opensource.cirrus.com>");
2123MODULE_LICENSE("GPL");
2199 .of_match_table = of_match_ptr(cs42l42_of_match),
2200 .acpi_match_table = ACPI_PTR(cs42l42_acpi_match),
2201 },
2202 .id_table = cs42l42_id,
2203 .probe = cs42l42_i2c_probe,
2204 .remove = cs42l42_i2c_remove,
2205};
2206
2207module_i2c_driver(cs42l42_i2c_driver);
2208
2209MODULE_DESCRIPTION("ASoC CS42L42 driver");
2210MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
2211MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
2212MODULE_AUTHOR("Michael White, Cirrus Logic Inc, <michael.white@cirrus.com>");
2213MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
2214MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
2215MODULE_AUTHOR("Vitaly Rodionov <vitalyr@opensource.cirrus.com>");
2216MODULE_LICENSE("GPL");