1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * wm2200.c -- WM2200 ALSA SoC Audio driver 4 * 5 * Copyright 2012 Wolfson Microelectronics plc 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/moduleparam.h> 12 #include <linux/init.h> 13 #include <linux/delay.h> 14 #include <linux/pm.h> 15 #include <linux/firmware.h> 16 #include <linux/gcd.h> 17 #include <linux/gpio.h> 18 #include <linux/i2c.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/regulator/consumer.h> 21 #include <linux/regulator/fixed.h> 22 #include <linux/slab.h> 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc.h> 27 #include <sound/jack.h> 28 #include <sound/initval.h> 29 #include <sound/tlv.h> 30 #include <sound/wm2200.h> 31 32 #include "wm2200.h" 33 #include "wmfw.h" 34 #include "wm_adsp.h" 35 36 #define WM2200_DSP_CONTROL_1 0x00 37 #define WM2200_DSP_CONTROL_2 0x02 38 #define WM2200_DSP_CONTROL_3 0x03 39 #define WM2200_DSP_CONTROL_4 0x04 40 #define WM2200_DSP_CONTROL_5 0x06 41 #define WM2200_DSP_CONTROL_6 0x07 42 #define WM2200_DSP_CONTROL_7 0x08 43 #define WM2200_DSP_CONTROL_8 0x09 44 #define WM2200_DSP_CONTROL_9 0x0A 45 #define WM2200_DSP_CONTROL_10 0x0B 46 #define WM2200_DSP_CONTROL_11 0x0C 47 #define WM2200_DSP_CONTROL_12 0x0D 48 #define WM2200_DSP_CONTROL_13 0x0F 49 #define WM2200_DSP_CONTROL_14 0x10 50 #define WM2200_DSP_CONTROL_15 0x11 51 #define WM2200_DSP_CONTROL_16 0x12 52 #define WM2200_DSP_CONTROL_17 0x13 53 #define WM2200_DSP_CONTROL_18 0x14 54 #define WM2200_DSP_CONTROL_19 0x16 55 #define WM2200_DSP_CONTROL_20 0x17 56 #define WM2200_DSP_CONTROL_21 0x18 57 #define WM2200_DSP_CONTROL_22 0x1A 58 #define WM2200_DSP_CONTROL_23 0x1B 59 #define WM2200_DSP_CONTROL_24 0x1C 60 #define WM2200_DSP_CONTROL_25 0x1E 61 #define WM2200_DSP_CONTROL_26 0x20 62 #define WM2200_DSP_CONTROL_27 0x21 63 #define WM2200_DSP_CONTROL_28 0x22 64 #define WM2200_DSP_CONTROL_29 0x23 65 #define WM2200_DSP_CONTROL_30 0x24 66 #define WM2200_DSP_CONTROL_31 0x26 67 68 /* The code assumes DCVDD is generated internally */ 69 #define WM2200_NUM_CORE_SUPPLIES 2 70 static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = { 71 "DBVDD", 72 "LDOVDD", 73 }; 74 75 /* codec private data */ 76 struct wm2200_priv { 77 struct wm_adsp dsp[2]; 78 struct regmap *regmap; 79 struct device *dev; 80 struct snd_soc_component *component; 81 struct wm2200_pdata pdata; 82 struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES]; 83 84 struct completion fll_lock; 85 int fll_fout; 86 int fll_fref; 87 int fll_src; 88 89 int rev; 90 int sysclk; 91 92 unsigned int symmetric_rates:1; 93 }; 94 95 #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) 96 #define WM2200_DSP_SPACING 12288 97 98 #define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING)) 99 #define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING)) 100 #define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING)) 101 #define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING)) 102 #define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING)) 103 #define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING)) 104 105 static const struct regmap_range_cfg wm2200_ranges[] = { 106 { .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE, 107 .range_max = WM2200_DSP1_DM_BASE + 12287, 108 .selector_reg = WM2200_DSP1_CONTROL_3, 109 .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK, 110 .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT, 111 .window_start = WM2200_DSP1_DM_0, .window_len = 2048, }, 112 113 { .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE, 114 .range_max = WM2200_DSP1_PM_BASE + 12287, 115 .selector_reg = WM2200_DSP1_CONTROL_2, 116 .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK, 117 .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT, 118 .window_start = WM2200_DSP1_PM_0, .window_len = 768, }, 119 120 { .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE, 121 .range_max = WM2200_DSP1_ZM_BASE + 2047, 122 .selector_reg = WM2200_DSP1_CONTROL_4, 123 .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK, 124 .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT, 125 .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, }, 126 127 { .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE, 128 .range_max = WM2200_DSP2_DM_BASE + 4095, 129 .selector_reg = WM2200_DSP2_CONTROL_3, 130 .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK, 131 .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT, 132 .window_start = WM2200_DSP2_DM_0, .window_len = 2048, }, 133 134 { .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE, 135 .range_max = WM2200_DSP2_PM_BASE + 11287, 136 .selector_reg = WM2200_DSP2_CONTROL_2, 137 .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK, 138 .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT, 139 .window_start = WM2200_DSP2_PM_0, .window_len = 768, }, 140 141 { .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE, 142 .range_max = WM2200_DSP2_ZM_BASE + 2047, 143 .selector_reg = WM2200_DSP2_CONTROL_4, 144 .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK, 145 .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT, 146 .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, 147 }; 148 149 static const struct wm_adsp_region wm2200_dsp1_regions[] = { 150 { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, 151 { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, 152 { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, 153 }; 154 155 static const struct wm_adsp_region wm2200_dsp2_regions[] = { 156 { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, 157 { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, 158 { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, 159 }; 160 161 static const struct reg_default wm2200_reg_defaults[] = { 162 { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ 163 { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ 164 { 0x0103, 0x0011 }, /* R259 - Clocking 4 */ 165 { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */ 166 { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */ 167 { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */ 168 { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */ 169 { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */ 170 { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */ 171 { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */ 172 { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */ 173 { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */ 174 { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */ 175 { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */ 176 { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */ 177 { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */ 178 { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */ 179 { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */ 180 { 0x0301, 0x0000 }, /* R769 - Input Enables */ 181 { 0x0302, 0x2240 }, /* R770 - IN1L Control */ 182 { 0x0303, 0x0040 }, /* R771 - IN1R Control */ 183 { 0x0304, 0x2240 }, /* R772 - IN2L Control */ 184 { 0x0305, 0x0040 }, /* R773 - IN2R Control */ 185 { 0x0306, 0x2240 }, /* R774 - IN3L Control */ 186 { 0x0307, 0x0040 }, /* R775 - IN3R Control */ 187 { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */ 188 { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */ 189 { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */ 190 { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */ 191 { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */ 192 { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */ 193 { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */ 194 { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */ 195 { 0x0400, 0x0000 }, /* R1024 - Output Enables */ 196 { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */ 197 { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */ 198 { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */ 199 { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */ 200 { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */ 201 { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */ 202 { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */ 203 { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */ 204 { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */ 205 { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */ 206 { 0x0417, 0x0069 }, /* R1047 - PDM 1 */ 207 { 0x0418, 0x0000 }, /* R1048 - PDM 2 */ 208 { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */ 209 { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */ 210 { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */ 211 { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */ 212 { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */ 213 { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */ 214 { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */ 215 { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */ 216 { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */ 217 { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */ 218 { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */ 219 { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */ 220 { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */ 221 { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */ 222 { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */ 223 { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */ 224 { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */ 225 { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */ 226 { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */ 227 { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */ 228 { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */ 229 { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */ 230 { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */ 231 { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */ 232 { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */ 233 { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */ 234 { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */ 235 { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */ 236 { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */ 237 { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */ 238 { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */ 239 { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */ 240 { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */ 241 { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */ 242 { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */ 243 { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */ 244 { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */ 245 { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */ 246 { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */ 247 { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */ 248 { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */ 249 { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */ 250 { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */ 251 { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */ 252 { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */ 253 { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */ 254 { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */ 255 { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */ 256 { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */ 257 { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */ 258 { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */ 259 { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */ 260 { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */ 261 { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */ 262 { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */ 263 { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */ 264 { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */ 265 { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */ 266 { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */ 267 { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */ 268 { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */ 269 { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */ 270 { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */ 271 { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */ 272 { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */ 273 { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */ 274 { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */ 275 { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */ 276 { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */ 277 { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */ 278 { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */ 279 { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */ 280 { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */ 281 { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */ 282 { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */ 283 { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */ 284 { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */ 285 { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */ 286 { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */ 287 { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */ 288 { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */ 289 { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */ 290 { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */ 291 { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */ 292 { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */ 293 { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */ 294 { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */ 295 { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */ 296 { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */ 297 { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */ 298 { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */ 299 { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */ 300 { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */ 301 { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */ 302 { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */ 303 { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */ 304 { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */ 305 { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */ 306 { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */ 307 { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */ 308 { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */ 309 { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */ 310 { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */ 311 { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */ 312 { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */ 313 { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */ 314 { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */ 315 { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */ 316 { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */ 317 { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */ 318 { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */ 319 { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */ 320 { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */ 321 { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */ 322 { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */ 323 { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */ 324 { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */ 325 { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */ 326 { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */ 327 { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */ 328 { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */ 329 { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */ 330 { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */ 331 { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */ 332 { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */ 333 { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */ 334 { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */ 335 { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */ 336 { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */ 337 { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */ 338 { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */ 339 { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */ 340 { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */ 341 { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */ 342 { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */ 343 { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */ 344 { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */ 345 { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */ 346 { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */ 347 { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */ 348 { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */ 349 { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */ 350 { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */ 351 { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */ 352 { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */ 353 { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */ 354 { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */ 355 { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */ 356 { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */ 357 { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */ 358 { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */ 359 { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */ 360 { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */ 361 { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */ 362 { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */ 363 { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */ 364 { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */ 365 { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */ 366 { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */ 367 { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */ 368 { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */ 369 { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */ 370 { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */ 371 { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */ 372 { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */ 373 { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */ 374 { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */ 375 { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */ 376 { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */ 377 { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */ 378 { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */ 379 { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */ 380 { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */ 381 { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */ 382 { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */ 383 { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */ 384 { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */ 385 { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */ 386 { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */ 387 { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */ 388 { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */ 389 { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */ 390 { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */ 391 { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */ 392 { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */ 393 { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */ 394 { 0x0900, 0x0000 }, /* R2304 - EQL_1 */ 395 { 0x0901, 0x0000 }, /* R2305 - EQL_2 */ 396 { 0x0902, 0x0000 }, /* R2306 - EQL_3 */ 397 { 0x0903, 0x0000 }, /* R2307 - EQL_4 */ 398 { 0x0904, 0x0000 }, /* R2308 - EQL_5 */ 399 { 0x0905, 0x0000 }, /* R2309 - EQL_6 */ 400 { 0x0906, 0x0000 }, /* R2310 - EQL_7 */ 401 { 0x0907, 0x0000 }, /* R2311 - EQL_8 */ 402 { 0x0908, 0x0000 }, /* R2312 - EQL_9 */ 403 { 0x0909, 0x0000 }, /* R2313 - EQL_10 */ 404 { 0x090A, 0x0000 }, /* R2314 - EQL_11 */ 405 { 0x090B, 0x0000 }, /* R2315 - EQL_12 */ 406 { 0x090C, 0x0000 }, /* R2316 - EQL_13 */ 407 { 0x090D, 0x0000 }, /* R2317 - EQL_14 */ 408 { 0x090E, 0x0000 }, /* R2318 - EQL_15 */ 409 { 0x090F, 0x0000 }, /* R2319 - EQL_16 */ 410 { 0x0910, 0x0000 }, /* R2320 - EQL_17 */ 411 { 0x0911, 0x0000 }, /* R2321 - EQL_18 */ 412 { 0x0912, 0x0000 }, /* R2322 - EQL_19 */ 413 { 0x0913, 0x0000 }, /* R2323 - EQL_20 */ 414 { 0x0916, 0x0000 }, /* R2326 - EQR_1 */ 415 { 0x0917, 0x0000 }, /* R2327 - EQR_2 */ 416 { 0x0918, 0x0000 }, /* R2328 - EQR_3 */ 417 { 0x0919, 0x0000 }, /* R2329 - EQR_4 */ 418 { 0x091A, 0x0000 }, /* R2330 - EQR_5 */ 419 { 0x091B, 0x0000 }, /* R2331 - EQR_6 */ 420 { 0x091C, 0x0000 }, /* R2332 - EQR_7 */ 421 { 0x091D, 0x0000 }, /* R2333 - EQR_8 */ 422 { 0x091E, 0x0000 }, /* R2334 - EQR_9 */ 423 { 0x091F, 0x0000 }, /* R2335 - EQR_10 */ 424 { 0x0920, 0x0000 }, /* R2336 - EQR_11 */ 425 { 0x0921, 0x0000 }, /* R2337 - EQR_12 */ 426 { 0x0922, 0x0000 }, /* R2338 - EQR_13 */ 427 { 0x0923, 0x0000 }, /* R2339 - EQR_14 */ 428 { 0x0924, 0x0000 }, /* R2340 - EQR_15 */ 429 { 0x0925, 0x0000 }, /* R2341 - EQR_16 */ 430 { 0x0926, 0x0000 }, /* R2342 - EQR_17 */ 431 { 0x0927, 0x0000 }, /* R2343 - EQR_18 */ 432 { 0x0928, 0x0000 }, /* R2344 - EQR_19 */ 433 { 0x0929, 0x0000 }, /* R2345 - EQR_20 */ 434 { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */ 435 { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */ 436 { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */ 437 { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */ 438 { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */ 439 { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */ 440 { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */ 441 { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */ 442 { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */ 443 { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */ 444 { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */ 445 { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */ 446 { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */ 447 { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */ 448 { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */ 449 { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */ 450 { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */ 451 { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */ 452 { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */ 453 { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */ 454 { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */ 455 { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */ 456 { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */ 457 { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */ 458 { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */ 459 { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */ 460 { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */ 461 { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */ 462 { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */ 463 { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */ 464 { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */ 465 { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */ 466 { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */ 467 { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */ 468 { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */ 469 { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */ 470 { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */ 471 { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */ 472 { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */ 473 { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */ 474 { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */ 475 { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */ 476 { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */ 477 { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */ 478 { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */ 479 { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */ 480 { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */ 481 { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */ 482 { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */ 483 { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */ 484 { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */ 485 { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */ 486 { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */ 487 { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */ 488 { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */ 489 { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */ 490 { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */ 491 { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */ 492 { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */ 493 { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */ 494 { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */ 495 { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */ 496 { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */ 497 { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */ 498 { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */ 499 { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */ 500 }; 501 502 static bool wm2200_volatile_register(struct device *dev, unsigned int reg) 503 { 504 int i; 505 506 for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) 507 if ((reg >= wm2200_ranges[i].window_start && 508 reg <= wm2200_ranges[i].window_start + 509 wm2200_ranges[i].window_len) || 510 (reg >= wm2200_ranges[i].range_min && 511 reg <= wm2200_ranges[i].range_max)) 512 return true; 513 514 switch (reg) { 515 case WM2200_SOFTWARE_RESET: 516 case WM2200_DEVICE_REVISION: 517 case WM2200_ADPS1_IRQ0: 518 case WM2200_ADPS1_IRQ1: 519 case WM2200_INTERRUPT_STATUS_1: 520 case WM2200_INTERRUPT_STATUS_2: 521 case WM2200_INTERRUPT_RAW_STATUS_2: 522 return true; 523 default: 524 return false; 525 } 526 } 527 528 static bool wm2200_readable_register(struct device *dev, unsigned int reg) 529 { 530 int i; 531 532 for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++) 533 if ((reg >= wm2200_ranges[i].window_start && 534 reg <= wm2200_ranges[i].window_start + 535 wm2200_ranges[i].window_len) || 536 (reg >= wm2200_ranges[i].range_min && 537 reg <= wm2200_ranges[i].range_max)) 538 return true; 539 540 switch (reg) { 541 case WM2200_SOFTWARE_RESET: 542 case WM2200_DEVICE_REVISION: 543 case WM2200_TONE_GENERATOR_1: 544 case WM2200_CLOCKING_3: 545 case WM2200_CLOCKING_4: 546 case WM2200_FLL_CONTROL_1: 547 case WM2200_FLL_CONTROL_2: 548 case WM2200_FLL_CONTROL_3: 549 case WM2200_FLL_CONTROL_4: 550 case WM2200_FLL_CONTROL_6: 551 case WM2200_FLL_CONTROL_7: 552 case WM2200_FLL_EFS_1: 553 case WM2200_FLL_EFS_2: 554 case WM2200_MIC_CHARGE_PUMP_1: 555 case WM2200_MIC_CHARGE_PUMP_2: 556 case WM2200_DM_CHARGE_PUMP_1: 557 case WM2200_MIC_BIAS_CTRL_1: 558 case WM2200_MIC_BIAS_CTRL_2: 559 case WM2200_EAR_PIECE_CTRL_1: 560 case WM2200_EAR_PIECE_CTRL_2: 561 case WM2200_INPUT_ENABLES: 562 case WM2200_IN1L_CONTROL: 563 case WM2200_IN1R_CONTROL: 564 case WM2200_IN2L_CONTROL: 565 case WM2200_IN2R_CONTROL: 566 case WM2200_IN3L_CONTROL: 567 case WM2200_IN3R_CONTROL: 568 case WM2200_RXANC_SRC: 569 case WM2200_INPUT_VOLUME_RAMP: 570 case WM2200_ADC_DIGITAL_VOLUME_1L: 571 case WM2200_ADC_DIGITAL_VOLUME_1R: 572 case WM2200_ADC_DIGITAL_VOLUME_2L: 573 case WM2200_ADC_DIGITAL_VOLUME_2R: 574 case WM2200_ADC_DIGITAL_VOLUME_3L: 575 case WM2200_ADC_DIGITAL_VOLUME_3R: 576 case WM2200_OUTPUT_ENABLES: 577 case WM2200_DAC_VOLUME_LIMIT_1L: 578 case WM2200_DAC_VOLUME_LIMIT_1R: 579 case WM2200_DAC_VOLUME_LIMIT_2L: 580 case WM2200_DAC_VOLUME_LIMIT_2R: 581 case WM2200_DAC_AEC_CONTROL_1: 582 case WM2200_OUTPUT_VOLUME_RAMP: 583 case WM2200_DAC_DIGITAL_VOLUME_1L: 584 case WM2200_DAC_DIGITAL_VOLUME_1R: 585 case WM2200_DAC_DIGITAL_VOLUME_2L: 586 case WM2200_DAC_DIGITAL_VOLUME_2R: 587 case WM2200_PDM_1: 588 case WM2200_PDM_2: 589 case WM2200_AUDIO_IF_1_1: 590 case WM2200_AUDIO_IF_1_2: 591 case WM2200_AUDIO_IF_1_3: 592 case WM2200_AUDIO_IF_1_4: 593 case WM2200_AUDIO_IF_1_5: 594 case WM2200_AUDIO_IF_1_6: 595 case WM2200_AUDIO_IF_1_7: 596 case WM2200_AUDIO_IF_1_8: 597 case WM2200_AUDIO_IF_1_9: 598 case WM2200_AUDIO_IF_1_10: 599 case WM2200_AUDIO_IF_1_11: 600 case WM2200_AUDIO_IF_1_12: 601 case WM2200_AUDIO_IF_1_13: 602 case WM2200_AUDIO_IF_1_14: 603 case WM2200_AUDIO_IF_1_15: 604 case WM2200_AUDIO_IF_1_16: 605 case WM2200_AUDIO_IF_1_17: 606 case WM2200_AUDIO_IF_1_18: 607 case WM2200_AUDIO_IF_1_19: 608 case WM2200_AUDIO_IF_1_20: 609 case WM2200_AUDIO_IF_1_21: 610 case WM2200_AUDIO_IF_1_22: 611 case WM2200_OUT1LMIX_INPUT_1_SOURCE: 612 case WM2200_OUT1LMIX_INPUT_1_VOLUME: 613 case WM2200_OUT1LMIX_INPUT_2_SOURCE: 614 case WM2200_OUT1LMIX_INPUT_2_VOLUME: 615 case WM2200_OUT1LMIX_INPUT_3_SOURCE: 616 case WM2200_OUT1LMIX_INPUT_3_VOLUME: 617 case WM2200_OUT1LMIX_INPUT_4_SOURCE: 618 case WM2200_OUT1LMIX_INPUT_4_VOLUME: 619 case WM2200_OUT1RMIX_INPUT_1_SOURCE: 620 case WM2200_OUT1RMIX_INPUT_1_VOLUME: 621 case WM2200_OUT1RMIX_INPUT_2_SOURCE: 622 case WM2200_OUT1RMIX_INPUT_2_VOLUME: 623 case WM2200_OUT1RMIX_INPUT_3_SOURCE: 624 case WM2200_OUT1RMIX_INPUT_3_VOLUME: 625 case WM2200_OUT1RMIX_INPUT_4_SOURCE: 626 case WM2200_OUT1RMIX_INPUT_4_VOLUME: 627 case WM2200_OUT2LMIX_INPUT_1_SOURCE: 628 case WM2200_OUT2LMIX_INPUT_1_VOLUME: 629 case WM2200_OUT2LMIX_INPUT_2_SOURCE: 630 case WM2200_OUT2LMIX_INPUT_2_VOLUME: 631 case WM2200_OUT2LMIX_INPUT_3_SOURCE: 632 case WM2200_OUT2LMIX_INPUT_3_VOLUME: 633 case WM2200_OUT2LMIX_INPUT_4_SOURCE: 634 case WM2200_OUT2LMIX_INPUT_4_VOLUME: 635 case WM2200_OUT2RMIX_INPUT_1_SOURCE: 636 case WM2200_OUT2RMIX_INPUT_1_VOLUME: 637 case WM2200_OUT2RMIX_INPUT_2_SOURCE: 638 case WM2200_OUT2RMIX_INPUT_2_VOLUME: 639 case WM2200_OUT2RMIX_INPUT_3_SOURCE: 640 case WM2200_OUT2RMIX_INPUT_3_VOLUME: 641 case WM2200_OUT2RMIX_INPUT_4_SOURCE: 642 case WM2200_OUT2RMIX_INPUT_4_VOLUME: 643 case WM2200_AIF1TX1MIX_INPUT_1_SOURCE: 644 case WM2200_AIF1TX1MIX_INPUT_1_VOLUME: 645 case WM2200_AIF1TX1MIX_INPUT_2_SOURCE: 646 case WM2200_AIF1TX1MIX_INPUT_2_VOLUME: 647 case WM2200_AIF1TX1MIX_INPUT_3_SOURCE: 648 case WM2200_AIF1TX1MIX_INPUT_3_VOLUME: 649 case WM2200_AIF1TX1MIX_INPUT_4_SOURCE: 650 case WM2200_AIF1TX1MIX_INPUT_4_VOLUME: 651 case WM2200_AIF1TX2MIX_INPUT_1_SOURCE: 652 case WM2200_AIF1TX2MIX_INPUT_1_VOLUME: 653 case WM2200_AIF1TX2MIX_INPUT_2_SOURCE: 654 case WM2200_AIF1TX2MIX_INPUT_2_VOLUME: 655 case WM2200_AIF1TX2MIX_INPUT_3_SOURCE: 656 case WM2200_AIF1TX2MIX_INPUT_3_VOLUME: 657 case WM2200_AIF1TX2MIX_INPUT_4_SOURCE: 658 case WM2200_AIF1TX2MIX_INPUT_4_VOLUME: 659 case WM2200_AIF1TX3MIX_INPUT_1_SOURCE: 660 case WM2200_AIF1TX3MIX_INPUT_1_VOLUME: 661 case WM2200_AIF1TX3MIX_INPUT_2_SOURCE: 662 case WM2200_AIF1TX3MIX_INPUT_2_VOLUME: 663 case WM2200_AIF1TX3MIX_INPUT_3_SOURCE: 664 case WM2200_AIF1TX3MIX_INPUT_3_VOLUME: 665 case WM2200_AIF1TX3MIX_INPUT_4_SOURCE: 666 case WM2200_AIF1TX3MIX_INPUT_4_VOLUME: 667 case WM2200_AIF1TX4MIX_INPUT_1_SOURCE: 668 case WM2200_AIF1TX4MIX_INPUT_1_VOLUME: 669 case WM2200_AIF1TX4MIX_INPUT_2_SOURCE: 670 case WM2200_AIF1TX4MIX_INPUT_2_VOLUME: 671 case WM2200_AIF1TX4MIX_INPUT_3_SOURCE: 672 case WM2200_AIF1TX4MIX_INPUT_3_VOLUME: 673 case WM2200_AIF1TX4MIX_INPUT_4_SOURCE: 674 case WM2200_AIF1TX4MIX_INPUT_4_VOLUME: 675 case WM2200_AIF1TX5MIX_INPUT_1_SOURCE: 676 case WM2200_AIF1TX5MIX_INPUT_1_VOLUME: 677 case WM2200_AIF1TX5MIX_INPUT_2_SOURCE: 678 case WM2200_AIF1TX5MIX_INPUT_2_VOLUME: 679 case WM2200_AIF1TX5MIX_INPUT_3_SOURCE: 680 case WM2200_AIF1TX5MIX_INPUT_3_VOLUME: 681 case WM2200_AIF1TX5MIX_INPUT_4_SOURCE: 682 case WM2200_AIF1TX5MIX_INPUT_4_VOLUME: 683 case WM2200_AIF1TX6MIX_INPUT_1_SOURCE: 684 case WM2200_AIF1TX6MIX_INPUT_1_VOLUME: 685 case WM2200_AIF1TX6MIX_INPUT_2_SOURCE: 686 case WM2200_AIF1TX6MIX_INPUT_2_VOLUME: 687 case WM2200_AIF1TX6MIX_INPUT_3_SOURCE: 688 case WM2200_AIF1TX6MIX_INPUT_3_VOLUME: 689 case WM2200_AIF1TX6MIX_INPUT_4_SOURCE: 690 case WM2200_AIF1TX6MIX_INPUT_4_VOLUME: 691 case WM2200_EQLMIX_INPUT_1_SOURCE: 692 case WM2200_EQLMIX_INPUT_1_VOLUME: 693 case WM2200_EQLMIX_INPUT_2_SOURCE: 694 case WM2200_EQLMIX_INPUT_2_VOLUME: 695 case WM2200_EQLMIX_INPUT_3_SOURCE: 696 case WM2200_EQLMIX_INPUT_3_VOLUME: 697 case WM2200_EQLMIX_INPUT_4_SOURCE: 698 case WM2200_EQLMIX_INPUT_4_VOLUME: 699 case WM2200_EQRMIX_INPUT_1_SOURCE: 700 case WM2200_EQRMIX_INPUT_1_VOLUME: 701 case WM2200_EQRMIX_INPUT_2_SOURCE: 702 case WM2200_EQRMIX_INPUT_2_VOLUME: 703 case WM2200_EQRMIX_INPUT_3_SOURCE: 704 case WM2200_EQRMIX_INPUT_3_VOLUME: 705 case WM2200_EQRMIX_INPUT_4_SOURCE: 706 case WM2200_EQRMIX_INPUT_4_VOLUME: 707 case WM2200_LHPF1MIX_INPUT_1_SOURCE: 708 case WM2200_LHPF1MIX_INPUT_1_VOLUME: 709 case WM2200_LHPF1MIX_INPUT_2_SOURCE: 710 case WM2200_LHPF1MIX_INPUT_2_VOLUME: 711 case WM2200_LHPF1MIX_INPUT_3_SOURCE: 712 case WM2200_LHPF1MIX_INPUT_3_VOLUME: 713 case WM2200_LHPF1MIX_INPUT_4_SOURCE: 714 case WM2200_LHPF1MIX_INPUT_4_VOLUME: 715 case WM2200_LHPF2MIX_INPUT_1_SOURCE: 716 case WM2200_LHPF2MIX_INPUT_1_VOLUME: 717 case WM2200_LHPF2MIX_INPUT_2_SOURCE: 718 case WM2200_LHPF2MIX_INPUT_2_VOLUME: 719 case WM2200_LHPF2MIX_INPUT_3_SOURCE: 720 case WM2200_LHPF2MIX_INPUT_3_VOLUME: 721 case WM2200_LHPF2MIX_INPUT_4_SOURCE: 722 case WM2200_LHPF2MIX_INPUT_4_VOLUME: 723 case WM2200_DSP1LMIX_INPUT_1_SOURCE: 724 case WM2200_DSP1LMIX_INPUT_1_VOLUME: 725 case WM2200_DSP1LMIX_INPUT_2_SOURCE: 726 case WM2200_DSP1LMIX_INPUT_2_VOLUME: 727 case WM2200_DSP1LMIX_INPUT_3_SOURCE: 728 case WM2200_DSP1LMIX_INPUT_3_VOLUME: 729 case WM2200_DSP1LMIX_INPUT_4_SOURCE: 730 case WM2200_DSP1LMIX_INPUT_4_VOLUME: 731 case WM2200_DSP1RMIX_INPUT_1_SOURCE: 732 case WM2200_DSP1RMIX_INPUT_1_VOLUME: 733 case WM2200_DSP1RMIX_INPUT_2_SOURCE: 734 case WM2200_DSP1RMIX_INPUT_2_VOLUME: 735 case WM2200_DSP1RMIX_INPUT_3_SOURCE: 736 case WM2200_DSP1RMIX_INPUT_3_VOLUME: 737 case WM2200_DSP1RMIX_INPUT_4_SOURCE: 738 case WM2200_DSP1RMIX_INPUT_4_VOLUME: 739 case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE: 740 case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE: 741 case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE: 742 case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE: 743 case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE: 744 case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE: 745 case WM2200_DSP2LMIX_INPUT_1_SOURCE: 746 case WM2200_DSP2LMIX_INPUT_1_VOLUME: 747 case WM2200_DSP2LMIX_INPUT_2_SOURCE: 748 case WM2200_DSP2LMIX_INPUT_2_VOLUME: 749 case WM2200_DSP2LMIX_INPUT_3_SOURCE: 750 case WM2200_DSP2LMIX_INPUT_3_VOLUME: 751 case WM2200_DSP2LMIX_INPUT_4_SOURCE: 752 case WM2200_DSP2LMIX_INPUT_4_VOLUME: 753 case WM2200_DSP2RMIX_INPUT_1_SOURCE: 754 case WM2200_DSP2RMIX_INPUT_1_VOLUME: 755 case WM2200_DSP2RMIX_INPUT_2_SOURCE: 756 case WM2200_DSP2RMIX_INPUT_2_VOLUME: 757 case WM2200_DSP2RMIX_INPUT_3_SOURCE: 758 case WM2200_DSP2RMIX_INPUT_3_VOLUME: 759 case WM2200_DSP2RMIX_INPUT_4_SOURCE: 760 case WM2200_DSP2RMIX_INPUT_4_VOLUME: 761 case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE: 762 case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE: 763 case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE: 764 case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE: 765 case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE: 766 case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE: 767 case WM2200_GPIO_CTRL_1: 768 case WM2200_GPIO_CTRL_2: 769 case WM2200_GPIO_CTRL_3: 770 case WM2200_GPIO_CTRL_4: 771 case WM2200_ADPS1_IRQ0: 772 case WM2200_ADPS1_IRQ1: 773 case WM2200_MISC_PAD_CTRL_1: 774 case WM2200_INTERRUPT_STATUS_1: 775 case WM2200_INTERRUPT_STATUS_1_MASK: 776 case WM2200_INTERRUPT_STATUS_2: 777 case WM2200_INTERRUPT_RAW_STATUS_2: 778 case WM2200_INTERRUPT_STATUS_2_MASK: 779 case WM2200_INTERRUPT_CONTROL: 780 case WM2200_EQL_1: 781 case WM2200_EQL_2: 782 case WM2200_EQL_3: 783 case WM2200_EQL_4: 784 case WM2200_EQL_5: 785 case WM2200_EQL_6: 786 case WM2200_EQL_7: 787 case WM2200_EQL_8: 788 case WM2200_EQL_9: 789 case WM2200_EQL_10: 790 case WM2200_EQL_11: 791 case WM2200_EQL_12: 792 case WM2200_EQL_13: 793 case WM2200_EQL_14: 794 case WM2200_EQL_15: 795 case WM2200_EQL_16: 796 case WM2200_EQL_17: 797 case WM2200_EQL_18: 798 case WM2200_EQL_19: 799 case WM2200_EQL_20: 800 case WM2200_EQR_1: 801 case WM2200_EQR_2: 802 case WM2200_EQR_3: 803 case WM2200_EQR_4: 804 case WM2200_EQR_5: 805 case WM2200_EQR_6: 806 case WM2200_EQR_7: 807 case WM2200_EQR_8: 808 case WM2200_EQR_9: 809 case WM2200_EQR_10: 810 case WM2200_EQR_11: 811 case WM2200_EQR_12: 812 case WM2200_EQR_13: 813 case WM2200_EQR_14: 814 case WM2200_EQR_15: 815 case WM2200_EQR_16: 816 case WM2200_EQR_17: 817 case WM2200_EQR_18: 818 case WM2200_EQR_19: 819 case WM2200_EQR_20: 820 case WM2200_HPLPF1_1: 821 case WM2200_HPLPF1_2: 822 case WM2200_HPLPF2_1: 823 case WM2200_HPLPF2_2: 824 case WM2200_DSP1_CONTROL_1: 825 case WM2200_DSP1_CONTROL_2: 826 case WM2200_DSP1_CONTROL_3: 827 case WM2200_DSP1_CONTROL_4: 828 case WM2200_DSP1_CONTROL_5: 829 case WM2200_DSP1_CONTROL_6: 830 case WM2200_DSP1_CONTROL_7: 831 case WM2200_DSP1_CONTROL_8: 832 case WM2200_DSP1_CONTROL_9: 833 case WM2200_DSP1_CONTROL_10: 834 case WM2200_DSP1_CONTROL_11: 835 case WM2200_DSP1_CONTROL_12: 836 case WM2200_DSP1_CONTROL_13: 837 case WM2200_DSP1_CONTROL_14: 838 case WM2200_DSP1_CONTROL_15: 839 case WM2200_DSP1_CONTROL_16: 840 case WM2200_DSP1_CONTROL_17: 841 case WM2200_DSP1_CONTROL_18: 842 case WM2200_DSP1_CONTROL_19: 843 case WM2200_DSP1_CONTROL_20: 844 case WM2200_DSP1_CONTROL_21: 845 case WM2200_DSP1_CONTROL_22: 846 case WM2200_DSP1_CONTROL_23: 847 case WM2200_DSP1_CONTROL_24: 848 case WM2200_DSP1_CONTROL_25: 849 case WM2200_DSP1_CONTROL_26: 850 case WM2200_DSP1_CONTROL_27: 851 case WM2200_DSP1_CONTROL_28: 852 case WM2200_DSP1_CONTROL_29: 853 case WM2200_DSP1_CONTROL_30: 854 case WM2200_DSP1_CONTROL_31: 855 case WM2200_DSP2_CONTROL_1: 856 case WM2200_DSP2_CONTROL_2: 857 case WM2200_DSP2_CONTROL_3: 858 case WM2200_DSP2_CONTROL_4: 859 case WM2200_DSP2_CONTROL_5: 860 case WM2200_DSP2_CONTROL_6: 861 case WM2200_DSP2_CONTROL_7: 862 case WM2200_DSP2_CONTROL_8: 863 case WM2200_DSP2_CONTROL_9: 864 case WM2200_DSP2_CONTROL_10: 865 case WM2200_DSP2_CONTROL_11: 866 case WM2200_DSP2_CONTROL_12: 867 case WM2200_DSP2_CONTROL_13: 868 case WM2200_DSP2_CONTROL_14: 869 case WM2200_DSP2_CONTROL_15: 870 case WM2200_DSP2_CONTROL_16: 871 case WM2200_DSP2_CONTROL_17: 872 case WM2200_DSP2_CONTROL_18: 873 case WM2200_DSP2_CONTROL_19: 874 case WM2200_DSP2_CONTROL_20: 875 case WM2200_DSP2_CONTROL_21: 876 case WM2200_DSP2_CONTROL_22: 877 case WM2200_DSP2_CONTROL_23: 878 case WM2200_DSP2_CONTROL_24: 879 case WM2200_DSP2_CONTROL_25: 880 case WM2200_DSP2_CONTROL_26: 881 case WM2200_DSP2_CONTROL_27: 882 case WM2200_DSP2_CONTROL_28: 883 case WM2200_DSP2_CONTROL_29: 884 case WM2200_DSP2_CONTROL_30: 885 case WM2200_DSP2_CONTROL_31: 886 return true; 887 default: 888 return false; 889 } 890 } 891 892 static const struct reg_sequence wm2200_reva_patch[] = { 893 { 0x07, 0x0003 }, 894 { 0x102, 0x0200 }, 895 { 0x203, 0x0084 }, 896 { 0x201, 0x83FF }, 897 { 0x20C, 0x0062 }, 898 { 0x20D, 0x0062 }, 899 { 0x207, 0x2002 }, 900 { 0x208, 0x20C0 }, 901 { 0x21D, 0x01C0 }, 902 { 0x50A, 0x0001 }, 903 { 0x50B, 0x0002 }, 904 { 0x50C, 0x0003 }, 905 { 0x50D, 0x0004 }, 906 { 0x50E, 0x0005 }, 907 { 0x510, 0x0001 }, 908 { 0x511, 0x0002 }, 909 { 0x512, 0x0003 }, 910 { 0x513, 0x0004 }, 911 { 0x514, 0x0005 }, 912 { 0x515, 0x0000 }, 913 { 0x201, 0x8084 }, 914 { 0x202, 0xBBDE }, 915 { 0x203, 0x00EC }, 916 { 0x500, 0x8000 }, 917 { 0x507, 0x1820 }, 918 { 0x508, 0x1820 }, 919 { 0x505, 0x0300 }, 920 { 0x506, 0x0300 }, 921 { 0x302, 0x2280 }, 922 { 0x303, 0x0080 }, 923 { 0x304, 0x2280 }, 924 { 0x305, 0x0080 }, 925 { 0x306, 0x2280 }, 926 { 0x307, 0x0080 }, 927 { 0x401, 0x0080 }, 928 { 0x402, 0x0080 }, 929 { 0x417, 0x3069 }, 930 { 0x900, 0x6318 }, 931 { 0x901, 0x6300 }, 932 { 0x902, 0x0FC8 }, 933 { 0x903, 0x03FE }, 934 { 0x904, 0x00E0 }, 935 { 0x905, 0x1EC4 }, 936 { 0x906, 0xF136 }, 937 { 0x907, 0x0409 }, 938 { 0x908, 0x04CC }, 939 { 0x909, 0x1C9B }, 940 { 0x90A, 0xF337 }, 941 { 0x90B, 0x040B }, 942 { 0x90C, 0x0CBB }, 943 { 0x90D, 0x16F8 }, 944 { 0x90E, 0xF7D9 }, 945 { 0x90F, 0x040A }, 946 { 0x910, 0x1F14 }, 947 { 0x911, 0x058C }, 948 { 0x912, 0x0563 }, 949 { 0x913, 0x4000 }, 950 { 0x916, 0x6318 }, 951 { 0x917, 0x6300 }, 952 { 0x918, 0x0FC8 }, 953 { 0x919, 0x03FE }, 954 { 0x91A, 0x00E0 }, 955 { 0x91B, 0x1EC4 }, 956 { 0x91C, 0xF136 }, 957 { 0x91D, 0x0409 }, 958 { 0x91E, 0x04CC }, 959 { 0x91F, 0x1C9B }, 960 { 0x920, 0xF337 }, 961 { 0x921, 0x040B }, 962 { 0x922, 0x0CBB }, 963 { 0x923, 0x16F8 }, 964 { 0x924, 0xF7D9 }, 965 { 0x925, 0x040A }, 966 { 0x926, 0x1F14 }, 967 { 0x927, 0x058C }, 968 { 0x928, 0x0563 }, 969 { 0x929, 0x4000 }, 970 { 0x709, 0x2000 }, 971 { 0x207, 0x200E }, 972 { 0x208, 0x20D4 }, 973 { 0x20A, 0x0080 }, 974 { 0x07, 0x0000 }, 975 }; 976 977 static int wm2200_reset(struct wm2200_priv *wm2200) 978 { 979 if (wm2200->pdata.reset) { 980 gpio_set_value_cansleep(wm2200->pdata.reset, 0); 981 gpio_set_value_cansleep(wm2200->pdata.reset, 1); 982 983 return 0; 984 } else { 985 return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET, 986 0x2200); 987 } 988 } 989 990 static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0); 991 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 992 static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); 993 994 static const char * const wm2200_mixer_texts[] = { 995 "None", 996 "Tone Generator", 997 "AEC Loopback", 998 "IN1L", 999 "IN1R", 1000 "IN2L", 1001 "IN2R", 1002 "IN3L", 1003 "IN3R", 1004 "AIF1RX1", 1005 "AIF1RX2", 1006 "AIF1RX3", 1007 "AIF1RX4", 1008 "AIF1RX5", 1009 "AIF1RX6", 1010 "EQL", 1011 "EQR", 1012 "LHPF1", 1013 "LHPF2", 1014 "DSP1.1", 1015 "DSP1.2", 1016 "DSP1.3", 1017 "DSP1.4", 1018 "DSP1.5", 1019 "DSP1.6", 1020 "DSP2.1", 1021 "DSP2.2", 1022 "DSP2.3", 1023 "DSP2.4", 1024 "DSP2.5", 1025 "DSP2.6", 1026 }; 1027 1028 static unsigned int wm2200_mixer_values[] = { 1029 0x00, 1030 0x04, /* Tone */ 1031 0x08, /* AEC */ 1032 0x10, /* Input */ 1033 0x11, 1034 0x12, 1035 0x13, 1036 0x14, 1037 0x15, 1038 0x20, /* AIF */ 1039 0x21, 1040 0x22, 1041 0x23, 1042 0x24, 1043 0x25, 1044 0x50, /* EQ */ 1045 0x51, 1046 0x60, /* LHPF1 */ 1047 0x61, /* LHPF2 */ 1048 0x68, /* DSP1 */ 1049 0x69, 1050 0x6a, 1051 0x6b, 1052 0x6c, 1053 0x6d, 1054 0x70, /* DSP2 */ 1055 0x71, 1056 0x72, 1057 0x73, 1058 0x74, 1059 0x75, 1060 }; 1061 1062 #define WM2200_MIXER_CONTROLS(name, base) \ 1063 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \ 1064 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ 1065 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \ 1066 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ 1067 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \ 1068 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ 1069 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \ 1070 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv) 1071 1072 #define WM2200_MUX_ENUM_DECL(name, reg) \ 1073 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ 1074 wm2200_mixer_texts, wm2200_mixer_values) 1075 1076 #define WM2200_MUX_CTL_DECL(name) \ 1077 const struct snd_kcontrol_new name##_mux = \ 1078 SOC_DAPM_ENUM("Route", name##_enum) 1079 1080 #define WM2200_MIXER_ENUMS(name, base_reg) \ 1081 static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ 1082 static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ 1083 static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ 1084 static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ 1085 static WM2200_MUX_CTL_DECL(name##_in1); \ 1086 static WM2200_MUX_CTL_DECL(name##_in2); \ 1087 static WM2200_MUX_CTL_DECL(name##_in3); \ 1088 static WM2200_MUX_CTL_DECL(name##_in4) 1089 1090 #define WM2200_DSP_ENUMS(name, base_reg) \ 1091 static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg); \ 1092 static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \ 1093 static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \ 1094 static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \ 1095 static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \ 1096 static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \ 1097 static WM2200_MUX_CTL_DECL(name##_aux1); \ 1098 static WM2200_MUX_CTL_DECL(name##_aux2); \ 1099 static WM2200_MUX_CTL_DECL(name##_aux3); \ 1100 static WM2200_MUX_CTL_DECL(name##_aux4); \ 1101 static WM2200_MUX_CTL_DECL(name##_aux5); \ 1102 static WM2200_MUX_CTL_DECL(name##_aux6); 1103 1104 static const char *wm2200_rxanc_input_sel_texts[] = { 1105 "None", "IN1", "IN2", "IN3", 1106 }; 1107 1108 static SOC_ENUM_SINGLE_DECL(wm2200_rxanc_input_sel, 1109 WM2200_RXANC_SRC, 1110 WM2200_IN_RXANC_SEL_SHIFT, 1111 wm2200_rxanc_input_sel_texts); 1112 1113 static const struct snd_kcontrol_new wm2200_snd_controls[] = { 1114 SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, 1115 WM2200_IN1_OSR_SHIFT, 1, 0), 1116 SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL, 1117 WM2200_IN2_OSR_SHIFT, 1, 0), 1118 SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL, 1119 WM2200_IN3_OSR_SHIFT, 1, 0), 1120 1121 SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL, 1122 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), 1123 SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL, 1124 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), 1125 SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL, 1126 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), 1127 1128 SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, 1129 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1), 1130 SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_2L, 1131 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1), 1132 SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_3L, 1133 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1), 1134 1135 SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L, 1136 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT, 1137 0xbf, 0, digital_tlv), 1138 SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L, 1139 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT, 1140 0xbf, 0, digital_tlv), 1141 SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L, 1142 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT, 1143 0xbf, 0, digital_tlv), 1144 1145 SND_SOC_BYTES_MASK("EQL Coefficients", WM2200_EQL_1, 20, WM2200_EQL_ENA), 1146 SND_SOC_BYTES_MASK("EQR Coefficients", WM2200_EQR_1, 20, WM2200_EQR_ENA), 1147 1148 SND_SOC_BYTES("LHPF1 Coefficients", WM2200_HPLPF1_2, 1), 1149 SND_SOC_BYTES("LHPF2 Coefficients", WM2200_HPLPF2_2, 1), 1150 1151 SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L, 1152 WM2200_OUT1_OSR_SHIFT, 1, 0), 1153 SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L, 1154 WM2200_OUT2_OSR_SHIFT, 1, 0), 1155 1156 SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L, 1157 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1), 1158 SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L, 1159 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0, 1160 digital_tlv), 1161 SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L, 1162 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT, 1163 0x46, 0, out_tlv), 1164 1165 SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L, 1166 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1), 1167 SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L, 1168 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0, 1169 digital_tlv), 1170 SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT, 1171 WM2200_SPK1R_MUTE_SHIFT, 1, 1), 1172 SOC_ENUM("RxANC Src", wm2200_rxanc_input_sel), 1173 1174 WM_ADSP_FW_CONTROL("DSP1", 0), 1175 WM_ADSP_FW_CONTROL("DSP2", 1), 1176 }; 1177 1178 WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE); 1179 WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE); 1180 WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE); 1181 WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE); 1182 1183 WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE); 1184 WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE); 1185 WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE); 1186 WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE); 1187 WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE); 1188 WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE); 1189 1190 WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE); 1191 WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE); 1192 1193 WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE); 1194 WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); 1195 WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); 1196 WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); 1197 1198 WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE); 1199 WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE); 1200 1201 WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); 1202 WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); 1203 1204 #define WM2200_MUX(name, ctrl) \ 1205 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) 1206 1207 #define WM2200_MIXER_WIDGETS(name, name_str) \ 1208 WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ 1209 WM2200_MUX(name_str " Input 2", &name##_in2_mux), \ 1210 WM2200_MUX(name_str " Input 3", &name##_in3_mux), \ 1211 WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ 1212 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) 1213 1214 #define WM2200_DSP_WIDGETS(name, name_str) \ 1215 WM2200_MIXER_WIDGETS(name##L, name_str "L"), \ 1216 WM2200_MIXER_WIDGETS(name##R, name_str "R"), \ 1217 WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \ 1218 WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \ 1219 WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \ 1220 WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \ 1221 WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \ 1222 WM2200_MUX(name_str " Aux 6", &name##_aux6_mux) 1223 1224 #define WM2200_MIXER_INPUT_ROUTES(name) \ 1225 { name, "Tone Generator", "Tone Generator" }, \ 1226 { name, "AEC Loopback", "AEC Loopback" }, \ 1227 { name, "IN1L", "IN1L PGA" }, \ 1228 { name, "IN1R", "IN1R PGA" }, \ 1229 { name, "IN2L", "IN2L PGA" }, \ 1230 { name, "IN2R", "IN2R PGA" }, \ 1231 { name, "IN3L", "IN3L PGA" }, \ 1232 { name, "IN3R", "IN3R PGA" }, \ 1233 { name, "DSP1.1", "DSP1" }, \ 1234 { name, "DSP1.2", "DSP1" }, \ 1235 { name, "DSP1.3", "DSP1" }, \ 1236 { name, "DSP1.4", "DSP1" }, \ 1237 { name, "DSP1.5", "DSP1" }, \ 1238 { name, "DSP1.6", "DSP1" }, \ 1239 { name, "DSP2.1", "DSP2" }, \ 1240 { name, "DSP2.2", "DSP2" }, \ 1241 { name, "DSP2.3", "DSP2" }, \ 1242 { name, "DSP2.4", "DSP2" }, \ 1243 { name, "DSP2.5", "DSP2" }, \ 1244 { name, "DSP2.6", "DSP2" }, \ 1245 { name, "AIF1RX1", "AIF1RX1" }, \ 1246 { name, "AIF1RX2", "AIF1RX2" }, \ 1247 { name, "AIF1RX3", "AIF1RX3" }, \ 1248 { name, "AIF1RX4", "AIF1RX4" }, \ 1249 { name, "AIF1RX5", "AIF1RX5" }, \ 1250 { name, "AIF1RX6", "AIF1RX6" }, \ 1251 { name, "EQL", "EQL" }, \ 1252 { name, "EQR", "EQR" }, \ 1253 { name, "LHPF1", "LHPF1" }, \ 1254 { name, "LHPF2", "LHPF2" } 1255 1256 #define WM2200_MIXER_ROUTES(widget, name) \ 1257 { widget, NULL, name " Mixer" }, \ 1258 { name " Mixer", NULL, name " Input 1" }, \ 1259 { name " Mixer", NULL, name " Input 2" }, \ 1260 { name " Mixer", NULL, name " Input 3" }, \ 1261 { name " Mixer", NULL, name " Input 4" }, \ 1262 WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \ 1263 WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \ 1264 WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ 1265 WM2200_MIXER_INPUT_ROUTES(name " Input 4") 1266 1267 #define WM2200_DSP_AUX_ROUTES(name) \ 1268 { name, NULL, name " Aux 1" }, \ 1269 { name, NULL, name " Aux 2" }, \ 1270 { name, NULL, name " Aux 3" }, \ 1271 { name, NULL, name " Aux 4" }, \ 1272 { name, NULL, name " Aux 5" }, \ 1273 { name, NULL, name " Aux 6" }, \ 1274 WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \ 1275 WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \ 1276 WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \ 1277 WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \ 1278 WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \ 1279 WM2200_MIXER_INPUT_ROUTES(name " Aux 6") 1280 1281 static const char *wm2200_aec_loopback_texts[] = { 1282 "OUT1L", "OUT1R", "OUT2L", "OUT2R", 1283 }; 1284 1285 static SOC_ENUM_SINGLE_DECL(wm2200_aec_loopback, 1286 WM2200_DAC_AEC_CONTROL_1, 1287 WM2200_AEC_LOOPBACK_SRC_SHIFT, 1288 wm2200_aec_loopback_texts); 1289 1290 static const struct snd_kcontrol_new wm2200_aec_loopback_mux = 1291 SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback); 1292 1293 static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { 1294 SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, 1295 NULL, 0), 1296 SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0, 1297 NULL, 0), 1298 SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0, 1299 NULL, 0), 1300 SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT, 1301 0, NULL, 0), 1302 SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT, 1303 0, NULL, 0), 1304 SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), 1305 SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0), 1306 1307 SND_SOC_DAPM_INPUT("IN1L"), 1308 SND_SOC_DAPM_INPUT("IN1R"), 1309 SND_SOC_DAPM_INPUT("IN2L"), 1310 SND_SOC_DAPM_INPUT("IN2R"), 1311 SND_SOC_DAPM_INPUT("IN3L"), 1312 SND_SOC_DAPM_INPUT("IN3R"), 1313 1314 SND_SOC_DAPM_SIGGEN("TONE"), 1315 SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1, 1316 WM2200_TONE_ENA_SHIFT, 0, NULL, 0), 1317 1318 SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0, 1319 NULL, 0), 1320 SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0, 1321 NULL, 0), 1322 SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0, 1323 NULL, 0), 1324 SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0, 1325 NULL, 0), 1326 SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0, 1327 NULL, 0), 1328 SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0, 1329 NULL, 0), 1330 1331 SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0, 1332 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0), 1333 SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1, 1334 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0), 1335 SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2, 1336 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0), 1337 SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3, 1338 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0), 1339 SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4, 1340 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0), 1341 SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5, 1342 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0), 1343 1344 SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0), 1345 SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0), 1346 1347 SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, 1348 NULL, 0), 1349 SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, 1350 NULL, 0), 1351 1352 WM_ADSP1("DSP1", 0), 1353 WM_ADSP1("DSP2", 1), 1354 1355 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, 1356 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), 1357 SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1, 1358 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0), 1359 SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2, 1360 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0), 1361 SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3, 1362 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0), 1363 SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, 1364 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0), 1365 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, 1366 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), 1367 1368 SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1, 1369 WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux), 1370 1371 SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, 1372 WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), 1373 SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, 1374 WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0), 1375 1376 SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1, 1377 WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0), 1378 SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1, 1379 WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0), 1380 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1, 1381 WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0), 1382 1383 SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1, 1384 WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0), 1385 SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1, 1386 WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0), 1387 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1, 1388 WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0), 1389 1390 SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2, 1391 WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0), 1392 SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2, 1393 WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0), 1394 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2, 1395 WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0), 1396 1397 SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2, 1398 WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0), 1399 SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2, 1400 WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0), 1401 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2, 1402 WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0), 1403 1404 SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT, 1405 0, NULL, 0), 1406 SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT, 1407 0, NULL, 0), 1408 1409 SND_SOC_DAPM_OUTPUT("EPOUTLN"), 1410 SND_SOC_DAPM_OUTPUT("EPOUTLP"), 1411 SND_SOC_DAPM_OUTPUT("EPOUTRN"), 1412 SND_SOC_DAPM_OUTPUT("EPOUTRP"), 1413 SND_SOC_DAPM_OUTPUT("SPK"), 1414 1415 WM2200_MIXER_WIDGETS(EQL, "EQL"), 1416 WM2200_MIXER_WIDGETS(EQR, "EQR"), 1417 1418 WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), 1419 WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), 1420 1421 WM2200_DSP_WIDGETS(DSP1, "DSP1"), 1422 WM2200_DSP_WIDGETS(DSP2, "DSP2"), 1423 1424 WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), 1425 WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), 1426 WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), 1427 WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), 1428 WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), 1429 WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), 1430 1431 WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"), 1432 WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"), 1433 WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"), 1434 WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"), 1435 }; 1436 1437 static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { 1438 /* Everything needs SYSCLK but only hook up things on the edge 1439 * of the chip */ 1440 { "IN1L", NULL, "SYSCLK" }, 1441 { "IN1R", NULL, "SYSCLK" }, 1442 { "IN2L", NULL, "SYSCLK" }, 1443 { "IN2R", NULL, "SYSCLK" }, 1444 { "IN3L", NULL, "SYSCLK" }, 1445 { "IN3R", NULL, "SYSCLK" }, 1446 { "OUT1L", NULL, "SYSCLK" }, 1447 { "OUT1R", NULL, "SYSCLK" }, 1448 { "OUT2L", NULL, "SYSCLK" }, 1449 { "OUT2R", NULL, "SYSCLK" }, 1450 { "AIF1RX1", NULL, "SYSCLK" }, 1451 { "AIF1RX2", NULL, "SYSCLK" }, 1452 { "AIF1RX3", NULL, "SYSCLK" }, 1453 { "AIF1RX4", NULL, "SYSCLK" }, 1454 { "AIF1RX5", NULL, "SYSCLK" }, 1455 { "AIF1RX6", NULL, "SYSCLK" }, 1456 { "AIF1TX1", NULL, "SYSCLK" }, 1457 { "AIF1TX2", NULL, "SYSCLK" }, 1458 { "AIF1TX3", NULL, "SYSCLK" }, 1459 { "AIF1TX4", NULL, "SYSCLK" }, 1460 { "AIF1TX5", NULL, "SYSCLK" }, 1461 { "AIF1TX6", NULL, "SYSCLK" }, 1462 1463 { "IN1L", NULL, "AVDD" }, 1464 { "IN1R", NULL, "AVDD" }, 1465 { "IN2L", NULL, "AVDD" }, 1466 { "IN2R", NULL, "AVDD" }, 1467 { "IN3L", NULL, "AVDD" }, 1468 { "IN3R", NULL, "AVDD" }, 1469 { "OUT1L", NULL, "AVDD" }, 1470 { "OUT1R", NULL, "AVDD" }, 1471 1472 { "IN1L PGA", NULL, "IN1L" }, 1473 { "IN1R PGA", NULL, "IN1R" }, 1474 { "IN2L PGA", NULL, "IN2L" }, 1475 { "IN2R PGA", NULL, "IN2R" }, 1476 { "IN3L PGA", NULL, "IN3L" }, 1477 { "IN3R PGA", NULL, "IN3R" }, 1478 1479 { "Tone Generator", NULL, "TONE" }, 1480 1481 { "CP2", NULL, "CPVDD" }, 1482 { "MICBIAS1", NULL, "CP2" }, 1483 { "MICBIAS2", NULL, "CP2" }, 1484 1485 { "CP1", NULL, "CPVDD" }, 1486 { "EPD_LN", NULL, "CP1" }, 1487 { "EPD_LP", NULL, "CP1" }, 1488 { "EPD_RN", NULL, "CP1" }, 1489 { "EPD_RP", NULL, "CP1" }, 1490 1491 { "EPD_LP", NULL, "OUT1L" }, 1492 { "EPD_OUTP_LP", NULL, "EPD_LP" }, 1493 { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" }, 1494 { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" }, 1495 1496 { "EPD_LN", NULL, "OUT1L" }, 1497 { "EPD_OUTP_LN", NULL, "EPD_LN" }, 1498 { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" }, 1499 { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" }, 1500 1501 { "EPD_RP", NULL, "OUT1R" }, 1502 { "EPD_OUTP_RP", NULL, "EPD_RP" }, 1503 { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" }, 1504 { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" }, 1505 1506 { "EPD_RN", NULL, "OUT1R" }, 1507 { "EPD_OUTP_RN", NULL, "EPD_RN" }, 1508 { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" }, 1509 { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" }, 1510 1511 { "SPK", NULL, "OUT2L" }, 1512 { "SPK", NULL, "OUT2R" }, 1513 1514 { "AEC Loopback", "OUT1L", "OUT1L" }, 1515 { "AEC Loopback", "OUT1R", "OUT1R" }, 1516 { "AEC Loopback", "OUT2L", "OUT2L" }, 1517 { "AEC Loopback", "OUT2R", "OUT2R" }, 1518 1519 WM2200_MIXER_ROUTES("DSP1", "DSP1L"), 1520 WM2200_MIXER_ROUTES("DSP1", "DSP1R"), 1521 WM2200_MIXER_ROUTES("DSP2", "DSP2L"), 1522 WM2200_MIXER_ROUTES("DSP2", "DSP2R"), 1523 1524 WM2200_DSP_AUX_ROUTES("DSP1"), 1525 WM2200_DSP_AUX_ROUTES("DSP2"), 1526 1527 WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), 1528 WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), 1529 WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), 1530 WM2200_MIXER_ROUTES("OUT2R", "OUT2R"), 1531 1532 WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), 1533 WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), 1534 WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), 1535 WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), 1536 WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), 1537 WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), 1538 1539 WM2200_MIXER_ROUTES("EQL", "EQL"), 1540 WM2200_MIXER_ROUTES("EQR", "EQR"), 1541 1542 WM2200_MIXER_ROUTES("LHPF1", "LHPF1"), 1543 WM2200_MIXER_ROUTES("LHPF2", "LHPF2"), 1544 }; 1545 1546 static int wm2200_probe(struct snd_soc_component *component) 1547 { 1548 struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component); 1549 1550 wm2200->component = component; 1551 1552 return 0; 1553 } 1554 1555 static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1556 { 1557 struct snd_soc_component *component = dai->component; 1558 int lrclk, bclk, fmt_val; 1559 1560 lrclk = 0; 1561 bclk = 0; 1562 1563 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1564 case SND_SOC_DAIFMT_DSP_A: 1565 fmt_val = 0; 1566 break; 1567 case SND_SOC_DAIFMT_I2S: 1568 fmt_val = 2; 1569 break; 1570 default: 1571 dev_err(component->dev, "Unsupported DAI format %d\n", 1572 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 1573 return -EINVAL; 1574 } 1575 1576 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1577 case SND_SOC_DAIFMT_CBS_CFS: 1578 break; 1579 case SND_SOC_DAIFMT_CBS_CFM: 1580 lrclk |= WM2200_AIF1TX_LRCLK_MSTR; 1581 break; 1582 case SND_SOC_DAIFMT_CBM_CFS: 1583 bclk |= WM2200_AIF1_BCLK_MSTR; 1584 break; 1585 case SND_SOC_DAIFMT_CBM_CFM: 1586 lrclk |= WM2200_AIF1TX_LRCLK_MSTR; 1587 bclk |= WM2200_AIF1_BCLK_MSTR; 1588 break; 1589 default: 1590 dev_err(component->dev, "Unsupported master mode %d\n", 1591 fmt & SND_SOC_DAIFMT_MASTER_MASK); 1592 return -EINVAL; 1593 } 1594 1595 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1596 case SND_SOC_DAIFMT_NB_NF: 1597 break; 1598 case SND_SOC_DAIFMT_IB_IF: 1599 bclk |= WM2200_AIF1_BCLK_INV; 1600 lrclk |= WM2200_AIF1TX_LRCLK_INV; 1601 break; 1602 case SND_SOC_DAIFMT_IB_NF: 1603 bclk |= WM2200_AIF1_BCLK_INV; 1604 break; 1605 case SND_SOC_DAIFMT_NB_IF: 1606 lrclk |= WM2200_AIF1TX_LRCLK_INV; 1607 break; 1608 default: 1609 return -EINVAL; 1610 } 1611 1612 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR | 1613 WM2200_AIF1_BCLK_INV, bclk); 1614 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2, 1615 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, 1616 lrclk); 1617 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_3, 1618 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, 1619 lrclk); 1620 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_5, 1621 WM2200_AIF1_FMT_MASK, fmt_val); 1622 1623 return 0; 1624 } 1625 1626 static int wm2200_sr_code[] = { 1627 0, 1628 12000, 1629 24000, 1630 48000, 1631 96000, 1632 192000, 1633 384000, 1634 768000, 1635 0, 1636 11025, 1637 22050, 1638 44100, 1639 88200, 1640 176400, 1641 352800, 1642 705600, 1643 4000, 1644 8000, 1645 16000, 1646 32000, 1647 64000, 1648 128000, 1649 256000, 1650 512000, 1651 }; 1652 1653 #define WM2200_NUM_BCLK_RATES 12 1654 1655 static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { 1656 6144000, 1657 3072000, 1658 2048000, 1659 1536000, 1660 768000, 1661 512000, 1662 384000, 1663 256000, 1664 192000, 1665 128000, 1666 96000, 1667 64000, 1668 }; 1669 1670 static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { 1671 5644800, 1672 3763200, 1673 2882400, 1674 1881600, 1675 1411200, 1676 705600, 1677 470400, 1678 352800, 1679 176400, 1680 117600, 1681 88200, 1682 58800, 1683 }; 1684 1685 static int wm2200_hw_params(struct snd_pcm_substream *substream, 1686 struct snd_pcm_hw_params *params, 1687 struct snd_soc_dai *dai) 1688 { 1689 struct snd_soc_component *component = dai->component; 1690 struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component); 1691 int i, bclk, lrclk, wl, fl, sr_code; 1692 int *bclk_rates; 1693 1694 /* Data sizes if not using TDM */ 1695 wl = params_width(params); 1696 if (wl < 0) 1697 return wl; 1698 fl = snd_soc_params_to_frame_size(params); 1699 if (fl < 0) 1700 return fl; 1701 1702 dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n", 1703 wl, fl); 1704 1705 /* Target BCLK rate */ 1706 bclk = snd_soc_params_to_bclk(params); 1707 if (bclk < 0) 1708 return bclk; 1709 1710 if (!wm2200->sysclk) { 1711 dev_err(component->dev, "SYSCLK has no rate set\n"); 1712 return -EINVAL; 1713 } 1714 1715 for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++) 1716 if (wm2200_sr_code[i] == params_rate(params)) 1717 break; 1718 if (i == ARRAY_SIZE(wm2200_sr_code)) { 1719 dev_err(component->dev, "Unsupported sample rate: %dHz\n", 1720 params_rate(params)); 1721 return -EINVAL; 1722 } 1723 sr_code = i; 1724 1725 dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n", 1726 bclk, wm2200->sysclk); 1727 1728 if (wm2200->sysclk % 4000) 1729 bclk_rates = wm2200_bclk_rates_cd; 1730 else 1731 bclk_rates = wm2200_bclk_rates_dat; 1732 1733 for (i = 0; i < WM2200_NUM_BCLK_RATES; i++) 1734 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0)) 1735 break; 1736 if (i == WM2200_NUM_BCLK_RATES) { 1737 dev_err(component->dev, 1738 "No valid BCLK for %dHz found from %dHz SYSCLK\n", 1739 bclk, wm2200->sysclk); 1740 return -EINVAL; 1741 } 1742 1743 bclk = i; 1744 dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]); 1745 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1, 1746 WM2200_AIF1_BCLK_DIV_MASK, bclk); 1747 1748 lrclk = bclk_rates[bclk] / params_rate(params); 1749 dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); 1750 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || 1751 wm2200->symmetric_rates) 1752 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_7, 1753 WM2200_AIF1RX_BCPF_MASK, lrclk); 1754 else 1755 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_6, 1756 WM2200_AIF1TX_BCPF_MASK, lrclk); 1757 1758 i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl; 1759 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1760 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_9, 1761 WM2200_AIF1RX_WL_MASK | 1762 WM2200_AIF1RX_SLOT_LEN_MASK, i); 1763 else 1764 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_8, 1765 WM2200_AIF1TX_WL_MASK | 1766 WM2200_AIF1TX_SLOT_LEN_MASK, i); 1767 1768 snd_soc_component_update_bits(component, WM2200_CLOCKING_4, 1769 WM2200_SAMPLE_RATE_1_MASK, sr_code); 1770 1771 return 0; 1772 } 1773 1774 static const struct snd_soc_dai_ops wm2200_dai_ops = { 1775 .set_fmt = wm2200_set_fmt, 1776 .hw_params = wm2200_hw_params, 1777 }; 1778 1779 static int wm2200_set_sysclk(struct snd_soc_component *component, int clk_id, 1780 int source, unsigned int freq, int dir) 1781 { 1782 struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component); 1783 int fval; 1784 1785 switch (clk_id) { 1786 case WM2200_CLK_SYSCLK: 1787 break; 1788 1789 default: 1790 dev_err(component->dev, "Unknown clock %d\n", clk_id); 1791 return -EINVAL; 1792 } 1793 1794 switch (source) { 1795 case WM2200_CLKSRC_MCLK1: 1796 case WM2200_CLKSRC_MCLK2: 1797 case WM2200_CLKSRC_FLL: 1798 case WM2200_CLKSRC_BCLK1: 1799 break; 1800 default: 1801 dev_err(component->dev, "Invalid source %d\n", source); 1802 return -EINVAL; 1803 } 1804 1805 switch (freq) { 1806 case 22579200: 1807 case 24576000: 1808 fval = 2; 1809 break; 1810 default: 1811 dev_err(component->dev, "Invalid clock rate: %d\n", freq); 1812 return -EINVAL; 1813 } 1814 1815 /* TODO: Check if MCLKs are in use and enable/disable pulls to 1816 * match. 1817 */ 1818 1819 snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK | 1820 WM2200_SYSCLK_SRC_MASK, 1821 fval << WM2200_SYSCLK_FREQ_SHIFT | source); 1822 1823 wm2200->sysclk = freq; 1824 1825 return 0; 1826 } 1827 1828 struct _fll_div { 1829 u16 fll_fratio; 1830 u16 fll_outdiv; 1831 u16 fll_refclk_div; 1832 u16 n; 1833 u16 theta; 1834 u16 lambda; 1835 }; 1836 1837 static struct { 1838 unsigned int min; 1839 unsigned int max; 1840 u16 fll_fratio; 1841 int ratio; 1842 } fll_fratios[] = { 1843 { 0, 64000, 4, 16 }, 1844 { 64000, 128000, 3, 8 }, 1845 { 128000, 256000, 2, 4 }, 1846 { 256000, 1000000, 1, 2 }, 1847 { 1000000, 13500000, 0, 1 }, 1848 }; 1849 1850 static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, 1851 unsigned int Fout) 1852 { 1853 unsigned int target; 1854 unsigned int div; 1855 unsigned int fratio, gcd_fll; 1856 int i; 1857 1858 /* Fref must be <=13.5MHz */ 1859 div = 1; 1860 fll_div->fll_refclk_div = 0; 1861 while ((Fref / div) > 13500000) { 1862 div *= 2; 1863 fll_div->fll_refclk_div++; 1864 1865 if (div > 8) { 1866 pr_err("Can't scale %dMHz input down to <=13.5MHz\n", 1867 Fref); 1868 return -EINVAL; 1869 } 1870 } 1871 1872 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); 1873 1874 /* Apply the division for our remaining calculations */ 1875 Fref /= div; 1876 1877 /* Fvco should be 90-100MHz; don't check the upper bound */ 1878 div = 2; 1879 while (Fout * div < 90000000) { 1880 div++; 1881 if (div > 64) { 1882 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", 1883 Fout); 1884 return -EINVAL; 1885 } 1886 } 1887 target = Fout * div; 1888 fll_div->fll_outdiv = div - 1; 1889 1890 pr_debug("FLL Fvco=%dHz\n", target); 1891 1892 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1893 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1894 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1895 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 1896 fratio = fll_fratios[i].ratio; 1897 break; 1898 } 1899 } 1900 if (i == ARRAY_SIZE(fll_fratios)) { 1901 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); 1902 return -EINVAL; 1903 } 1904 1905 fll_div->n = target / (fratio * Fref); 1906 1907 if (target % Fref == 0) { 1908 fll_div->theta = 0; 1909 fll_div->lambda = 0; 1910 } else { 1911 gcd_fll = gcd(target, fratio * Fref); 1912 1913 fll_div->theta = (target - (fll_div->n * fratio * Fref)) 1914 / gcd_fll; 1915 fll_div->lambda = (fratio * Fref) / gcd_fll; 1916 } 1917 1918 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", 1919 fll_div->n, fll_div->theta, fll_div->lambda); 1920 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", 1921 fll_div->fll_fratio, fratio, fll_div->fll_outdiv, 1922 fll_div->fll_refclk_div); 1923 1924 return 0; 1925 } 1926 1927 static int wm2200_set_fll(struct snd_soc_component *component, int fll_id, int source, 1928 unsigned int Fref, unsigned int Fout) 1929 { 1930 struct i2c_client *i2c = to_i2c_client(component->dev); 1931 struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component); 1932 struct _fll_div factors; 1933 int ret, i, timeout; 1934 unsigned long time_left; 1935 1936 if (!Fout) { 1937 dev_dbg(component->dev, "FLL disabled"); 1938 1939 if (wm2200->fll_fout) 1940 pm_runtime_put(component->dev); 1941 1942 wm2200->fll_fout = 0; 1943 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, 1944 WM2200_FLL_ENA, 0); 1945 return 0; 1946 } 1947 1948 switch (source) { 1949 case WM2200_FLL_SRC_MCLK1: 1950 case WM2200_FLL_SRC_MCLK2: 1951 case WM2200_FLL_SRC_BCLK: 1952 break; 1953 default: 1954 dev_err(component->dev, "Invalid FLL source %d\n", source); 1955 return -EINVAL; 1956 } 1957 1958 ret = fll_factors(&factors, Fref, Fout); 1959 if (ret < 0) 1960 return ret; 1961 1962 /* Disable the FLL while we reconfigure */ 1963 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0); 1964 1965 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_2, 1966 WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK, 1967 (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) | 1968 factors.fll_fratio); 1969 if (factors.theta) { 1970 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3, 1971 WM2200_FLL_FRACN_ENA, 1972 WM2200_FLL_FRACN_ENA); 1973 snd_soc_component_update_bits(component, WM2200_FLL_EFS_2, 1974 WM2200_FLL_EFS_ENA, 1975 WM2200_FLL_EFS_ENA); 1976 } else { 1977 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3, 1978 WM2200_FLL_FRACN_ENA, 0); 1979 snd_soc_component_update_bits(component, WM2200_FLL_EFS_2, 1980 WM2200_FLL_EFS_ENA, 0); 1981 } 1982 1983 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK, 1984 factors.theta); 1985 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK, 1986 factors.n); 1987 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_7, 1988 WM2200_FLL_CLK_REF_DIV_MASK | 1989 WM2200_FLL_CLK_REF_SRC_MASK, 1990 (factors.fll_refclk_div 1991 << WM2200_FLL_CLK_REF_DIV_SHIFT) | source); 1992 snd_soc_component_update_bits(component, WM2200_FLL_EFS_1, 1993 WM2200_FLL_LAMBDA_MASK, factors.lambda); 1994 1995 /* Clear any pending completions */ 1996 try_wait_for_completion(&wm2200->fll_lock); 1997 1998 pm_runtime_get_sync(component->dev); 1999 2000 snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, 2001 WM2200_FLL_ENA, WM2200_FLL_ENA); 2002 2003 if (i2c->irq) 2004 timeout = 2; 2005 else 2006 timeout = 50; 2007 2008 snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA, 2009 WM2200_SYSCLK_ENA); 2010 2011 /* Poll for the lock; will use the interrupt to exit quickly */ 2012 for (i = 0; i < timeout; i++) { 2013 if (i2c->irq) { 2014 time_left = wait_for_completion_timeout( 2015 &wm2200->fll_lock, 2016 msecs_to_jiffies(25)); 2017 if (time_left > 0) 2018 break; 2019 } else { 2020 msleep(1); 2021 } 2022 2023 ret = snd_soc_component_read(component, 2024 WM2200_INTERRUPT_RAW_STATUS_2); 2025 if (ret < 0) { 2026 dev_err(component->dev, 2027 "Failed to read FLL status: %d\n", 2028 ret); 2029 continue; 2030 } 2031 if (ret & WM2200_FLL_LOCK_STS) 2032 break; 2033 } 2034 if (i == timeout) { 2035 dev_err(component->dev, "FLL lock timed out\n"); 2036 pm_runtime_put(component->dev); 2037 return -ETIMEDOUT; 2038 } 2039 2040 wm2200->fll_src = source; 2041 wm2200->fll_fref = Fref; 2042 wm2200->fll_fout = Fout; 2043 2044 dev_dbg(component->dev, "FLL running %dHz->%dHz\n", Fref, Fout); 2045 2046 return 0; 2047 } 2048 2049 static int wm2200_dai_probe(struct snd_soc_dai *dai) 2050 { 2051 struct snd_soc_component *component = dai->component; 2052 struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component); 2053 unsigned int val = 0; 2054 int ret; 2055 2056 ret = snd_soc_component_read(component, WM2200_GPIO_CTRL_1); 2057 if (ret >= 0) { 2058 if ((ret & WM2200_GP1_FN_MASK) != 0) { 2059 wm2200->symmetric_rates = true; 2060 val = WM2200_AIF1TX_LRCLK_SRC; 2061 } 2062 } else { 2063 dev_err(component->dev, "Failed to read GPIO 1 config: %d\n", ret); 2064 } 2065 2066 snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2, 2067 WM2200_AIF1TX_LRCLK_SRC, val); 2068 2069 return 0; 2070 } 2071 2072 #define WM2200_RATES SNDRV_PCM_RATE_8000_48000 2073 2074 #define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2075 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 2076 2077 static struct snd_soc_dai_driver wm2200_dai = { 2078 .name = "wm2200", 2079 .probe = wm2200_dai_probe, 2080 .playback = { 2081 .stream_name = "Playback", 2082 .channels_min = 2, 2083 .channels_max = 2, 2084 .rates = WM2200_RATES, 2085 .formats = WM2200_FORMATS, 2086 }, 2087 .capture = { 2088 .stream_name = "Capture", 2089 .channels_min = 2, 2090 .channels_max = 2, 2091 .rates = WM2200_RATES, 2092 .formats = WM2200_FORMATS, 2093 }, 2094 .ops = &wm2200_dai_ops, 2095 }; 2096 2097 static const struct snd_soc_component_driver soc_component_wm2200 = { 2098 .probe = wm2200_probe, 2099 .set_sysclk = wm2200_set_sysclk, 2100 .set_pll = wm2200_set_fll, 2101 .controls = wm2200_snd_controls, 2102 .num_controls = ARRAY_SIZE(wm2200_snd_controls), 2103 .dapm_widgets = wm2200_dapm_widgets, 2104 .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), 2105 .dapm_routes = wm2200_dapm_routes, 2106 .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), 2107 .endianness = 1, 2108 .non_legacy_dai_naming = 1, 2109 }; 2110 2111 static irqreturn_t wm2200_irq(int irq, void *data) 2112 { 2113 struct wm2200_priv *wm2200 = data; 2114 unsigned int val, mask; 2115 int ret; 2116 2117 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val); 2118 if (ret != 0) { 2119 dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret); 2120 return IRQ_NONE; 2121 } 2122 2123 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK, 2124 &mask); 2125 if (ret != 0) { 2126 dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret); 2127 mask = 0; 2128 } 2129 2130 val &= ~mask; 2131 2132 if (val & WM2200_FLL_LOCK_EINT) { 2133 dev_dbg(wm2200->dev, "FLL locked\n"); 2134 complete(&wm2200->fll_lock); 2135 } 2136 2137 if (val) { 2138 regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val); 2139 2140 return IRQ_HANDLED; 2141 } else { 2142 return IRQ_NONE; 2143 } 2144 } 2145 2146 static const struct regmap_config wm2200_regmap = { 2147 .reg_bits = 16, 2148 .val_bits = 16, 2149 2150 .max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) * 2151 WM2200_DSP_SPACING), 2152 .reg_defaults = wm2200_reg_defaults, 2153 .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), 2154 .volatile_reg = wm2200_volatile_register, 2155 .readable_reg = wm2200_readable_register, 2156 .cache_type = REGCACHE_RBTREE, 2157 .ranges = wm2200_ranges, 2158 .num_ranges = ARRAY_SIZE(wm2200_ranges), 2159 }; 2160 2161 static const unsigned int wm2200_dig_vu[] = { 2162 WM2200_DAC_DIGITAL_VOLUME_1L, 2163 WM2200_DAC_DIGITAL_VOLUME_1R, 2164 WM2200_DAC_DIGITAL_VOLUME_2L, 2165 WM2200_DAC_DIGITAL_VOLUME_2R, 2166 WM2200_ADC_DIGITAL_VOLUME_1L, 2167 WM2200_ADC_DIGITAL_VOLUME_1R, 2168 WM2200_ADC_DIGITAL_VOLUME_2L, 2169 WM2200_ADC_DIGITAL_VOLUME_2R, 2170 WM2200_ADC_DIGITAL_VOLUME_3L, 2171 WM2200_ADC_DIGITAL_VOLUME_3R, 2172 }; 2173 2174 static const unsigned int wm2200_mic_ctrl_reg[] = { 2175 WM2200_IN1L_CONTROL, 2176 WM2200_IN2L_CONTROL, 2177 WM2200_IN3L_CONTROL, 2178 }; 2179 2180 static int wm2200_i2c_probe(struct i2c_client *i2c, 2181 const struct i2c_device_id *id) 2182 { 2183 struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev); 2184 struct wm2200_priv *wm2200; 2185 unsigned int reg; 2186 int ret, i; 2187 int val; 2188 2189 wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv), 2190 GFP_KERNEL); 2191 if (wm2200 == NULL) 2192 return -ENOMEM; 2193 2194 wm2200->dev = &i2c->dev; 2195 init_completion(&wm2200->fll_lock); 2196 2197 wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap); 2198 if (IS_ERR(wm2200->regmap)) { 2199 ret = PTR_ERR(wm2200->regmap); 2200 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2201 ret); 2202 return ret; 2203 } 2204 2205 for (i = 0; i < 2; i++) { 2206 wm2200->dsp[i].type = WMFW_ADSP1; 2207 wm2200->dsp[i].part = "wm2200"; 2208 wm2200->dsp[i].num = i + 1; 2209 wm2200->dsp[i].dev = &i2c->dev; 2210 wm2200->dsp[i].regmap = wm2200->regmap; 2211 wm2200->dsp[i].sysclk_reg = WM2200_CLOCKING_3; 2212 wm2200->dsp[i].sysclk_mask = WM2200_SYSCLK_FREQ_MASK; 2213 wm2200->dsp[i].sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT; 2214 } 2215 2216 wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; 2217 wm2200->dsp[0].mem = wm2200_dsp1_regions; 2218 wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); 2219 2220 wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; 2221 wm2200->dsp[1].mem = wm2200_dsp2_regions; 2222 wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); 2223 2224 for (i = 0; i < ARRAY_SIZE(wm2200->dsp); i++) 2225 wm_adsp1_init(&wm2200->dsp[i]); 2226 2227 if (pdata) 2228 wm2200->pdata = *pdata; 2229 2230 i2c_set_clientdata(i2c, wm2200); 2231 2232 for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) 2233 wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; 2234 2235 ret = devm_regulator_bulk_get(&i2c->dev, 2236 ARRAY_SIZE(wm2200->core_supplies), 2237 wm2200->core_supplies); 2238 if (ret != 0) { 2239 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", 2240 ret); 2241 return ret; 2242 } 2243 2244 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), 2245 wm2200->core_supplies); 2246 if (ret != 0) { 2247 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", 2248 ret); 2249 return ret; 2250 } 2251 2252 if (wm2200->pdata.ldo_ena) { 2253 ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena, 2254 GPIOF_OUT_INIT_HIGH, 2255 "WM2200 LDOENA"); 2256 if (ret < 0) { 2257 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", 2258 wm2200->pdata.ldo_ena, ret); 2259 goto err_enable; 2260 } 2261 msleep(2); 2262 } 2263 2264 if (wm2200->pdata.reset) { 2265 ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset, 2266 GPIOF_OUT_INIT_HIGH, 2267 "WM2200 /RESET"); 2268 if (ret < 0) { 2269 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", 2270 wm2200->pdata.reset, ret); 2271 goto err_ldo; 2272 } 2273 } 2274 2275 ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, ®); 2276 if (ret < 0) { 2277 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); 2278 goto err_reset; 2279 } 2280 switch (reg) { 2281 case 0x2200: 2282 break; 2283 2284 default: 2285 dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg); 2286 ret = -EINVAL; 2287 goto err_reset; 2288 } 2289 2290 ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, ®); 2291 if (ret < 0) { 2292 dev_err(&i2c->dev, "Failed to read revision register\n"); 2293 goto err_reset; 2294 } 2295 2296 wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK; 2297 2298 dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A'); 2299 2300 switch (wm2200->rev) { 2301 case 0: 2302 case 1: 2303 ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch, 2304 ARRAY_SIZE(wm2200_reva_patch)); 2305 if (ret != 0) { 2306 dev_err(&i2c->dev, "Failed to register patch: %d\n", 2307 ret); 2308 } 2309 break; 2310 default: 2311 break; 2312 } 2313 2314 ret = wm2200_reset(wm2200); 2315 if (ret < 0) { 2316 dev_err(&i2c->dev, "Failed to issue reset\n"); 2317 goto err_reset; 2318 } 2319 2320 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) { 2321 if (!wm2200->pdata.gpio_defaults[i]) 2322 continue; 2323 2324 regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i, 2325 wm2200->pdata.gpio_defaults[i]); 2326 } 2327 2328 for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++) 2329 regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i], 2330 WM2200_OUT_VU, WM2200_OUT_VU); 2331 2332 /* Assign slots 1-6 to channels 1-6 for both TX and RX */ 2333 for (i = 0; i < 6; i++) { 2334 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i); 2335 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i); 2336 } 2337 2338 for (i = 0; i < WM2200_MAX_MICBIAS; i++) { 2339 if (!wm2200->pdata.micbias[i].mb_lvl && 2340 !wm2200->pdata.micbias[i].bypass) 2341 continue; 2342 2343 /* Apply default for bypass mode */ 2344 if (!wm2200->pdata.micbias[i].mb_lvl) 2345 wm2200->pdata.micbias[i].mb_lvl 2346 = WM2200_MBIAS_LVL_1V5; 2347 2348 val = (wm2200->pdata.micbias[i].mb_lvl -1) 2349 << WM2200_MICB1_LVL_SHIFT; 2350 2351 if (wm2200->pdata.micbias[i].discharge) 2352 val |= WM2200_MICB1_DISCH; 2353 2354 if (wm2200->pdata.micbias[i].fast_start) 2355 val |= WM2200_MICB1_RATE; 2356 2357 if (wm2200->pdata.micbias[i].bypass) 2358 val |= WM2200_MICB1_MODE; 2359 2360 regmap_update_bits(wm2200->regmap, 2361 WM2200_MIC_BIAS_CTRL_1 + i, 2362 WM2200_MICB1_LVL_MASK | 2363 WM2200_MICB1_DISCH | 2364 WM2200_MICB1_MODE | 2365 WM2200_MICB1_RATE, val); 2366 } 2367 2368 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) { 2369 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i], 2370 WM2200_IN1_MODE_MASK | 2371 WM2200_IN1_DMIC_SUP_MASK, 2372 (wm2200->pdata.in_mode[i] << 2373 WM2200_IN1_MODE_SHIFT) | 2374 (wm2200->pdata.dmic_sup[i] << 2375 WM2200_IN1_DMIC_SUP_SHIFT)); 2376 } 2377 2378 if (i2c->irq) { 2379 ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq, 2380 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 2381 "wm2200", wm2200); 2382 if (ret == 0) 2383 regmap_update_bits(wm2200->regmap, 2384 WM2200_INTERRUPT_STATUS_2_MASK, 2385 WM2200_FLL_LOCK_EINT, 0); 2386 else 2387 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", 2388 i2c->irq, ret); 2389 } 2390 2391 pm_runtime_set_active(&i2c->dev); 2392 pm_runtime_enable(&i2c->dev); 2393 pm_request_idle(&i2c->dev); 2394 2395 ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_wm2200, 2396 &wm2200_dai, 1); 2397 if (ret != 0) { 2398 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); 2399 goto err_pm_runtime; 2400 } 2401 2402 return 0; 2403 2404 err_pm_runtime: 2405 pm_runtime_disable(&i2c->dev); 2406 if (i2c->irq) 2407 free_irq(i2c->irq, wm2200); 2408 err_reset: 2409 if (wm2200->pdata.reset) 2410 gpio_set_value_cansleep(wm2200->pdata.reset, 0); 2411 err_ldo: 2412 if (wm2200->pdata.ldo_ena) 2413 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); 2414 err_enable: 2415 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), 2416 wm2200->core_supplies); 2417 return ret; 2418 } 2419 2420 static int wm2200_i2c_remove(struct i2c_client *i2c) 2421 { 2422 struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c); 2423 2424 pm_runtime_disable(&i2c->dev); 2425 if (i2c->irq) 2426 free_irq(i2c->irq, wm2200); 2427 if (wm2200->pdata.reset) 2428 gpio_set_value_cansleep(wm2200->pdata.reset, 0); 2429 if (wm2200->pdata.ldo_ena) 2430 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); 2431 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), 2432 wm2200->core_supplies); 2433 2434 return 0; 2435 } 2436 2437 #ifdef CONFIG_PM 2438 static int wm2200_runtime_suspend(struct device *dev) 2439 { 2440 struct wm2200_priv *wm2200 = dev_get_drvdata(dev); 2441 2442 regcache_cache_only(wm2200->regmap, true); 2443 regcache_mark_dirty(wm2200->regmap); 2444 if (wm2200->pdata.ldo_ena) 2445 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); 2446 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), 2447 wm2200->core_supplies); 2448 2449 return 0; 2450 } 2451 2452 static int wm2200_runtime_resume(struct device *dev) 2453 { 2454 struct wm2200_priv *wm2200 = dev_get_drvdata(dev); 2455 int ret; 2456 2457 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), 2458 wm2200->core_supplies); 2459 if (ret != 0) { 2460 dev_err(dev, "Failed to enable supplies: %d\n", 2461 ret); 2462 return ret; 2463 } 2464 2465 if (wm2200->pdata.ldo_ena) { 2466 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1); 2467 msleep(2); 2468 } 2469 2470 regcache_cache_only(wm2200->regmap, false); 2471 regcache_sync(wm2200->regmap); 2472 2473 return 0; 2474 } 2475 #endif 2476 2477 static const struct dev_pm_ops wm2200_pm = { 2478 SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume, 2479 NULL) 2480 }; 2481 2482 static const struct i2c_device_id wm2200_i2c_id[] = { 2483 { "wm2200", 0 }, 2484 { } 2485 }; 2486 MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id); 2487 2488 static struct i2c_driver wm2200_i2c_driver = { 2489 .driver = { 2490 .name = "wm2200", 2491 .pm = &wm2200_pm, 2492 }, 2493 .probe = wm2200_i2c_probe, 2494 .remove = wm2200_i2c_remove, 2495 .id_table = wm2200_i2c_id, 2496 }; 2497 2498 module_i2c_driver(wm2200_i2c_driver); 2499 2500 MODULE_DESCRIPTION("ASoC WM2200 driver"); 2501 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2502 MODULE_LICENSE("GPL"); 2503