arizona.c (168268a225d24da3768a88c1029fb3014b0837ca) | arizona.c (19b34bdc6d267723f3fc526ae775efba0ca4c39b) |
---|---|
1/* 2 * arizona.c - Wolfson Arizona class device shared support 3 * 4 * Copyright 2012 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 42 unchanged lines hidden (view full) --- 51#define ARIZONA_AIF_RX_ENABLES 0x1A 52#define ARIZONA_AIF_FORCE_WRITE 0x1B 53 54#define arizona_fll_err(_fll, fmt, ...) \ 55 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 56#define arizona_fll_warn(_fll, fmt, ...) \ 57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 58#define arizona_fll_dbg(_fll, fmt, ...) \ | 1/* 2 * arizona.c - Wolfson Arizona class device shared support 3 * 4 * Copyright 2012 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 42 unchanged lines hidden (view full) --- 51#define ARIZONA_AIF_RX_ENABLES 0x1A 52#define ARIZONA_AIF_FORCE_WRITE 0x1B 53 54#define arizona_fll_err(_fll, fmt, ...) \ 55 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 56#define arizona_fll_warn(_fll, fmt, ...) \ 57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 58#define arizona_fll_dbg(_fll, fmt, ...) \ |
59 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) | 59 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) |
60 61#define arizona_aif_err(_dai, fmt, ...) \ 62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 63#define arizona_aif_warn(_dai, fmt, ...) \ 64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 65#define arizona_aif_dbg(_dai, fmt, ...) \ | 60 61#define arizona_aif_err(_dai, fmt, ...) \ 62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 63#define arizona_aif_warn(_dai, fmt, ...) \ 64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 65#define arizona_aif_dbg(_dai, fmt, ...) \ |
66 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) | 66 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) |
67 68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 69 "None", 70 "Tone Generator 1", 71 "Tone Generator 2", 72 "Haptics", 73 "AEC", 74 "Mic Mute Mixer", --- 61 unchanged lines hidden (view full) --- 136 "DSP4.3", 137 "DSP4.4", 138 "DSP4.5", 139 "DSP4.6", 140 "ASRC1L", 141 "ASRC1R", 142 "ASRC2L", 143 "ASRC2R", | 67 68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 69 "None", 70 "Tone Generator 1", 71 "Tone Generator 2", 72 "Haptics", 73 "AEC", 74 "Mic Mute Mixer", --- 61 unchanged lines hidden (view full) --- 136 "DSP4.3", 137 "DSP4.4", 138 "DSP4.5", 139 "DSP4.6", 140 "ASRC1L", 141 "ASRC1R", 142 "ASRC2L", 143 "ASRC2R", |
144 "ISRC1INT1", 145 "ISRC1INT2", 146 "ISRC1INT3", 147 "ISRC1INT4", 148 "ISRC1DEC1", 149 "ISRC1DEC2", 150 "ISRC1DEC3", 151 "ISRC1DEC4", 152 "ISRC2INT1", 153 "ISRC2INT2", 154 "ISRC2INT3", 155 "ISRC2INT4", 156 "ISRC2DEC1", 157 "ISRC2DEC2", 158 "ISRC2DEC3", 159 "ISRC2DEC4", 160 "ISRC3INT1", 161 "ISRC3INT2", 162 "ISRC3INT3", 163 "ISRC3INT4", 164 "ISRC3DEC1", 165 "ISRC3DEC2", 166 "ISRC3DEC3", 167 "ISRC3DEC4", |
|
144}; 145EXPORT_SYMBOL_GPL(arizona_mixer_texts); 146 147int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 148 0x00, /* None */ 149 0x04, /* Tone */ 150 0x05, 151 0x06, /* Haptics */ --- 63 unchanged lines hidden (view full) --- 215 0x82, 216 0x83, 217 0x84, 218 0x85, 219 0x90, /* ASRC1L */ 220 0x91, 221 0x92, 222 0x93, | 168}; 169EXPORT_SYMBOL_GPL(arizona_mixer_texts); 170 171int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 172 0x00, /* None */ 173 0x04, /* Tone */ 174 0x05, 175 0x06, /* Haptics */ --- 63 unchanged lines hidden (view full) --- 239 0x82, 240 0x83, 241 0x84, 242 0x85, 243 0x90, /* ASRC1L */ 244 0x91, 245 0x92, 246 0x93, |
247 0xa0, /* ISRC1INT1 */ 248 0xa1, 249 0xa2, 250 0xa3, 251 0xa4, /* ISRC1DEC1 */ 252 0xa5, 253 0xa6, 254 0xa7, 255 0xa8, /* ISRC2DEC1 */ 256 0xa9, 257 0xaa, 258 0xab, 259 0xac, /* ISRC2INT1 */ 260 0xad, 261 0xae, 262 0xaf, 263 0xb0, /* ISRC3DEC1 */ 264 0xb1, 265 0xb2, 266 0xb3, 267 0xb4, /* ISRC3INT1 */ 268 0xb5, 269 0xb6, 270 0xb7, |
|
223}; 224EXPORT_SYMBOL_GPL(arizona_mixer_values); 225 226const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 227EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 228 229static const char *arizona_vol_ramp_text[] = { 230 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", --- 39 unchanged lines hidden (view full) --- 270 arizona_lhpf_mode_text); 271EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 272 273const struct soc_enum arizona_lhpf4_mode = 274 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, 275 arizona_lhpf_mode_text); 276EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 277 | 271}; 272EXPORT_SYMBOL_GPL(arizona_mixer_values); 273 274const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 275EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 276 277static const char *arizona_vol_ramp_text[] = { 278 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", --- 39 unchanged lines hidden (view full) --- 318 arizona_lhpf_mode_text); 319EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 320 321const struct soc_enum arizona_lhpf4_mode = 322 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, 323 arizona_lhpf_mode_text); 324EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 325 |
326static const char *arizona_ng_hold_text[] = { 327 "30ms", "120ms", "250ms", "500ms", 328}; 329 330const struct soc_enum arizona_ng_hold = 331 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, 332 4, arizona_ng_hold_text); 333EXPORT_SYMBOL_GPL(arizona_ng_hold); 334 |
|
278int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 279 int event) 280{ | 335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 336 int event) 337{ |
338 unsigned int reg; 339 340 if (w->shift % 2) 341 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8); 342 else 343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 344 345 switch (event) { 346 case SND_SOC_DAPM_POST_PMU: 347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 348 break; 349 case SND_SOC_DAPM_PRE_PMD: 350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 351 ARIZONA_IN1L_MUTE); 352 break; 353 } 354 |
|
281 return 0; 282} 283EXPORT_SYMBOL_GPL(arizona_in_ev); 284 285int arizona_out_ev(struct snd_soc_dapm_widget *w, 286 struct snd_kcontrol *kcontrol, 287 int event) 288{ --- 123 unchanged lines hidden (view full) --- 412 case 90316800: 413 case 98304000: 414 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 415 break; 416 case 135475200: 417 case 147456000: 418 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 419 break; | 355 return 0; 356} 357EXPORT_SYMBOL_GPL(arizona_in_ev); 358 359int arizona_out_ev(struct snd_soc_dapm_widget *w, 360 struct snd_kcontrol *kcontrol, 361 int event) 362{ --- 123 unchanged lines hidden (view full) --- 486 case 90316800: 487 case 98304000: 488 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; 489 break; 490 case 135475200: 491 case 147456000: 492 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 493 break; |
494 case 0: 495 dev_dbg(arizona->dev, "%s cleared\n", name); 496 *clk = freq; 497 return 0; |
|
420 default: 421 return -EINVAL; 422 } 423 424 *clk = freq; 425 426 if (freq % 6144000) 427 val |= ARIZONA_SYSCLK_FRAC; --- 202 unchanged lines hidden (view full) --- 630 break; 631 case ARIZONA_CLK_ASYNCCLK: 632 base_rate = priv->asyncclk; 633 break; 634 default: 635 return 0; 636 } 637 | 498 default: 499 return -EINVAL; 500 } 501 502 *clk = freq; 503 504 if (freq % 6144000) 505 val |= ARIZONA_SYSCLK_FRAC; --- 202 unchanged lines hidden (view full) --- 708 break; 709 case ARIZONA_CLK_ASYNCCLK: 710 base_rate = priv->asyncclk; 711 break; 712 default: 713 return 0; 714 } 715 |
716 if (base_rate == 0) 717 return 0; 718 |
|
638 if (base_rate % 8000) 639 constraint = &arizona_44k1_constraint; 640 else 641 constraint = &arizona_48k_constraint; 642 643 return snd_pcm_hw_constraint_list(substream->runtime, 0, 644 SNDRV_PCM_HW_PARAM_RATE, 645 constraint); 646} 647 | 719 if (base_rate % 8000) 720 constraint = &arizona_44k1_constraint; 721 else 722 constraint = &arizona_48k_constraint; 723 724 return snd_pcm_hw_constraint_list(substream->runtime, 0, 725 SNDRV_PCM_HW_PARAM_RATE, 726 constraint); 727} 728 |
729static int arizona_hw_params_rate(struct snd_pcm_substream *substream, 730 struct snd_pcm_hw_params *params, 731 struct snd_soc_dai *dai) 732{ 733 struct snd_soc_codec *codec = dai->codec; 734 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 735 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 736 int base = dai->driver->base; 737 int i, sr_val; 738 739 /* 740 * We will need to be more flexible than this in future, 741 * currently we use a single sample rate for SYSCLK. 742 */ 743 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) 744 if (arizona_sr_vals[i] == params_rate(params)) 745 break; 746 if (i == ARRAY_SIZE(arizona_sr_vals)) { 747 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 748 params_rate(params)); 749 return -EINVAL; 750 } 751 sr_val = i; 752 753 switch (dai_priv->clk) { 754 case ARIZONA_CLK_SYSCLK: 755 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, 756 ARIZONA_SAMPLE_RATE_1_MASK, sr_val); 757 if (base) 758 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 759 ARIZONA_AIF1_RATE_MASK, 0); 760 break; 761 case ARIZONA_CLK_ASYNCCLK: 762 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, 763 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val); 764 if (base) 765 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 766 ARIZONA_AIF1_RATE_MASK, 767 8 << ARIZONA_AIF1_RATE_SHIFT); 768 break; 769 default: 770 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); 771 return -EINVAL; 772 } 773 774 return 0; 775} 776 |
|
648static int arizona_hw_params(struct snd_pcm_substream *substream, 649 struct snd_pcm_hw_params *params, 650 struct snd_soc_dai *dai) 651{ 652 struct snd_soc_codec *codec = dai->codec; 653 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 777static int arizona_hw_params(struct snd_pcm_substream *substream, 778 struct snd_pcm_hw_params *params, 779 struct snd_soc_dai *dai) 780{ 781 struct snd_soc_codec *codec = dai->codec; 782 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
654 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; | 783 struct arizona *arizona = priv->arizona; |
655 int base = dai->driver->base; 656 const int *rates; | 784 int base = dai->driver->base; 785 const int *rates; |
657 int i; 658 int bclk, lrclk, wl, frame, sr_val; | 786 int i, ret; 787 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 788 int bclk, lrclk, wl, frame, bclk_target; |
659 660 if (params_rate(params) % 8000) 661 rates = &arizona_44k1_bclk_rates[0]; 662 else 663 rates = &arizona_48k_bclk_rates[0]; 664 | 789 790 if (params_rate(params) % 8000) 791 rates = &arizona_44k1_bclk_rates[0]; 792 else 793 rates = &arizona_48k_bclk_rates[0]; 794 |
795 bclk_target = snd_soc_params_to_bclk(params); 796 if (chan_limit && chan_limit < params_channels(params)) { 797 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit); 798 bclk_target /= params_channels(params); 799 bclk_target *= chan_limit; 800 } 801 |
|
665 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { | 802 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { |
666 if (rates[i] >= snd_soc_params_to_bclk(params) && | 803 if (rates[i] >= bclk_target && |
667 rates[i] % params_rate(params) == 0) { 668 bclk = i; 669 break; 670 } 671 } 672 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) { 673 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 674 params_rate(params)); 675 return -EINVAL; 676 } 677 | 804 rates[i] % params_rate(params) == 0) { 805 bclk = i; 806 break; 807 } 808 } 809 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) { 810 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 811 params_rate(params)); 812 return -EINVAL; 813 } 814 |
678 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) 679 if (arizona_sr_vals[i] == params_rate(params)) 680 break; 681 if (i == ARRAY_SIZE(arizona_sr_vals)) { 682 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 683 params_rate(params)); 684 return -EINVAL; 685 } 686 sr_val = i; 687 | |
688 lrclk = rates[bclk] / params_rate(params); 689 690 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", 691 rates[bclk], rates[bclk] / lrclk); 692 693 wl = snd_pcm_format_width(params_format(params)); 694 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; 695 | 815 lrclk = rates[bclk] / params_rate(params); 816 817 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", 818 rates[bclk], rates[bclk] / lrclk); 819 820 wl = snd_pcm_format_width(params_format(params)); 821 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; 822 |
696 /* 697 * We will need to be more flexible than this in future, 698 * currently we use a single sample rate for SYSCLK. 699 */ 700 switch (dai_priv->clk) { 701 case ARIZONA_CLK_SYSCLK: 702 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, 703 ARIZONA_SAMPLE_RATE_1_MASK, sr_val); 704 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 705 ARIZONA_AIF1_RATE_MASK, 0); 706 break; 707 case ARIZONA_CLK_ASYNCCLK: 708 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, 709 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val); 710 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 711 ARIZONA_AIF1_RATE_MASK, 712 8 << ARIZONA_AIF1_RATE_SHIFT); 713 break; 714 default: 715 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); 716 return -EINVAL; 717 } | 823 ret = arizona_hw_params_rate(substream, params, dai); 824 if (ret != 0) 825 return ret; |
718 719 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, 720 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); 721 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, 722 ARIZONA_AIF1TX_BCPF_MASK, lrclk); 723 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, 724 ARIZONA_AIF1RX_BCPF_MASK, lrclk); 725 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, --- 58 unchanged lines hidden (view full) --- 784 routes[1].source = arizona_dai_clk_str(clk_id); 785 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); 786 787 dai_priv->clk = clk_id; 788 789 return snd_soc_dapm_sync(&codec->dapm); 790} 791 | 826 827 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, 828 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); 829 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, 830 ARIZONA_AIF1TX_BCPF_MASK, lrclk); 831 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, 832 ARIZONA_AIF1RX_BCPF_MASK, lrclk); 833 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, --- 58 unchanged lines hidden (view full) --- 892 routes[1].source = arizona_dai_clk_str(clk_id); 893 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); 894 895 dai_priv->clk = clk_id; 896 897 return snd_soc_dapm_sync(&codec->dapm); 898} 899 |
900static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate) 901{ 902 struct snd_soc_codec *codec = dai->codec; 903 int base = dai->driver->base; 904 unsigned int reg; 905 906 if (tristate) 907 reg = ARIZONA_AIF1_TRI; 908 else 909 reg = 0; 910 911 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 912 ARIZONA_AIF1_TRI, reg); 913} 914 |
|
792const struct snd_soc_dai_ops arizona_dai_ops = { 793 .startup = arizona_startup, 794 .set_fmt = arizona_set_fmt, 795 .hw_params = arizona_hw_params, 796 .set_sysclk = arizona_dai_set_sysclk, | 915const struct snd_soc_dai_ops arizona_dai_ops = { 916 .startup = arizona_startup, 917 .set_fmt = arizona_set_fmt, 918 .hw_params = arizona_hw_params, 919 .set_sysclk = arizona_dai_set_sysclk, |
920 .set_tristate = arizona_set_tristate, |
|
797}; 798EXPORT_SYMBOL_GPL(arizona_dai_ops); 799 800int arizona_init_dai(struct arizona_priv *priv, int id) 801{ 802 struct arizona_dai_priv *dai_priv = &priv->dai[id]; 803 804 dai_priv->clk = ARIZONA_CLK_SYSCLK; 805 806 return 0; 807} 808EXPORT_SYMBOL_GPL(arizona_init_dai); 809 | 921}; 922EXPORT_SYMBOL_GPL(arizona_dai_ops); 923 924int arizona_init_dai(struct arizona_priv *priv, int id) 925{ 926 struct arizona_dai_priv *dai_priv = &priv->dai[id]; 927 928 dai_priv->clk = ARIZONA_CLK_SYSCLK; 929 930 return 0; 931} 932EXPORT_SYMBOL_GPL(arizona_init_dai); 933 |
810static irqreturn_t arizona_fll_lock(int irq, void *data) 811{ 812 struct arizona_fll *fll = data; 813 814 arizona_fll_dbg(fll, "Lock status changed\n"); 815 816 complete(&fll->lock); 817 818 return IRQ_HANDLED; 819} 820 | |
821static irqreturn_t arizona_fll_clock_ok(int irq, void *data) 822{ 823 struct arizona_fll *fll = data; 824 825 arizona_fll_dbg(fll, "clock OK\n"); 826 827 complete(&fll->ok); 828 --- 76 unchanged lines hidden (view full) --- 905 if (i == ARRAY_SIZE(fll_fratios)) { 906 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", 907 Fref); 908 return -EINVAL; 909 } 910 911 cfg->n = target / (ratio * Fref); 912 | 934static irqreturn_t arizona_fll_clock_ok(int irq, void *data) 935{ 936 struct arizona_fll *fll = data; 937 938 arizona_fll_dbg(fll, "clock OK\n"); 939 940 complete(&fll->ok); 941 --- 76 unchanged lines hidden (view full) --- 1018 if (i == ARRAY_SIZE(fll_fratios)) { 1019 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", 1020 Fref); 1021 return -EINVAL; 1022 } 1023 1024 cfg->n = target / (ratio * Fref); 1025 |
913 if (target % Fref) { | 1026 if (target % (ratio * Fref)) { |
914 gcd_fll = gcd(target, ratio * Fref); 915 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); 916 917 cfg->theta = (target - (cfg->n * ratio * Fref)) 918 / gcd_fll; 919 cfg->lambda = (ratio * Fref) / gcd_fll; 920 } else { 921 cfg->theta = 0; 922 cfg->lambda = 0; 923 } 924 | 1027 gcd_fll = gcd(target, ratio * Fref); 1028 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); 1029 1030 cfg->theta = (target - (cfg->n * ratio * Fref)) 1031 / gcd_fll; 1032 cfg->lambda = (ratio * Fref) / gcd_fll; 1033 } else { 1034 cfg->theta = 0; 1035 cfg->lambda = 0; 1036 } 1037 |
1038 /* Round down to 16bit range with cost of accuracy lost. 1039 * Denominator must be bigger than numerator so we only 1040 * take care of it. 1041 */ 1042 while (cfg->lambda >= (1 << 16)) { 1043 cfg->theta >>= 1; 1044 cfg->lambda >>= 1; 1045 } 1046 |
|
925 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 926 cfg->n, cfg->theta, cfg->lambda); 927 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 928 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 929 930 return 0; 931 932} --- 19 unchanged lines hidden (view full) --- 952 ARIZONA_FLL1_CTRL_UPD | cfg->n); 953} 954 955int arizona_set_fll(struct arizona_fll *fll, int source, 956 unsigned int Fref, unsigned int Fout) 957{ 958 struct arizona *arizona = fll->arizona; 959 struct arizona_fll_cfg cfg, sync; | 1047 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 1048 cfg->n, cfg->theta, cfg->lambda); 1049 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1050 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1051 1052 return 0; 1053 1054} --- 19 unchanged lines hidden (view full) --- 1074 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1075} 1076 1077int arizona_set_fll(struct arizona_fll *fll, int source, 1078 unsigned int Fref, unsigned int Fout) 1079{ 1080 struct arizona *arizona = fll->arizona; 1081 struct arizona_fll_cfg cfg, sync; |
960 unsigned int reg, val; | 1082 unsigned int reg; |
961 int syncsrc; 962 bool ena; 963 int ret; 964 965 if (fll->fref == Fref && fll->fout == Fout) 966 return 0; 967 968 ret = regmap_read(arizona->regmap, fll->base + 1, ®); 969 if (ret != 0) { 970 arizona_fll_err(fll, "Failed to read current state: %d\n", 971 ret); 972 return ret; 973 } 974 ena = reg & ARIZONA_FLL1_ENA; 975 976 if (Fout) { | 1083 int syncsrc; 1084 bool ena; 1085 int ret; 1086 1087 if (fll->fref == Fref && fll->fout == Fout) 1088 return 0; 1089 1090 ret = regmap_read(arizona->regmap, fll->base + 1, ®); 1091 if (ret != 0) { 1092 arizona_fll_err(fll, "Failed to read current state: %d\n", 1093 ret); 1094 return ret; 1095 } 1096 ena = reg & ARIZONA_FLL1_ENA; 1097 1098 if (Fout) { |
977 /* Do we have a 32kHz reference? */ 978 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); 979 switch (val & ARIZONA_CLK_32K_SRC_MASK) { 980 case ARIZONA_CLK_SRC_MCLK1: 981 case ARIZONA_CLK_SRC_MCLK2: 982 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; 983 break; 984 default: 985 syncsrc = -1; 986 } | 1099 syncsrc = fll->ref_src; |
987 988 if (source == syncsrc) 989 syncsrc = -1; 990 991 if (syncsrc >= 0) { 992 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 993 if (ret != 0) 994 return ret; 995 | 1100 1101 if (source == syncsrc) 1102 syncsrc = -1; 1103 1104 if (syncsrc >= 0) { 1105 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1106 if (ret != 0) 1107 return ret; 1108 |
996 ret = arizona_calc_fll(fll, &cfg, 32768, Fout); | 1109 ret = arizona_calc_fll(fll, &cfg, fll->ref_freq, Fout); |
997 if (ret != 0) 998 return ret; 999 } else { 1000 ret = arizona_calc_fll(fll, &cfg, Fref, Fout); 1001 if (ret != 0) 1002 return ret; 1003 } 1004 } else { --- 46 unchanged lines hidden (view full) --- 1051 return 0; 1052} 1053EXPORT_SYMBOL_GPL(arizona_set_fll); 1054 1055int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, 1056 int ok_irq, struct arizona_fll *fll) 1057{ 1058 int ret; | 1110 if (ret != 0) 1111 return ret; 1112 } else { 1113 ret = arizona_calc_fll(fll, &cfg, Fref, Fout); 1114 if (ret != 0) 1115 return ret; 1116 } 1117 } else { --- 46 unchanged lines hidden (view full) --- 1164 return 0; 1165} 1166EXPORT_SYMBOL_GPL(arizona_set_fll); 1167 1168int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, 1169 int ok_irq, struct arizona_fll *fll) 1170{ 1171 int ret; |
1172 unsigned int val; |
|
1059 | 1173 |
1060 init_completion(&fll->lock); | |
1061 init_completion(&fll->ok); 1062 1063 fll->id = id; 1064 fll->base = base; 1065 fll->arizona = arizona; 1066 | 1174 init_completion(&fll->ok); 1175 1176 fll->id = id; 1177 fll->base = base; 1178 fll->arizona = arizona; 1179 |
1180 /* Configure default refclk to 32kHz if we have one */ 1181 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); 1182 switch (val & ARIZONA_CLK_32K_SRC_MASK) { 1183 case ARIZONA_CLK_SRC_MCLK1: 1184 case ARIZONA_CLK_SRC_MCLK2: 1185 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; 1186 break; 1187 default: 1188 fll->ref_src = -1; 1189 } 1190 fll->ref_freq = 32768; 1191 |
|
1067 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1068 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1069 "FLL%d clock OK", id); 1070 | 1192 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1193 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1194 "FLL%d clock OK", id); 1195 |
1071 ret = arizona_request_irq(arizona, lock_irq, fll->lock_name, 1072 arizona_fll_lock, fll); 1073 if (ret != 0) { 1074 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n", 1075 id, ret); 1076 } 1077 | |
1078 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name, 1079 arizona_fll_clock_ok, fll); 1080 if (ret != 0) { 1081 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n", 1082 id, ret); 1083 } 1084 1085 regmap_update_bits(arizona->regmap, fll->base + 1, 1086 ARIZONA_FLL1_FREERUN, 0); 1087 1088 return 0; 1089} 1090EXPORT_SYMBOL_GPL(arizona_init_fll); 1091 | 1196 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name, 1197 arizona_fll_clock_ok, fll); 1198 if (ret != 0) { 1199 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n", 1200 id, ret); 1201 } 1202 1203 regmap_update_bits(arizona->regmap, fll->base + 1, 1204 ARIZONA_FLL1_FREERUN, 0); 1205 1206 return 0; 1207} 1208EXPORT_SYMBOL_GPL(arizona_init_fll); 1209 |
1210/** 1211 * arizona_set_output_mode - Set the mode of the specified output 1212 * 1213 * @codec: Device to configure 1214 * @output: Output number 1215 * @diff: True to set the output to differential mode 1216 * 1217 * Some systems use external analogue switches to connect more 1218 * analogue devices to the CODEC than are supported by the device. In 1219 * some systems this requires changing the switched output from single 1220 * ended to differential mode dynamically at runtime, an operation 1221 * supported using this function. 1222 * 1223 * Most systems have a single static configuration and should use 1224 * platform data instead. 1225 */ 1226int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff) 1227{ 1228 unsigned int reg, val; 1229 1230 if (output < 1 || output > 6) 1231 return -EINVAL; 1232 1233 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8; 1234 1235 if (diff) 1236 val = ARIZONA_OUT1_MONO; 1237 else 1238 val = 0; 1239 1240 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val); 1241} 1242EXPORT_SYMBOL_GPL(arizona_set_output_mode); 1243 |
|
1092MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 1093MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1094MODULE_LICENSE("GPL"); | 1244MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 1245MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1246MODULE_LICENSE("GPL"); |