diff options
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r-- | sound/soc/codecs/rt5645.c | 204 |
1 files changed, 185 insertions, 19 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index d16331e0b64d..27141e2df878 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -554,6 +554,53 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
554 | return 0; | 554 | return 0; |
555 | } | 555 | } |
556 | 556 | ||
557 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | ||
558 | struct snd_soc_dapm_widget *sink) | ||
559 | { | ||
560 | unsigned int reg, shift, val; | ||
561 | |||
562 | switch (source->shift) { | ||
563 | case 0: | ||
564 | reg = RT5645_ASRC_3; | ||
565 | shift = 0; | ||
566 | break; | ||
567 | case 1: | ||
568 | reg = RT5645_ASRC_3; | ||
569 | shift = 4; | ||
570 | break; | ||
571 | case 3: | ||
572 | reg = RT5645_ASRC_2; | ||
573 | shift = 0; | ||
574 | break; | ||
575 | case 8: | ||
576 | reg = RT5645_ASRC_2; | ||
577 | shift = 4; | ||
578 | break; | ||
579 | case 9: | ||
580 | reg = RT5645_ASRC_2; | ||
581 | shift = 8; | ||
582 | break; | ||
583 | case 10: | ||
584 | reg = RT5645_ASRC_2; | ||
585 | shift = 12; | ||
586 | break; | ||
587 | default: | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; | ||
592 | switch (val) { | ||
593 | case 1: | ||
594 | case 2: | ||
595 | case 3: | ||
596 | case 4: | ||
597 | return 1; | ||
598 | default: | ||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | } | ||
603 | |||
557 | /* Digital Mixer */ | 604 | /* Digital Mixer */ |
558 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { | 605 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { |
559 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | 606 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, |
@@ -1246,6 +1293,30 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1246 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, | 1293 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, |
1247 | RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), | 1294 | RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), |
1248 | 1295 | ||
1296 | /* ASRC */ | ||
1297 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5645_ASRC_1, | ||
1298 | 11, 0, NULL, 0), | ||
1299 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5645_ASRC_1, | ||
1300 | 12, 0, NULL, 0), | ||
1301 | SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5645_ASRC_1, | ||
1302 | 10, 0, NULL, 0), | ||
1303 | SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1304 | 9, 0, NULL, 0), | ||
1305 | SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1306 | 8, 0, NULL, 0), | ||
1307 | SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5645_ASRC_1, | ||
1308 | 7, 0, NULL, 0), | ||
1309 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1310 | 5, 0, NULL, 0), | ||
1311 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1312 | 4, 0, NULL, 0), | ||
1313 | SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5645_ASRC_1, | ||
1314 | 3, 0, NULL, 0), | ||
1315 | SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5645_ASRC_1, | ||
1316 | 1, 0, NULL, 0), | ||
1317 | SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5645_ASRC_1, | ||
1318 | 0, 0, NULL, 0), | ||
1319 | |||
1249 | /* Input Side */ | 1320 | /* Input Side */ |
1250 | /* micbias */ | 1321 | /* micbias */ |
1251 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, | 1322 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, |
@@ -1504,6 +1575,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1504 | }; | 1575 | }; |
1505 | 1576 | ||
1506 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | 1577 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { |
1578 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | ||
1579 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | ||
1580 | { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, | ||
1581 | { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, | ||
1582 | { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc }, | ||
1583 | { "dac mono right filter", NULL, "DAC MONO R ASRC", is_using_asrc }, | ||
1584 | { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc }, | ||
1585 | |||
1586 | { "I2S1", NULL, "I2S1 ASRC" }, | ||
1587 | { "I2S2", NULL, "I2S2 ASRC" }, | ||
1588 | |||
1507 | { "IN1P", NULL, "LDO2" }, | 1589 | { "IN1P", NULL, "LDO2" }, |
1508 | { "IN2P", NULL, "LDO2" }, | 1590 | { "IN2P", NULL, "LDO2" }, |
1509 | 1591 | ||
@@ -1550,12 +1632,15 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1550 | 1632 | ||
1551 | { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, | 1633 | { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, |
1552 | { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, | 1634 | { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, |
1635 | { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC" }, | ||
1553 | 1636 | ||
1554 | { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, | 1637 | { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, |
1555 | { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, | 1638 | { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, |
1639 | { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC" }, | ||
1556 | 1640 | ||
1557 | { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, | 1641 | { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, |
1558 | { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, | 1642 | { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, |
1643 | { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC" }, | ||
1559 | 1644 | ||
1560 | { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, | 1645 | { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, |
1561 | { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, | 1646 | { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, |
@@ -2029,8 +2114,11 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | |||
2029 | struct snd_soc_codec *codec = dai->codec; | 2114 | struct snd_soc_codec *codec = dai->codec; |
2030 | unsigned int val = 0; | 2115 | unsigned int val = 0; |
2031 | 2116 | ||
2032 | if (rx_mask || tx_mask) | 2117 | if (rx_mask || tx_mask) { |
2033 | val |= (1 << 14); | 2118 | val |= (1 << 14); |
2119 | snd_soc_update_bits(codec, RT5645_BASS_BACK, | ||
2120 | RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB); | ||
2121 | } | ||
2034 | 2122 | ||
2035 | switch (slots) { | 2123 | switch (slots) { |
2036 | case 4: | 2124 | case 4: |
@@ -2071,8 +2159,8 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, | |||
2071 | enum snd_soc_bias_level level) | 2159 | enum snd_soc_bias_level level) |
2072 | { | 2160 | { |
2073 | switch (level) { | 2161 | switch (level) { |
2074 | case SND_SOC_BIAS_STANDBY: | 2162 | case SND_SOC_BIAS_PREPARE: |
2075 | if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { | 2163 | if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { |
2076 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | 2164 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, |
2077 | RT5645_PWR_VREF1 | RT5645_PWR_MB | | 2165 | RT5645_PWR_VREF1 | RT5645_PWR_MB | |
2078 | RT5645_PWR_BG | RT5645_PWR_VREF2, | 2166 | RT5645_PWR_BG | RT5645_PWR_VREF2, |
@@ -2087,15 +2175,24 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, | |||
2087 | } | 2175 | } |
2088 | break; | 2176 | break; |
2089 | 2177 | ||
2178 | case SND_SOC_BIAS_STANDBY: | ||
2179 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
2180 | RT5645_PWR_VREF1 | RT5645_PWR_MB | | ||
2181 | RT5645_PWR_BG | RT5645_PWR_VREF2, | ||
2182 | RT5645_PWR_VREF1 | RT5645_PWR_MB | | ||
2183 | RT5645_PWR_BG | RT5645_PWR_VREF2); | ||
2184 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
2185 | RT5645_PWR_FV1 | RT5645_PWR_FV2, | ||
2186 | RT5645_PWR_FV1 | RT5645_PWR_FV2); | ||
2187 | break; | ||
2188 | |||
2090 | case SND_SOC_BIAS_OFF: | 2189 | case SND_SOC_BIAS_OFF: |
2091 | snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); | 2190 | snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); |
2092 | snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); | 2191 | snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); |
2093 | snd_soc_write(codec, RT5645_PWR_DIG1, 0x0000); | 2192 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, |
2094 | snd_soc_write(codec, RT5645_PWR_DIG2, 0x0000); | 2193 | RT5645_PWR_VREF1 | RT5645_PWR_MB | |
2095 | snd_soc_write(codec, RT5645_PWR_VOL, 0x0000); | 2194 | RT5645_PWR_BG | RT5645_PWR_VREF2 | |
2096 | snd_soc_write(codec, RT5645_PWR_MIXER, 0x0000); | 2195 | RT5645_PWR_FV1 | RT5645_PWR_FV2, 0x0); |
2097 | snd_soc_write(codec, RT5645_PWR_ANLG1, 0x0000); | ||
2098 | snd_soc_write(codec, RT5645_PWR_ANLG2, 0x0000); | ||
2099 | break; | 2196 | break; |
2100 | 2197 | ||
2101 | default: | 2198 | default: |
@@ -2106,13 +2203,16 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, | |||
2106 | return 0; | 2203 | return 0; |
2107 | } | 2204 | } |
2108 | 2205 | ||
2109 | static int rt5645_jack_detect(struct snd_soc_codec *codec, | 2206 | static int rt5645_jack_detect(struct snd_soc_codec *codec) |
2110 | struct snd_soc_jack *jack) | ||
2111 | { | 2207 | { |
2112 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 2208 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
2113 | int gpio_state, jack_type = 0; | 2209 | int gpio_state, jack_type = 0; |
2114 | unsigned int val; | 2210 | unsigned int val; |
2115 | 2211 | ||
2212 | if (!gpio_is_valid(rt5645->pdata.hp_det_gpio)) { | ||
2213 | dev_err(codec->dev, "invalid gpio\n"); | ||
2214 | return -EINVAL; | ||
2215 | } | ||
2116 | gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); | 2216 | gpio_state = gpio_get_value(rt5645->pdata.hp_det_gpio); |
2117 | 2217 | ||
2118 | dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, | 2218 | dev_dbg(codec->dev, "gpio = %d(%d)\n", rt5645->pdata.hp_det_gpio, |
@@ -2145,34 +2245,44 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, | |||
2145 | 2245 | ||
2146 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); | 2246 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); |
2147 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); | 2247 | snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); |
2148 | snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); | 2248 | if (rt5645->pdata.jd_mode == 0) |
2249 | snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); | ||
2149 | snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); | 2250 | snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); |
2150 | snd_soc_dapm_sync(&codec->dapm); | 2251 | snd_soc_dapm_sync(&codec->dapm); |
2151 | } | 2252 | } |
2152 | 2253 | ||
2153 | snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET); | 2254 | snd_soc_jack_report(rt5645->hp_jack, jack_type, SND_JACK_HEADPHONE); |
2154 | 2255 | snd_soc_jack_report(rt5645->mic_jack, jack_type, SND_JACK_MICROPHONE); | |
2155 | return 0; | 2256 | return 0; |
2156 | } | 2257 | } |
2157 | 2258 | ||
2158 | int rt5645_set_jack_detect(struct snd_soc_codec *codec, | 2259 | int rt5645_set_jack_detect(struct snd_soc_codec *codec, |
2159 | struct snd_soc_jack *jack) | 2260 | struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack) |
2160 | { | 2261 | { |
2161 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 2262 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
2162 | 2263 | ||
2163 | rt5645->jack = jack; | 2264 | rt5645->hp_jack = hp_jack; |
2164 | 2265 | rt5645->mic_jack = mic_jack; | |
2165 | rt5645_jack_detect(codec, rt5645->jack); | 2266 | rt5645_jack_detect(codec); |
2166 | 2267 | ||
2167 | return 0; | 2268 | return 0; |
2168 | } | 2269 | } |
2169 | EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); | 2270 | EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); |
2170 | 2271 | ||
2272 | static void rt5645_jack_detect_work(struct work_struct *work) | ||
2273 | { | ||
2274 | struct rt5645_priv *rt5645 = | ||
2275 | container_of(work, struct rt5645_priv, jack_detect_work.work); | ||
2276 | |||
2277 | rt5645_jack_detect(rt5645->codec); | ||
2278 | } | ||
2279 | |||
2171 | static irqreturn_t rt5645_irq(int irq, void *data) | 2280 | static irqreturn_t rt5645_irq(int irq, void *data) |
2172 | { | 2281 | { |
2173 | struct rt5645_priv *rt5645 = data; | 2282 | struct rt5645_priv *rt5645 = data; |
2174 | 2283 | ||
2175 | rt5645_jack_detect(rt5645->codec, rt5645->jack); | 2284 | queue_delayed_work(system_power_efficient_wq, |
2285 | &rt5645->jack_detect_work, msecs_to_jiffies(250)); | ||
2176 | 2286 | ||
2177 | return IRQ_HANDLED; | 2287 | return IRQ_HANDLED; |
2178 | } | 2288 | } |
@@ -2187,6 +2297,13 @@ static int rt5645_probe(struct snd_soc_codec *codec) | |||
2187 | 2297 | ||
2188 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); | 2298 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); |
2189 | 2299 | ||
2300 | /* for JD function */ | ||
2301 | if (rt5645->pdata.en_jd_func) { | ||
2302 | snd_soc_dapm_force_enable_pin(&codec->dapm, "JD Power"); | ||
2303 | snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); | ||
2304 | snd_soc_dapm_sync(&codec->dapm); | ||
2305 | } | ||
2306 | |||
2190 | return 0; | 2307 | return 0; |
2191 | } | 2308 | } |
2192 | 2309 | ||
@@ -2420,6 +2537,51 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2420 | 2537 | ||
2421 | } | 2538 | } |
2422 | 2539 | ||
2540 | if (rt5645->pdata.en_jd_func) { | ||
2541 | regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3, | ||
2542 | RT5645_IRQ_CLK_GATE_CTRL | RT5645_MICINDET_MANU, | ||
2543 | RT5645_IRQ_CLK_GATE_CTRL | RT5645_MICINDET_MANU); | ||
2544 | regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, | ||
2545 | RT5645_CBJ_BST1_EN, RT5645_CBJ_BST1_EN); | ||
2546 | regmap_update_bits(rt5645->regmap, RT5645_JD_CTRL3, | ||
2547 | RT5645_JD_CBJ_EN | RT5645_JD_CBJ_POL, | ||
2548 | RT5645_JD_CBJ_EN | RT5645_JD_CBJ_POL); | ||
2549 | regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, | ||
2550 | RT5645_IRQ_CLK_INT, RT5645_IRQ_CLK_INT); | ||
2551 | } | ||
2552 | |||
2553 | if (rt5645->pdata.jd_mode) { | ||
2554 | regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, | ||
2555 | RT5645_IRQ_JD_1_1_EN, RT5645_IRQ_JD_1_1_EN); | ||
2556 | regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3, | ||
2557 | RT5645_JD_PSV_MODE, RT5645_JD_PSV_MODE); | ||
2558 | regmap_update_bits(rt5645->regmap, RT5645_HPO_MIXER, | ||
2559 | RT5645_IRQ_PSV_MODE, RT5645_IRQ_PSV_MODE); | ||
2560 | regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, | ||
2561 | RT5645_MIC2_OVCD_EN, RT5645_MIC2_OVCD_EN); | ||
2562 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2563 | RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ); | ||
2564 | switch (rt5645->pdata.jd_mode) { | ||
2565 | case 1: | ||
2566 | regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, | ||
2567 | RT5645_JD1_MODE_MASK, | ||
2568 | RT5645_JD1_MODE_0); | ||
2569 | break; | ||
2570 | case 2: | ||
2571 | regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, | ||
2572 | RT5645_JD1_MODE_MASK, | ||
2573 | RT5645_JD1_MODE_1); | ||
2574 | break; | ||
2575 | case 3: | ||
2576 | regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, | ||
2577 | RT5645_JD1_MODE_MASK, | ||
2578 | RT5645_JD1_MODE_2); | ||
2579 | break; | ||
2580 | default: | ||
2581 | break; | ||
2582 | } | ||
2583 | } | ||
2584 | |||
2423 | if (rt5645->i2c->irq) { | 2585 | if (rt5645->i2c->irq) { |
2424 | ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, | 2586 | ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, |
2425 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | 2587 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
@@ -2438,6 +2600,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2438 | dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); | 2600 | dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); |
2439 | } | 2601 | } |
2440 | 2602 | ||
2603 | INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); | ||
2604 | |||
2441 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, | 2605 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, |
2442 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); | 2606 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); |
2443 | } | 2607 | } |
@@ -2449,6 +2613,8 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) | |||
2449 | if (i2c->irq) | 2613 | if (i2c->irq) |
2450 | free_irq(i2c->irq, rt5645); | 2614 | free_irq(i2c->irq, rt5645); |
2451 | 2615 | ||
2616 | cancel_delayed_work_sync(&rt5645->jack_detect_work); | ||
2617 | |||
2452 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) | 2618 | if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) |
2453 | gpio_free(rt5645->pdata.hp_det_gpio); | 2619 | gpio_free(rt5645->pdata.hp_det_gpio); |
2454 | 2620 | ||