rt5645.c (a3ae255e3729c1bb4507412ea29be804f703d44c) | rt5645.c (79080a8b42a08fb68a1ea2e036e54a4749edbd43) |
---|---|
1/* 2 * rt5645.c -- RT5645 ALSA SoC audio codec driver 3 * 4 * Copyright 2013 Realtek Semiconductor Corp. 5 * Author: Bard Liao <bardliao@realtek.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 525 unchanged lines hidden (view full) --- 534 * @w: DAPM widget. 535 * @kcontrol: The kcontrol of this widget. 536 * @event: Event id. 537 * 538 */ 539static int set_dmic_clk(struct snd_soc_dapm_widget *w, 540 struct snd_kcontrol *kcontrol, int event) 541{ | 1/* 2 * rt5645.c -- RT5645 ALSA SoC audio codec driver 3 * 4 * Copyright 2013 Realtek Semiconductor Corp. 5 * Author: Bard Liao <bardliao@realtek.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 525 unchanged lines hidden (view full) --- 534 * @w: DAPM widget. 535 * @kcontrol: The kcontrol of this widget. 536 * @event: Event id. 537 * 538 */ 539static int set_dmic_clk(struct snd_soc_dapm_widget *w, 540 struct snd_kcontrol *kcontrol, int event) 541{ |
542 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 542 struct snd_soc_codec *codec = w->codec; |
543 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 544 int idx = -EINVAL; 545 546 idx = rl6231_calc_dmic_clk(rt5645->sysclk); 547 548 if (idx < 0) 549 dev_err(codec->dev, "Failed to set DMIC clock\n"); 550 else 551 snd_soc_update_bits(codec, RT5645_DMIC_CTRL1, 552 RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT); 553 return idx; 554} 555 556static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, 557 struct snd_soc_dapm_widget *sink) 558{ | 543 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 544 int idx = -EINVAL; 545 546 idx = rl6231_calc_dmic_clk(rt5645->sysclk); 547 548 if (idx < 0) 549 dev_err(codec->dev, "Failed to set DMIC clock\n"); 550 else 551 snd_soc_update_bits(codec, RT5645_DMIC_CTRL1, 552 RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT); 553 return idx; 554} 555 556static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, 557 struct snd_soc_dapm_widget *sink) 558{ |
559 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | |
560 unsigned int val; 561 | 559 unsigned int val; 560 |
562 val = snd_soc_read(codec, RT5645_GLB_CLK); | 561 val = snd_soc_read(source->codec, RT5645_GLB_CLK); |
563 val &= RT5645_SCLK_SRC_MASK; 564 if (val == RT5645_SCLK_SRC_PLL1) 565 return 1; 566 else 567 return 0; 568} 569 570static int is_using_asrc(struct snd_soc_dapm_widget *source, 571 struct snd_soc_dapm_widget *sink) 572{ | 562 val &= RT5645_SCLK_SRC_MASK; 563 if (val == RT5645_SCLK_SRC_PLL1) 564 return 1; 565 else 566 return 0; 567} 568 569static int is_using_asrc(struct snd_soc_dapm_widget *source, 570 struct snd_soc_dapm_widget *sink) 571{ |
573 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | |
574 unsigned int reg, shift, val; 575 576 switch (source->shift) { 577 case 0: 578 reg = RT5645_ASRC_3; 579 shift = 0; 580 break; 581 case 1: --- 15 unchanged lines hidden (view full) --- 597 case 10: 598 reg = RT5645_ASRC_2; 599 shift = 12; 600 break; 601 default: 602 return 0; 603 } 604 | 572 unsigned int reg, shift, val; 573 574 switch (source->shift) { 575 case 0: 576 reg = RT5645_ASRC_3; 577 shift = 0; 578 break; 579 case 1: --- 15 unchanged lines hidden (view full) --- 595 case 10: 596 reg = RT5645_ASRC_2; 597 shift = 12; 598 break; 599 default: 600 return 0; 601 } 602 |
605 val = (snd_soc_read(codec, reg) >> shift) & 0xf; | 603 val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; |
606 switch (val) { 607 case 1: 608 case 2: 609 case 3: 610 case 4: 611 return 1; 612 default: 613 return 0; 614 } 615 616} 617 | 604 switch (val) { 605 case 1: 606 case 2: 607 case 3: 608 case 4: 609 return 1; 610 default: 611 return 0; 612 } 613 614} 615 |
616/** 617 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters 618 * @codec: SoC audio codec device. 619 * @filter_mask: mask of filters. 620 * @clk_src: clock source 621 * 622 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5645 can 623 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to 624 * support special i2s clock format such as Intel's 100fs(100 * sampling rate). 625 * ASRC function will track i2s clock and generate a corresponding system clock 626 * for codec. This function provides an API to select the clock source for a 627 * set of filters specified by the mask. And the codec driver will turn on ASRC 628 * for these filters if ASRC is selected as their clock source. 629 */ 630int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, 631 unsigned int filter_mask, unsigned int clk_src) 632{ 633 unsigned int asrc2_mask = 0; 634 unsigned int asrc2_value = 0; 635 unsigned int asrc3_mask = 0; 636 unsigned int asrc3_value = 0; 637 638 switch (clk_src) { 639 case RT5645_CLK_SEL_SYS: 640 case RT5645_CLK_SEL_I2S1_ASRC: 641 case RT5645_CLK_SEL_I2S2_ASRC: 642 case RT5645_CLK_SEL_SYS2: 643 break; 644 645 default: 646 return -EINVAL; 647 } 648 649 if (filter_mask & RT5645_DA_STEREO_FILTER) { 650 asrc2_mask |= RT5645_DA_STO_CLK_SEL_MASK; 651 asrc2_value = (asrc2_value & ~RT5645_DA_STO_CLK_SEL_MASK) 652 | (clk_src << RT5645_DA_STO_CLK_SEL_SFT); 653 } 654 655 if (filter_mask & RT5645_DA_MONO_L_FILTER) { 656 asrc2_mask |= RT5645_DA_MONOL_CLK_SEL_MASK; 657 asrc2_value = (asrc2_value & ~RT5645_DA_MONOL_CLK_SEL_MASK) 658 | (clk_src << RT5645_DA_MONOL_CLK_SEL_SFT); 659 } 660 661 if (filter_mask & RT5645_DA_MONO_R_FILTER) { 662 asrc2_mask |= RT5645_DA_MONOR_CLK_SEL_MASK; 663 asrc2_value = (asrc2_value & ~RT5645_DA_MONOR_CLK_SEL_MASK) 664 | (clk_src << RT5645_DA_MONOR_CLK_SEL_SFT); 665 } 666 667 if (filter_mask & RT5645_AD_STEREO_FILTER) { 668 asrc2_mask |= RT5645_AD_STO1_CLK_SEL_MASK; 669 asrc2_value = (asrc2_value & ~RT5645_AD_STO1_CLK_SEL_MASK) 670 | (clk_src << RT5645_AD_STO1_CLK_SEL_SFT); 671 } 672 673 if (filter_mask & RT5645_AD_MONO_L_FILTER) { 674 asrc3_mask |= RT5645_AD_MONOL_CLK_SEL_MASK; 675 asrc3_value = (asrc3_value & ~RT5645_AD_MONOL_CLK_SEL_MASK) 676 | (clk_src << RT5645_AD_MONOL_CLK_SEL_SFT); 677 } 678 679 if (filter_mask & RT5645_AD_MONO_R_FILTER) { 680 asrc3_mask |= RT5645_AD_MONOR_CLK_SEL_MASK; 681 asrc3_value = (asrc3_value & ~RT5645_AD_MONOR_CLK_SEL_MASK) 682 | (clk_src << RT5645_AD_MONOR_CLK_SEL_SFT); 683 } 684 685 if (asrc2_mask) 686 snd_soc_update_bits(codec, RT5645_ASRC_2, 687 asrc2_mask, asrc2_value); 688 689 if (asrc3_mask) 690 snd_soc_update_bits(codec, RT5645_ASRC_3, 691 asrc3_mask, asrc3_value); 692 693 return 0; 694} 695EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src); 696 |
|
618/* Digital Mixer */ 619static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { 620 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, 621 RT5645_M_ADC_L1_SFT, 1, 1), 622 SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER, 623 RT5645_M_ADC_L2_SFT, 1, 1), 624}; 625 --- 565 unchanged lines hidden (view full) --- 1191 RT5645_PWR_HA, 0); 1192 } 1193 } 1194} 1195 1196static int rt5645_hp_event(struct snd_soc_dapm_widget *w, 1197 struct snd_kcontrol *kcontrol, int event) 1198{ | 697/* Digital Mixer */ 698static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { 699 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, 700 RT5645_M_ADC_L1_SFT, 1, 1), 701 SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER, 702 RT5645_M_ADC_L2_SFT, 1, 1), 703}; 704 --- 565 unchanged lines hidden (view full) --- 1270 RT5645_PWR_HA, 0); 1271 } 1272 } 1273} 1274 1275static int rt5645_hp_event(struct snd_soc_dapm_widget *w, 1276 struct snd_kcontrol *kcontrol, int event) 1277{ |
1199 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 1278 struct snd_soc_codec *codec = w->codec; |
1200 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 1201 1202 switch (event) { 1203 case SND_SOC_DAPM_POST_PMU: 1204 hp_amp_power(codec, 1); 1205 /* headphone unmute sequence */ 1206 if (rt5645->codec_type == CODEC_TYPE_RT5650) { 1207 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); --- 53 unchanged lines hidden (view full) --- 1261 } 1262 1263 return 0; 1264} 1265 1266static int rt5645_spk_event(struct snd_soc_dapm_widget *w, 1267 struct snd_kcontrol *kcontrol, int event) 1268{ | 1279 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 1280 1281 switch (event) { 1282 case SND_SOC_DAPM_POST_PMU: 1283 hp_amp_power(codec, 1); 1284 /* headphone unmute sequence */ 1285 if (rt5645->codec_type == CODEC_TYPE_RT5650) { 1286 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); --- 53 unchanged lines hidden (view full) --- 1340 } 1341 1342 return 0; 1343} 1344 1345static int rt5645_spk_event(struct snd_soc_dapm_widget *w, 1346 struct snd_kcontrol *kcontrol, int event) 1347{ |
1269 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 1348 struct snd_soc_codec *codec = w->codec; |
1270 1271 switch (event) { 1272 case SND_SOC_DAPM_POST_PMU: 1273 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1274 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1275 RT5645_PWR_CLS_D_L, 1276 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1277 RT5645_PWR_CLS_D_L); --- 10 unchanged lines hidden (view full) --- 1288 } 1289 1290 return 0; 1291} 1292 1293static int rt5645_lout_event(struct snd_soc_dapm_widget *w, 1294 struct snd_kcontrol *kcontrol, int event) 1295{ | 1349 1350 switch (event) { 1351 case SND_SOC_DAPM_POST_PMU: 1352 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1353 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1354 RT5645_PWR_CLS_D_L, 1355 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1356 RT5645_PWR_CLS_D_L); --- 10 unchanged lines hidden (view full) --- 1367 } 1368 1369 return 0; 1370} 1371 1372static int rt5645_lout_event(struct snd_soc_dapm_widget *w, 1373 struct snd_kcontrol *kcontrol, int event) 1374{ |
1296 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 1375 struct snd_soc_codec *codec = w->codec; |
1297 1298 switch (event) { 1299 case SND_SOC_DAPM_POST_PMU: 1300 hp_amp_power(codec, 1); 1301 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 1302 RT5645_PWR_LM, RT5645_PWR_LM); 1303 snd_soc_update_bits(codec, RT5645_LOUT1, 1304 RT5645_L_MUTE | RT5645_R_MUTE, 0); --- 13 unchanged lines hidden (view full) --- 1318 } 1319 1320 return 0; 1321} 1322 1323static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, 1324 struct snd_kcontrol *kcontrol, int event) 1325{ | 1376 1377 switch (event) { 1378 case SND_SOC_DAPM_POST_PMU: 1379 hp_amp_power(codec, 1); 1380 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 1381 RT5645_PWR_LM, RT5645_PWR_LM); 1382 snd_soc_update_bits(codec, RT5645_LOUT1, 1383 RT5645_L_MUTE | RT5645_R_MUTE, 0); --- 13 unchanged lines hidden (view full) --- 1397 } 1398 1399 return 0; 1400} 1401 1402static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, 1403 struct snd_kcontrol *kcontrol, int event) 1404{ |
1326 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 1405 struct snd_soc_codec *codec = w->codec; |
1327 1328 switch (event) { 1329 case SND_SOC_DAPM_POST_PMU: 1330 snd_soc_update_bits(codec, RT5645_PWR_ANLG2, 1331 RT5645_PWR_BST2_P, RT5645_PWR_BST2_P); 1332 break; 1333 1334 case SND_SOC_DAPM_PRE_PMD: --- 1431 unchanged lines hidden --- | 1406 1407 switch (event) { 1408 case SND_SOC_DAPM_POST_PMU: 1409 snd_soc_update_bits(codec, RT5645_PWR_ANLG2, 1410 RT5645_PWR_BST2_P, RT5645_PWR_BST2_P); 1411 break; 1412 1413 case SND_SOC_DAPM_PRE_PMD: --- 1431 unchanged lines hidden --- |