1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | // |
3 | // sma1303.c -- sma1303 ALSA SoC Audio driver |
4 | // |
5 | // Copyright 2023 Iron Device Corporation |
6 | // |
7 | // Auther: Gyuhwa Park <gyuhwa.park@irondevice.com> |
8 | // Kiseok Jo <kiseok.jo@irondevice.com> |
9 | |
10 | #include <linux/mod_devicetable.h> |
11 | #include <linux/module.h> |
12 | #include <linux/moduleparam.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> |
15 | #include <linux/delay.h> |
16 | #include <linux/pm.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/regmap.h> |
19 | #include <sound/core.h> |
20 | #include <sound/pcm.h> |
21 | #include <sound/pcm_params.h> |
22 | #include <sound/soc.h> |
23 | #include <sound/initval.h> |
24 | #include <sound/tlv.h> |
25 | #include <linux/slab.h> |
26 | #include <asm/div64.h> |
27 | |
28 | #include "sma1303.h" |
29 | |
30 | #define CHECK_PERIOD_TIME 1 /* sec per HZ */ |
31 | #define MAX_CONTROL_NAME 48 |
32 | |
33 | #define PLL_MATCH(_input_clk_name, _output_clk_name, _input_clk,\ |
34 | _post_n, _n, _vco, _p_cp)\ |
35 | {\ |
36 | .input_clk_name = _input_clk_name,\ |
37 | .output_clk_name = _output_clk_name,\ |
38 | .input_clk = _input_clk,\ |
39 | .post_n = _post_n,\ |
40 | .n = _n,\ |
41 | .vco = _vco,\ |
42 | .p_cp = _p_cp,\ |
43 | } |
44 | |
45 | enum sma1303_type { |
46 | SMA1303, |
47 | }; |
48 | |
49 | struct sma1303_pll_match { |
50 | char *input_clk_name; |
51 | char *output_clk_name; |
52 | unsigned int input_clk; |
53 | unsigned int post_n; |
54 | unsigned int n; |
55 | unsigned int vco; |
56 | unsigned int p_cp; |
57 | }; |
58 | |
59 | struct sma1303_priv { |
60 | enum sma1303_type devtype; |
61 | struct attribute_group *attr_grp; |
62 | struct delayed_work check_fault_work; |
63 | struct device *dev; |
64 | struct kobject *kobj; |
65 | struct regmap *regmap; |
66 | struct sma1303_pll_match *pll_matches; |
67 | bool amp_power_status; |
68 | bool force_mute_status; |
69 | int num_of_pll_matches; |
70 | int retry_cnt; |
71 | unsigned int amp_mode; |
72 | unsigned int cur_vol; |
73 | unsigned int format; |
74 | unsigned int frame_size; |
75 | unsigned int init_vol; |
76 | unsigned int last_bclk; |
77 | unsigned int last_ocp_val; |
78 | unsigned int last_over_temp; |
79 | unsigned int rev_num; |
80 | unsigned int sys_clk_id; |
81 | unsigned int tdm_slot_rx; |
82 | unsigned int tdm_slot_tx; |
83 | unsigned int tsdw_cnt; |
84 | long check_fault_period; |
85 | long check_fault_status; |
86 | }; |
87 | |
88 | static struct sma1303_pll_match sma1303_pll_matches[] = { |
89 | PLL_MATCH("1.411MHz" , "24.595MHz" , 1411200, 0x07, 0xF4, 0x8B, 0x03), |
90 | PLL_MATCH("1.536MHz" , "24.576MHz" , 1536000, 0x07, 0xE0, 0x8B, 0x03), |
91 | PLL_MATCH("3.072MHz" , "24.576MHz" , 3072000, 0x07, 0x70, 0x8B, 0x03), |
92 | PLL_MATCH("6.144MHz" , "24.576MHz" , 6144000, 0x07, 0x70, 0x8B, 0x07), |
93 | PLL_MATCH("12.288MHz" , "24.576MHz" , 12288000, 0x07, 0x70, 0x8B, 0x0B), |
94 | PLL_MATCH("19.2MHz" , "24.343MHz" , 19200000, 0x07, 0x47, 0x8B, 0x0A), |
95 | PLL_MATCH("24.576MHz" , "24.576MHz" , 24576000, 0x07, 0x70, 0x8B, 0x0F), |
96 | }; |
97 | |
98 | static int sma1303_startup(struct snd_soc_component *); |
99 | static int sma1303_shutdown(struct snd_soc_component *); |
100 | |
101 | static const struct reg_default sma1303_reg_def[] = { |
102 | { 0x00, 0x80 }, |
103 | { 0x01, 0x00 }, |
104 | { 0x02, 0x00 }, |
105 | { 0x03, 0x11 }, |
106 | { 0x04, 0x17 }, |
107 | { 0x09, 0x00 }, |
108 | { 0x0A, 0x31 }, |
109 | { 0x0B, 0x98 }, |
110 | { 0x0C, 0x84 }, |
111 | { 0x0D, 0x07 }, |
112 | { 0x0E, 0x3F }, |
113 | { 0x10, 0x00 }, |
114 | { 0x11, 0x00 }, |
115 | { 0x12, 0x00 }, |
116 | { 0x14, 0x5C }, |
117 | { 0x15, 0x01 }, |
118 | { 0x16, 0x0F }, |
119 | { 0x17, 0x0F }, |
120 | { 0x18, 0x0F }, |
121 | { 0x19, 0x00 }, |
122 | { 0x1A, 0x00 }, |
123 | { 0x1B, 0x00 }, |
124 | { 0x23, 0x19 }, |
125 | { 0x24, 0x00 }, |
126 | { 0x25, 0x00 }, |
127 | { 0x26, 0x04 }, |
128 | { 0x33, 0x00 }, |
129 | { 0x36, 0x92 }, |
130 | { 0x37, 0x27 }, |
131 | { 0x3B, 0x5A }, |
132 | { 0x3C, 0x20 }, |
133 | { 0x3D, 0x00 }, |
134 | { 0x3E, 0x03 }, |
135 | { 0x3F, 0x0C }, |
136 | { 0x8B, 0x07 }, |
137 | { 0x8C, 0x70 }, |
138 | { 0x8D, 0x8B }, |
139 | { 0x8E, 0x6F }, |
140 | { 0x8F, 0x03 }, |
141 | { 0x90, 0x26 }, |
142 | { 0x91, 0x42 }, |
143 | { 0x92, 0xE0 }, |
144 | { 0x94, 0x35 }, |
145 | { 0x95, 0x0C }, |
146 | { 0x96, 0x42 }, |
147 | { 0x97, 0x95 }, |
148 | { 0xA0, 0x00 }, |
149 | { 0xA1, 0x3B }, |
150 | { 0xA2, 0xC8 }, |
151 | { 0xA3, 0x28 }, |
152 | { 0xA4, 0x40 }, |
153 | { 0xA5, 0x01 }, |
154 | { 0xA6, 0x41 }, |
155 | { 0xA7, 0x00 }, |
156 | }; |
157 | |
158 | static bool sma1303_readable_register(struct device *dev, unsigned int reg) |
159 | { |
160 | bool result; |
161 | |
162 | if (reg > SMA1303_FF_DEVICE_INDEX) |
163 | return false; |
164 | |
165 | switch (reg) { |
166 | case SMA1303_00_SYSTEM_CTRL ... SMA1303_04_INPUT1_CTRL4: |
167 | case SMA1303_09_OUTPUT_CTRL ... SMA1303_0E_MUTE_VOL_CTRL: |
168 | case SMA1303_10_SYSTEM_CTRL1 ... SMA1303_12_SYSTEM_CTRL3: |
169 | case SMA1303_14_MODULATOR ... SMA1303_1B_BASS_SPK7: |
170 | case SMA1303_23_COMP_LIM1 ... SMA1303_26_COMP_LIM4: |
171 | case SMA1303_33_SDM_CTRL ... SMA1303_34_OTP_DATA1: |
172 | case SMA1303_36_PROTECTION ... SMA1303_38_OTP_TRM0: |
173 | case SMA1303_3B_TEST1 ... SMA1303_3F_ATEST2: |
174 | case SMA1303_8B_PLL_POST_N ... SMA1303_92_FDPEC_CTRL: |
175 | case SMA1303_94_BOOST_CTRL1 ... SMA1303_97_BOOST_CTRL4: |
176 | case SMA1303_A0_PAD_CTRL0 ... SMA1303_A7_CLK_MON: |
177 | case SMA1303_FA_STATUS1 ... SMA1303_FB_STATUS2: |
178 | result = true; |
179 | break; |
180 | case SMA1303_FF_DEVICE_INDEX: |
181 | result = true; |
182 | break; |
183 | default: |
184 | result = false; |
185 | break; |
186 | } |
187 | return result; |
188 | } |
189 | |
190 | static bool sma1303_writeable_register(struct device *dev, unsigned int reg) |
191 | { |
192 | bool result; |
193 | |
194 | if (reg > SMA1303_FF_DEVICE_INDEX) |
195 | return false; |
196 | |
197 | switch (reg) { |
198 | case SMA1303_00_SYSTEM_CTRL ... SMA1303_04_INPUT1_CTRL4: |
199 | case SMA1303_09_OUTPUT_CTRL ... SMA1303_0E_MUTE_VOL_CTRL: |
200 | case SMA1303_10_SYSTEM_CTRL1 ... SMA1303_12_SYSTEM_CTRL3: |
201 | case SMA1303_14_MODULATOR ... SMA1303_1B_BASS_SPK7: |
202 | case SMA1303_23_COMP_LIM1 ... SMA1303_26_COMP_LIM4: |
203 | case SMA1303_33_SDM_CTRL: |
204 | case SMA1303_36_PROTECTION ... SMA1303_37_SLOPE_CTRL: |
205 | case SMA1303_3B_TEST1 ... SMA1303_3F_ATEST2: |
206 | case SMA1303_8B_PLL_POST_N ... SMA1303_92_FDPEC_CTRL: |
207 | case SMA1303_94_BOOST_CTRL1 ... SMA1303_97_BOOST_CTRL4: |
208 | case SMA1303_A0_PAD_CTRL0 ... SMA1303_A7_CLK_MON: |
209 | result = true; |
210 | break; |
211 | default: |
212 | result = false; |
213 | break; |
214 | } |
215 | return result; |
216 | } |
217 | |
218 | static bool sma1303_volatile_register(struct device *dev, unsigned int reg) |
219 | { |
220 | bool result; |
221 | |
222 | switch (reg) { |
223 | case SMA1303_FA_STATUS1 ... SMA1303_FB_STATUS2: |
224 | result = true; |
225 | break; |
226 | case SMA1303_FF_DEVICE_INDEX: |
227 | result = true; |
228 | break; |
229 | default: |
230 | result = false; |
231 | break; |
232 | } |
233 | return result; |
234 | } |
235 | |
236 | static const DECLARE_TLV_DB_SCALE(sma1303_spk_tlv, -6000, 50, 0); |
237 | |
238 | static int sma1303_regmap_write(struct sma1303_priv *sma1303, |
239 | unsigned int reg, unsigned int val) |
240 | { |
241 | int ret = 0; |
242 | int cnt = sma1303->retry_cnt; |
243 | |
244 | while (cnt--) { |
245 | ret = regmap_write(map: sma1303->regmap, reg, val); |
246 | if (ret < 0) { |
247 | dev_err(sma1303->dev, |
248 | "Failed to write [0x%02X]\n" , reg); |
249 | } else |
250 | break; |
251 | } |
252 | return ret; |
253 | } |
254 | |
255 | static int sma1303_regmap_update_bits(struct sma1303_priv *sma1303, |
256 | unsigned int reg, unsigned int mask, unsigned int val, bool *change) |
257 | { |
258 | int ret = 0; |
259 | int cnt = sma1303->retry_cnt; |
260 | |
261 | while (cnt--) { |
262 | ret = regmap_update_bits_check(map: sma1303->regmap, reg, |
263 | mask, val, change); |
264 | if (ret < 0) { |
265 | dev_err(sma1303->dev, |
266 | "Failed to update [0x%02X]\n" , reg); |
267 | } else |
268 | break; |
269 | } |
270 | return ret; |
271 | } |
272 | |
273 | static int sma1303_regmap_read(struct sma1303_priv *sma1303, |
274 | unsigned int reg, unsigned int *val) |
275 | { |
276 | int ret = 0; |
277 | int cnt = sma1303->retry_cnt; |
278 | |
279 | while (cnt--) { |
280 | ret = regmap_read(map: sma1303->regmap, reg, val); |
281 | if (ret < 0) { |
282 | dev_err(sma1303->dev, |
283 | "Failed to read [0x%02X]\n" , reg); |
284 | } else |
285 | break; |
286 | } |
287 | return ret; |
288 | } |
289 | |
290 | static const char * const sma1303_aif_in_source_text[] = { |
291 | "Mono" , "Left" , "Right" }; |
292 | static const char * const sma1303_aif_out_source_text[] = { |
293 | "Disable" , "After_FmtC" , "After_Mixer" , "After_DSP" , "After_Post" , |
294 | "Clk_PLL" , "Clk_OSC" }; |
295 | static const char * const sma1303_tdm_slot_text[] = { |
296 | "Slot0" , "Slot1" , "Slot2" , "Slot3" , |
297 | "Slot4" , "Slot5" , "Slot6" , "Slot7" }; |
298 | |
299 | static const struct soc_enum sma1303_aif_in_source_enum = |
300 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_in_source_text), |
301 | sma1303_aif_in_source_text); |
302 | static const struct soc_enum sma1303_aif_out_source_enum = |
303 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_out_source_text), |
304 | sma1303_aif_out_source_text); |
305 | static const struct soc_enum sma1303_tdm_slot_enum = |
306 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_tdm_slot_text), |
307 | sma1303_tdm_slot_text); |
308 | |
309 | static int sma1303_force_mute_get(struct snd_kcontrol *kcontrol, |
310 | struct snd_ctl_elem_value *ucontrol) |
311 | { |
312 | struct snd_soc_component *component = |
313 | snd_soc_kcontrol_component(kcontrol); |
314 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
315 | |
316 | ucontrol->value.integer.value[0] = (int)sma1303->force_mute_status; |
317 | dev_dbg(sma1303->dev, "%s : Force Mute %s\n" , __func__, |
318 | sma1303->force_mute_status ? "ON" : "OFF" ); |
319 | |
320 | return 0; |
321 | } |
322 | |
323 | static int sma1303_force_mute_put(struct snd_kcontrol *kcontrol, |
324 | struct snd_ctl_elem_value *ucontrol) |
325 | { |
326 | struct snd_soc_component *component = |
327 | snd_soc_kcontrol_component(kcontrol); |
328 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
329 | bool change = false, val = (bool)ucontrol->value.integer.value[0]; |
330 | |
331 | if (sma1303->force_mute_status == val) |
332 | change = false; |
333 | else { |
334 | change = true; |
335 | sma1303->force_mute_status = val; |
336 | } |
337 | dev_dbg(sma1303->dev, "%s : Force Mute %s\n" , __func__, |
338 | sma1303->force_mute_status ? "ON" : "OFF" ); |
339 | |
340 | return change; |
341 | } |
342 | |
343 | static int sma1303_postscaler_get(struct snd_kcontrol *kcontrol, |
344 | struct snd_ctl_elem_value *ucontrol) |
345 | { |
346 | struct snd_soc_component *component = |
347 | snd_soc_kcontrol_component(kcontrol); |
348 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
349 | int val, ret; |
350 | |
351 | ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, val: &val); |
352 | if (ret < 0) |
353 | return -EINVAL; |
354 | |
355 | ucontrol->value.integer.value[0] = (val & 0x7E) >> 1; |
356 | |
357 | return 0; |
358 | } |
359 | |
360 | static int sma1303_postscaler_put(struct snd_kcontrol *kcontrol, |
361 | struct snd_ctl_elem_value *ucontrol) |
362 | { |
363 | struct snd_soc_component *component = |
364 | snd_soc_kcontrol_component(kcontrol); |
365 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
366 | int ret, val = (int)ucontrol->value.integer.value[0]; |
367 | bool change; |
368 | |
369 | ret = sma1303_regmap_update_bits(sma1303, |
370 | SMA1303_90_POSTSCALER, mask: 0x7E, val: (val << 1), change: &change); |
371 | if (ret < 0) |
372 | return -EINVAL; |
373 | |
374 | return change; |
375 | } |
376 | |
377 | static int sma1303_tdm_slot_rx_get(struct snd_kcontrol *kcontrol, |
378 | struct snd_ctl_elem_value *ucontrol) |
379 | { |
380 | struct snd_soc_component *component = |
381 | snd_soc_kcontrol_component(kcontrol); |
382 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
383 | int val, ret; |
384 | |
385 | ret = sma1303_regmap_read(sma1303, SMA1303_A5_TDM1, val: &val); |
386 | if (ret < 0) |
387 | return -EINVAL; |
388 | |
389 | ucontrol->value.integer.value[0] = (val & 0x38) >> 3; |
390 | sma1303->tdm_slot_rx = ucontrol->value.integer.value[0]; |
391 | |
392 | return 0; |
393 | } |
394 | |
395 | static int sma1303_tdm_slot_rx_put(struct snd_kcontrol *kcontrol, |
396 | struct snd_ctl_elem_value *ucontrol) |
397 | { |
398 | struct snd_soc_component *component = |
399 | snd_soc_kcontrol_component(kcontrol); |
400 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
401 | int ret, val = (int)ucontrol->value.integer.value[0]; |
402 | bool change; |
403 | |
404 | ret = sma1303_regmap_update_bits(sma1303, |
405 | SMA1303_A5_TDM1, mask: 0x38, val: (val << 3), change: &change); |
406 | if (ret < 0) |
407 | return -EINVAL; |
408 | |
409 | return change; |
410 | } |
411 | |
412 | static int sma1303_tdm_slot_tx_get(struct snd_kcontrol *kcontrol, |
413 | struct snd_ctl_elem_value *ucontrol) |
414 | { |
415 | struct snd_soc_component *component = |
416 | snd_soc_kcontrol_component(kcontrol); |
417 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
418 | int val, ret; |
419 | |
420 | ret = sma1303_regmap_read(sma1303, SMA1303_A6_TDM2, val: &val); |
421 | if (ret < 0) |
422 | return -EINVAL; |
423 | |
424 | ucontrol->value.integer.value[0] = (val & 0x38) >> 3; |
425 | sma1303->tdm_slot_tx = ucontrol->value.integer.value[0]; |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | static int sma1303_tdm_slot_tx_put(struct snd_kcontrol *kcontrol, |
431 | struct snd_ctl_elem_value *ucontrol) |
432 | { |
433 | struct snd_soc_component *component = |
434 | snd_soc_kcontrol_component(kcontrol); |
435 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
436 | int ret, val = (int)ucontrol->value.integer.value[0]; |
437 | bool change; |
438 | |
439 | ret = sma1303_regmap_update_bits(sma1303, |
440 | SMA1303_A6_TDM2, mask: 0x38, val: (val << 3), change: &change); |
441 | if (ret < 0) |
442 | return -EINVAL; |
443 | |
444 | return change; |
445 | } |
446 | |
447 | static int sma1303_startup(struct snd_soc_component *component) |
448 | { |
449 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
450 | bool change = false, temp = false; |
451 | |
452 | sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL, |
453 | SMA1303_PLL_PD2_MASK, SMA1303_PLL_OPERATION2, change: &temp); |
454 | if (temp == true) |
455 | change = true; |
456 | |
457 | sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL, |
458 | SMA1303_POWER_MASK, SMA1303_POWER_ON, change: &temp); |
459 | if (temp == true) |
460 | change = true; |
461 | |
462 | if (sma1303->amp_mode == SMA1303_MONO) { |
463 | sma1303_regmap_update_bits(sma1303, |
464 | SMA1303_10_SYSTEM_CTRL1, |
465 | SMA1303_SPK_MODE_MASK, |
466 | SMA1303_SPK_MONO, |
467 | change: &temp); |
468 | if (temp == true) |
469 | change = true; |
470 | |
471 | } else { |
472 | sma1303_regmap_update_bits(sma1303, |
473 | SMA1303_10_SYSTEM_CTRL1, |
474 | SMA1303_SPK_MODE_MASK, |
475 | SMA1303_SPK_STEREO, |
476 | change: &temp); |
477 | if (temp == true) |
478 | change = true; |
479 | } |
480 | |
481 | if (sma1303->check_fault_status) { |
482 | if (sma1303->check_fault_period > 0) |
483 | queue_delayed_work(wq: system_freezable_wq, |
484 | dwork: &sma1303->check_fault_work, |
485 | delay: sma1303->check_fault_period * HZ); |
486 | else |
487 | queue_delayed_work(wq: system_freezable_wq, |
488 | dwork: &sma1303->check_fault_work, |
489 | CHECK_PERIOD_TIME * HZ); |
490 | } |
491 | |
492 | sma1303->amp_power_status = true; |
493 | |
494 | return change; |
495 | } |
496 | |
497 | static int sma1303_shutdown(struct snd_soc_component *component) |
498 | { |
499 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
500 | bool change = false, temp = false; |
501 | |
502 | cancel_delayed_work_sync(dwork: &sma1303->check_fault_work); |
503 | |
504 | sma1303_regmap_update_bits(sma1303, SMA1303_10_SYSTEM_CTRL1, |
505 | SMA1303_SPK_MODE_MASK, SMA1303_SPK_OFF, change: &temp); |
506 | if (temp == true) |
507 | change = true; |
508 | |
509 | sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL, |
510 | SMA1303_POWER_MASK, SMA1303_POWER_OFF, change: &temp); |
511 | if (temp == true) |
512 | change = true; |
513 | sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL, |
514 | SMA1303_PLL_PD2_MASK, SMA1303_PLL_PD2, change: &temp); |
515 | if (temp == true) |
516 | change = true; |
517 | |
518 | sma1303->amp_power_status = false; |
519 | |
520 | return change; |
521 | } |
522 | |
523 | static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w, |
524 | struct snd_kcontrol *kcontrol, int event) |
525 | { |
526 | struct snd_soc_component *component = |
527 | snd_soc_dapm_to_component(dapm: w->dapm); |
528 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
529 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
530 | int ret = 0; |
531 | bool change = false, temp = false; |
532 | |
533 | switch (event) { |
534 | case SND_SOC_DAPM_PRE_PMU: |
535 | switch (mux) { |
536 | case 0: |
537 | ret += sma1303_regmap_update_bits(sma1303, |
538 | SMA1303_11_SYSTEM_CTRL2, |
539 | SMA1303_MONOMIX_MASK, |
540 | SMA1303_MONOMIX_ON, |
541 | change: &change); |
542 | sma1303->amp_mode = SMA1303_MONO; |
543 | break; |
544 | case 1: |
545 | ret += sma1303_regmap_update_bits(sma1303, |
546 | SMA1303_11_SYSTEM_CTRL2, |
547 | SMA1303_MONOMIX_MASK, |
548 | SMA1303_MONOMIX_OFF, |
549 | change: &temp); |
550 | if (temp == true) |
551 | change = true; |
552 | ret += sma1303_regmap_update_bits(sma1303, |
553 | SMA1303_11_SYSTEM_CTRL2, |
554 | SMA1303_LR_DATA_SW_MASK, |
555 | SMA1303_LR_DATA_SW_NORMAL, |
556 | change: &temp); |
557 | if (temp == true) |
558 | change = true; |
559 | sma1303->amp_mode = SMA1303_STEREO; |
560 | break; |
561 | case 2: |
562 | ret += sma1303_regmap_update_bits(sma1303, |
563 | SMA1303_11_SYSTEM_CTRL2, |
564 | SMA1303_MONOMIX_MASK, |
565 | SMA1303_MONOMIX_OFF, |
566 | change: &temp); |
567 | if (temp == true) |
568 | change = true; |
569 | ret += sma1303_regmap_update_bits(sma1303, |
570 | SMA1303_11_SYSTEM_CTRL2, |
571 | SMA1303_LR_DATA_SW_MASK, |
572 | SMA1303_LR_DATA_SW_SWAP, |
573 | change: &temp); |
574 | if (temp == true) |
575 | change = true; |
576 | sma1303->amp_mode = SMA1303_STEREO; |
577 | break; |
578 | default: |
579 | dev_err(sma1303->dev, "%s : Invalid value (%d)\n" , |
580 | __func__, mux); |
581 | return -EINVAL; |
582 | } |
583 | |
584 | dev_dbg(sma1303->dev, "%s : Source : %s\n" , __func__, |
585 | sma1303_aif_in_source_text[mux]); |
586 | break; |
587 | } |
588 | if (ret < 0) |
589 | return -EINVAL; |
590 | return change; |
591 | } |
592 | |
593 | static int sma1303_aif_out_event(struct snd_soc_dapm_widget *w, |
594 | struct snd_kcontrol *kcontrol, int event) |
595 | { |
596 | struct snd_soc_component *component = |
597 | snd_soc_dapm_to_component(dapm: w->dapm); |
598 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
599 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
600 | int ret = 0; |
601 | bool change = false, temp = false; |
602 | |
603 | switch (event) { |
604 | case SND_SOC_DAPM_PRE_PMU: |
605 | switch (mux) { |
606 | case 0: |
607 | ret += sma1303_regmap_update_bits(sma1303, |
608 | SMA1303_A3_TOP_MAN2, |
609 | SMA1303_TEST_CLKO_EN_MASK, |
610 | SMA1303_NORMAL_SDO, |
611 | change: &temp); |
612 | if (temp == true) |
613 | change = true; |
614 | ret += sma1303_regmap_update_bits(sma1303, |
615 | SMA1303_09_OUTPUT_CTRL, |
616 | SMA1303_PORT_OUT_SEL_MASK, |
617 | SMA1303_OUT_SEL_DISABLE, |
618 | change: &temp); |
619 | if (temp == true) |
620 | change = true; |
621 | break; |
622 | case 1: |
623 | ret += sma1303_regmap_update_bits(sma1303, |
624 | SMA1303_A3_TOP_MAN2, |
625 | SMA1303_TEST_CLKO_EN_MASK, |
626 | SMA1303_NORMAL_SDO, |
627 | change: &temp); |
628 | if (temp == true) |
629 | change = true; |
630 | ret += sma1303_regmap_update_bits(sma1303, |
631 | SMA1303_09_OUTPUT_CTRL, |
632 | SMA1303_PORT_OUT_SEL_MASK, |
633 | SMA1303_FORMAT_CONVERTER, |
634 | change: &temp); |
635 | if (temp == true) |
636 | change = true; |
637 | break; |
638 | case 2: |
639 | ret += sma1303_regmap_update_bits(sma1303, |
640 | SMA1303_A3_TOP_MAN2, |
641 | SMA1303_TEST_CLKO_EN_MASK, |
642 | SMA1303_NORMAL_SDO, |
643 | change: &temp); |
644 | if (temp == true) |
645 | change = true; |
646 | ret += sma1303_regmap_update_bits(sma1303, |
647 | SMA1303_09_OUTPUT_CTRL, |
648 | SMA1303_PORT_OUT_SEL_MASK, |
649 | SMA1303_MIXER_OUTPUT, |
650 | change: &temp); |
651 | if (temp == true) |
652 | change = true; |
653 | break; |
654 | case 3: |
655 | ret += sma1303_regmap_update_bits(sma1303, |
656 | SMA1303_A3_TOP_MAN2, |
657 | SMA1303_TEST_CLKO_EN_MASK, |
658 | SMA1303_NORMAL_SDO, |
659 | change: &temp); |
660 | if (temp == true) |
661 | change = true; |
662 | ret += sma1303_regmap_update_bits(sma1303, |
663 | SMA1303_09_OUTPUT_CTRL, |
664 | SMA1303_PORT_OUT_SEL_MASK, |
665 | SMA1303_SPEAKER_PATH, |
666 | change: &temp); |
667 | if (temp == true) |
668 | change = true; |
669 | break; |
670 | case 4: |
671 | ret += sma1303_regmap_update_bits(sma1303, |
672 | SMA1303_A3_TOP_MAN2, |
673 | SMA1303_TEST_CLKO_EN_MASK, |
674 | SMA1303_NORMAL_SDO, |
675 | change: &temp); |
676 | if (temp == true) |
677 | change = true; |
678 | ret += sma1303_regmap_update_bits(sma1303, |
679 | SMA1303_09_OUTPUT_CTRL, |
680 | SMA1303_PORT_OUT_SEL_MASK, |
681 | SMA1303_POSTSCALER_OUTPUT, |
682 | change: &temp); |
683 | if (temp == true) |
684 | change = true; |
685 | break; |
686 | case 5: |
687 | ret += sma1303_regmap_update_bits(sma1303, |
688 | SMA1303_A3_TOP_MAN2, |
689 | SMA1303_TEST_CLKO_EN_MASK, |
690 | SMA1303_CLK_OUT_SDO, |
691 | change: &temp); |
692 | if (temp == true) |
693 | change = true; |
694 | ret += sma1303_regmap_update_bits(sma1303, |
695 | SMA1303_A3_TOP_MAN2, |
696 | SMA1303_MON_OSC_PLL_MASK, |
697 | SMA1303_PLL_SDO, |
698 | change: &temp); |
699 | if (temp == true) |
700 | change = true; |
701 | break; |
702 | case 6: |
703 | ret += sma1303_regmap_update_bits(sma1303, |
704 | SMA1303_A3_TOP_MAN2, |
705 | SMA1303_TEST_CLKO_EN_MASK, |
706 | SMA1303_CLK_OUT_SDO, |
707 | change: &temp); |
708 | if (temp == true) |
709 | change = true; |
710 | ret += sma1303_regmap_update_bits(sma1303, |
711 | SMA1303_A3_TOP_MAN2, |
712 | SMA1303_MON_OSC_PLL_MASK, |
713 | SMA1303_OSC_SDO, |
714 | change: &temp); |
715 | if (temp == true) |
716 | change = true; |
717 | break; |
718 | default: |
719 | dev_err(sma1303->dev, "%s : Invalid value (%d)\n" , |
720 | __func__, mux); |
721 | return -EINVAL; |
722 | } |
723 | |
724 | dev_dbg(sma1303->dev, "%s : Source : %s\n" , __func__, |
725 | sma1303_aif_out_source_text[mux]); |
726 | break; |
727 | } |
728 | if (ret < 0) |
729 | return -EINVAL; |
730 | return change; |
731 | } |
732 | |
733 | static int sma1303_sdo_event(struct snd_soc_dapm_widget *w, |
734 | struct snd_kcontrol *kcontrol, int event) |
735 | { |
736 | struct snd_soc_component *component = |
737 | snd_soc_dapm_to_component(dapm: w->dapm); |
738 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
739 | int ret = 0; |
740 | bool change = false, temp = false; |
741 | |
742 | switch (event) { |
743 | case SND_SOC_DAPM_PRE_PMU: |
744 | dev_dbg(sma1303->dev, |
745 | "%s : SND_SOC_DAPM_PRE_PMU\n" , __func__); |
746 | ret += sma1303_regmap_update_bits(sma1303, |
747 | SMA1303_09_OUTPUT_CTRL, |
748 | SMA1303_PORT_CONFIG_MASK, |
749 | SMA1303_OUTPUT_PORT_ENABLE, |
750 | change: &temp); |
751 | if (temp == true) |
752 | change = true; |
753 | ret += sma1303_regmap_update_bits(sma1303, |
754 | SMA1303_A3_TOP_MAN2, |
755 | SMA1303_SDO_OUTPUT_MASK, |
756 | SMA1303_NORMAL_OUT, |
757 | change: &temp); |
758 | if (temp == true) |
759 | change = true; |
760 | break; |
761 | case SND_SOC_DAPM_POST_PMD: |
762 | dev_dbg(sma1303->dev, |
763 | "%s : SND_SOC_DAPM_POST_PMD\n" , __func__); |
764 | ret += sma1303_regmap_update_bits(sma1303, |
765 | SMA1303_09_OUTPUT_CTRL, |
766 | SMA1303_PORT_CONFIG_MASK, |
767 | SMA1303_INPUT_PORT_ONLY, |
768 | change: &temp); |
769 | if (temp == true) |
770 | change = true; |
771 | ret += sma1303_regmap_update_bits(sma1303, |
772 | SMA1303_A3_TOP_MAN2, |
773 | SMA1303_SDO_OUTPUT_MASK, |
774 | SMA1303_HIGH_Z_OUT, |
775 | change: &temp); |
776 | if (temp == true) |
777 | change = true; |
778 | break; |
779 | } |
780 | if (ret < 0) |
781 | return -EINVAL; |
782 | return change; |
783 | } |
784 | |
785 | static int sma1303_post_scaler_event(struct snd_soc_dapm_widget *w, |
786 | struct snd_kcontrol *kcontrol, int event) |
787 | { |
788 | struct snd_soc_component *component = |
789 | snd_soc_dapm_to_component(dapm: w->dapm); |
790 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
791 | int ret = 0; |
792 | bool change = false; |
793 | |
794 | switch (event) { |
795 | case SND_SOC_DAPM_PRE_PMU: |
796 | dev_dbg(sma1303->dev, |
797 | "%s : SND_SOC_DAPM_PRE_PMU\n" , __func__); |
798 | ret += sma1303_regmap_update_bits(sma1303, |
799 | SMA1303_90_POSTSCALER, |
800 | SMA1303_BYP_POST_MASK, |
801 | SMA1303_EN_POST_SCALER, |
802 | change: &change); |
803 | break; |
804 | case SND_SOC_DAPM_POST_PMD: |
805 | dev_dbg(sma1303->dev, |
806 | "%s : SND_SOC_DAPM_POST_PMD\n" , __func__); |
807 | ret += sma1303_regmap_update_bits(sma1303, |
808 | SMA1303_90_POSTSCALER, |
809 | SMA1303_BYP_POST_MASK, |
810 | SMA1303_BYP_POST_SCALER, |
811 | change: &change); |
812 | break; |
813 | } |
814 | if (ret < 0) |
815 | return -EINVAL; |
816 | return change; |
817 | } |
818 | |
819 | static int sma1303_power_event(struct snd_soc_dapm_widget *w, |
820 | struct snd_kcontrol *kcontrol, int event) |
821 | { |
822 | struct snd_soc_component *component = |
823 | snd_soc_dapm_to_component(dapm: w->dapm); |
824 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
825 | int ret = 0; |
826 | |
827 | switch (event) { |
828 | case SND_SOC_DAPM_POST_PMU: |
829 | dev_dbg(sma1303->dev, |
830 | "%s : SND_SOC_DAPM_POST_PMU\n" , __func__); |
831 | ret = sma1303_startup(component); |
832 | break; |
833 | case SND_SOC_DAPM_PRE_PMD: |
834 | dev_dbg(sma1303->dev, |
835 | "%s : SND_SOC_DAPM_PRE_PMD\n" , __func__); |
836 | ret = sma1303_shutdown(component); |
837 | break; |
838 | } |
839 | return ret; |
840 | } |
841 | |
842 | static const struct snd_kcontrol_new sma1303_aif_in_source_control = |
843 | SOC_DAPM_ENUM("AIF IN Source" , sma1303_aif_in_source_enum); |
844 | static const struct snd_kcontrol_new sma1303_aif_out_source_control = |
845 | SOC_DAPM_ENUM("AIF OUT Source" , sma1303_aif_out_source_enum); |
846 | static const struct snd_kcontrol_new sma1303_sdo_control = |
847 | SOC_DAPM_SINGLE_VIRT("Switch" , 1); |
848 | static const struct snd_kcontrol_new sma1303_post_scaler_control = |
849 | SOC_DAPM_SINGLE_VIRT("Switch" , 1); |
850 | static const struct snd_kcontrol_new sma1303_enable_control = |
851 | SOC_DAPM_SINGLE_VIRT("Switch" , 1); |
852 | |
853 | static const struct snd_kcontrol_new sma1303_snd_controls[] = { |
854 | SOC_SINGLE_TLV("Speaker Volume" , SMA1303_0A_SPK_VOL, |
855 | 0, 167, 1, sma1303_spk_tlv), |
856 | SOC_SINGLE_BOOL_EXT("Force Mute Switch" , 0, |
857 | sma1303_force_mute_get, sma1303_force_mute_put), |
858 | SOC_SINGLE_EXT("Postscaler Gain" , SMA1303_90_POSTSCALER, 1, 0x30, 0, |
859 | sma1303_postscaler_get, sma1303_postscaler_put), |
860 | SOC_ENUM_EXT("TDM RX Slot Position" , sma1303_tdm_slot_enum, |
861 | sma1303_tdm_slot_rx_get, sma1303_tdm_slot_rx_put), |
862 | SOC_ENUM_EXT("TDM TX Slot Position" , sma1303_tdm_slot_enum, |
863 | sma1303_tdm_slot_tx_get, sma1303_tdm_slot_tx_put), |
864 | }; |
865 | |
866 | static const struct snd_soc_dapm_widget sma1303_dapm_widgets[] = { |
867 | /* platform domain */ |
868 | SND_SOC_DAPM_OUTPUT("SPK" ), |
869 | SND_SOC_DAPM_INPUT("SDO" ), |
870 | |
871 | /* path domain */ |
872 | SND_SOC_DAPM_MUX_E("AIF IN Source" , SND_SOC_NOPM, 0, 0, |
873 | &sma1303_aif_in_source_control, |
874 | sma1303_aif_in_event, |
875 | SND_SOC_DAPM_PRE_PMU), |
876 | SND_SOC_DAPM_MUX_E("AIF OUT Source" , SND_SOC_NOPM, 0, 0, |
877 | &sma1303_aif_out_source_control, |
878 | sma1303_aif_out_event, |
879 | SND_SOC_DAPM_PRE_PMU), |
880 | SND_SOC_DAPM_SWITCH_E("SDO Enable" , SND_SOC_NOPM, 0, 0, |
881 | &sma1303_sdo_control, |
882 | sma1303_sdo_event, |
883 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
884 | SND_SOC_DAPM_MIXER("Entry" , SND_SOC_NOPM, 0, 0, NULL, 0), |
885 | SND_SOC_DAPM_SWITCH_E("Post Scaler" , SND_SOC_NOPM, 0, 1, |
886 | &sma1303_post_scaler_control, |
887 | sma1303_post_scaler_event, |
888 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
889 | SND_SOC_DAPM_OUT_DRV_E("AMP Power" , SND_SOC_NOPM, 0, 0, NULL, 0, |
890 | sma1303_power_event, |
891 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
892 | SND_SOC_DAPM_SWITCH("AMP Enable" , SND_SOC_NOPM, 0, 1, |
893 | &sma1303_enable_control), |
894 | |
895 | /* stream domain */ |
896 | SND_SOC_DAPM_AIF_IN("AIF IN" , "Playback" , 0, SND_SOC_NOPM, 0, 0), |
897 | SND_SOC_DAPM_AIF_OUT("AIF OUT" , "Capture" , 0, SND_SOC_NOPM, 0, 0), |
898 | }; |
899 | |
900 | static const struct snd_soc_dapm_route sma1303_audio_map[] = { |
901 | /* Playback */ |
902 | {"AIF IN Source" , "Mono" , "AIF IN" }, |
903 | {"AIF IN Source" , "Left" , "AIF IN" }, |
904 | {"AIF IN Source" , "Right" , "AIF IN" }, |
905 | |
906 | {"SDO Enable" , "Switch" , "AIF IN" }, |
907 | {"AIF OUT Source" , "Disable" , "SDO Enable" }, |
908 | {"AIF OUT Source" , "After_FmtC" , "SDO Enable" }, |
909 | {"AIF OUT Source" , "After_Mixer" , "SDO Enable" }, |
910 | {"AIF OUT Source" , "After_DSP" , "SDO Enable" }, |
911 | {"AIF OUT Source" , "After_Post" , "SDO Enable" }, |
912 | {"AIF OUT Source" , "Clk_PLL" , "SDO Enable" }, |
913 | {"AIF OUT Source" , "Clk_OSC" , "SDO Enable" }, |
914 | |
915 | {"Entry" , NULL, "AIF OUT Source" }, |
916 | {"Entry" , NULL, "AIF IN Source" }, |
917 | |
918 | {"Post Scaler" , "Switch" , "Entry" }, |
919 | {"AMP Power" , NULL, "Entry" }, |
920 | {"AMP Power" , NULL, "Entry" }, |
921 | |
922 | {"AMP Enable" , "Switch" , "AMP Power" }, |
923 | {"SPK" , NULL, "AMP Enable" }, |
924 | |
925 | /* Capture */ |
926 | {"AIF OUT" , NULL, "AMP Enable" }, |
927 | }; |
928 | |
929 | static int sma1303_setup_pll(struct snd_soc_component *component, |
930 | unsigned int bclk) |
931 | { |
932 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
933 | |
934 | int i = 0, ret = 0; |
935 | |
936 | dev_dbg(component->dev, "%s : BCLK = %dHz\n" , |
937 | __func__, bclk); |
938 | |
939 | if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_MCLK) { |
940 | dev_dbg(component->dev, "%s : MCLK is not supported\n" , |
941 | __func__); |
942 | } else if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) { |
943 | for (i = 0; i < sma1303->num_of_pll_matches; i++) { |
944 | if (sma1303->pll_matches[i].input_clk == bclk) |
945 | break; |
946 | } |
947 | if (i == sma1303->num_of_pll_matches) { |
948 | dev_dbg(component->dev, "%s : No matching value between pll table and SCK\n" , |
949 | __func__); |
950 | return -EINVAL; |
951 | } |
952 | |
953 | ret += sma1303_regmap_update_bits(sma1303, |
954 | SMA1303_A2_TOP_MAN1, |
955 | SMA1303_PLL_PD_MASK|SMA1303_PLL_REF_CLK_MASK, |
956 | SMA1303_PLL_OPERATION|SMA1303_PLL_SCK, |
957 | NULL); |
958 | } |
959 | |
960 | ret += sma1303_regmap_write(sma1303, |
961 | SMA1303_8B_PLL_POST_N, |
962 | val: sma1303->pll_matches[i].post_n); |
963 | |
964 | ret += sma1303_regmap_write(sma1303, |
965 | SMA1303_8C_PLL_N, |
966 | val: sma1303->pll_matches[i].n); |
967 | |
968 | ret += sma1303_regmap_write(sma1303, |
969 | SMA1303_8D_PLL_A_SETTING, |
970 | val: sma1303->pll_matches[i].vco); |
971 | |
972 | ret += sma1303_regmap_write(sma1303, |
973 | SMA1303_8F_PLL_P_CP, |
974 | val: sma1303->pll_matches[i].p_cp); |
975 | if (ret < 0) |
976 | return -EINVAL; |
977 | |
978 | return 0; |
979 | } |
980 | |
981 | static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream, |
982 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
983 | { |
984 | struct snd_soc_component *component = dai->component; |
985 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
986 | unsigned int bclk = 0; |
987 | int ret = 0; |
988 | |
989 | if (sma1303->format == SND_SOC_DAIFMT_DSP_A) |
990 | bclk = params_rate(p: params) * sma1303->frame_size; |
991 | else |
992 | bclk = params_rate(p: params) * params_physical_width(p: params) |
993 | * params_channels(p: params); |
994 | |
995 | dev_dbg(component->dev, |
996 | "%s : rate = %d : bit size = %d : channel = %d\n" , |
997 | __func__, params_rate(params), params_width(params), |
998 | params_channels(params)); |
999 | |
1000 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1001 | if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) { |
1002 | if (sma1303->last_bclk != bclk) { |
1003 | sma1303_setup_pll(component, bclk); |
1004 | sma1303->last_bclk = bclk; |
1005 | } |
1006 | } |
1007 | |
1008 | switch (params_rate(p: params)) { |
1009 | case 8000: |
1010 | case 12000: |
1011 | case 16000: |
1012 | case 24000: |
1013 | case 32000: |
1014 | case 44100: |
1015 | case 48000: |
1016 | case 96000: |
1017 | ret += sma1303_regmap_update_bits(sma1303, |
1018 | SMA1303_A2_TOP_MAN1, |
1019 | SMA1303_DAC_DN_CONV_MASK, |
1020 | SMA1303_DAC_DN_CONV_DISABLE, |
1021 | NULL); |
1022 | |
1023 | ret += sma1303_regmap_update_bits(sma1303, |
1024 | SMA1303_01_INPUT1_CTRL1, |
1025 | SMA1303_LEFTPOL_MASK, |
1026 | SMA1303_LOW_FIRST_CH, |
1027 | NULL); |
1028 | break; |
1029 | |
1030 | case 192000: |
1031 | ret += sma1303_regmap_update_bits(sma1303, |
1032 | SMA1303_A2_TOP_MAN1, |
1033 | SMA1303_DAC_DN_CONV_MASK, |
1034 | SMA1303_DAC_DN_CONV_ENABLE, |
1035 | NULL); |
1036 | |
1037 | ret += sma1303_regmap_update_bits(sma1303, |
1038 | SMA1303_01_INPUT1_CTRL1, |
1039 | SMA1303_LEFTPOL_MASK, |
1040 | SMA1303_HIGH_FIRST_CH, |
1041 | NULL); |
1042 | break; |
1043 | |
1044 | default: |
1045 | dev_err(component->dev, "%s not support rate : %d\n" , |
1046 | __func__, params_rate(params)); |
1047 | |
1048 | return -EINVAL; |
1049 | } |
1050 | |
1051 | } else { |
1052 | |
1053 | switch (params_format(p: params)) { |
1054 | |
1055 | case SNDRV_PCM_FORMAT_S16_LE: |
1056 | dev_dbg(component->dev, |
1057 | "%s set format SNDRV_PCM_FORMAT_S16_LE\n" , |
1058 | __func__); |
1059 | ret += sma1303_regmap_update_bits(sma1303, |
1060 | SMA1303_A4_TOP_MAN3, |
1061 | SMA1303_SCK_RATE_MASK, |
1062 | SMA1303_SCK_32FS, |
1063 | NULL); |
1064 | break; |
1065 | |
1066 | case SNDRV_PCM_FORMAT_S24_LE: |
1067 | dev_dbg(component->dev, |
1068 | "%s set format SNDRV_PCM_FORMAT_S24_LE\n" , |
1069 | __func__); |
1070 | ret += sma1303_regmap_update_bits(sma1303, |
1071 | SMA1303_A4_TOP_MAN3, |
1072 | SMA1303_SCK_RATE_MASK, |
1073 | SMA1303_SCK_64FS, |
1074 | NULL); |
1075 | break; |
1076 | case SNDRV_PCM_FORMAT_S32_LE: |
1077 | dev_dbg(component->dev, |
1078 | "%s set format SNDRV_PCM_FORMAT_S32_LE\n" , |
1079 | __func__); |
1080 | ret += sma1303_regmap_update_bits(sma1303, |
1081 | SMA1303_A4_TOP_MAN3, |
1082 | SMA1303_SCK_RATE_MASK, |
1083 | SMA1303_SCK_64FS, |
1084 | NULL); |
1085 | break; |
1086 | default: |
1087 | dev_err(component->dev, |
1088 | "%s not support data bit : %d\n" , __func__, |
1089 | params_format(params)); |
1090 | return -EINVAL; |
1091 | } |
1092 | } |
1093 | |
1094 | switch (sma1303->format) { |
1095 | case SND_SOC_DAIFMT_I2S: |
1096 | ret += sma1303_regmap_update_bits(sma1303, |
1097 | SMA1303_01_INPUT1_CTRL1, |
1098 | SMA1303_I2S_MODE_MASK, |
1099 | SMA1303_STANDARD_I2S, |
1100 | NULL); |
1101 | ret += sma1303_regmap_update_bits(sma1303, |
1102 | SMA1303_A4_TOP_MAN3, |
1103 | SMA1303_O_FORMAT_MASK, |
1104 | SMA1303_O_FMT_I2S, |
1105 | NULL); |
1106 | break; |
1107 | case SND_SOC_DAIFMT_LEFT_J: |
1108 | ret += sma1303_regmap_update_bits(sma1303, |
1109 | SMA1303_01_INPUT1_CTRL1, |
1110 | SMA1303_I2S_MODE_MASK, |
1111 | SMA1303_LJ, |
1112 | NULL); |
1113 | ret += sma1303_regmap_update_bits(sma1303, |
1114 | SMA1303_A4_TOP_MAN3, |
1115 | SMA1303_O_FORMAT_MASK, |
1116 | SMA1303_O_FMT_LJ, |
1117 | NULL); |
1118 | break; |
1119 | case SND_SOC_DAIFMT_RIGHT_J: |
1120 | switch (params_width(p: params)) { |
1121 | case 16: |
1122 | ret += sma1303_regmap_update_bits(sma1303, |
1123 | SMA1303_01_INPUT1_CTRL1, |
1124 | SMA1303_I2S_MODE_MASK, |
1125 | SMA1303_RJ_16BIT, |
1126 | NULL); |
1127 | break; |
1128 | case 24: |
1129 | case 32: |
1130 | ret += sma1303_regmap_update_bits(sma1303, |
1131 | SMA1303_01_INPUT1_CTRL1, |
1132 | SMA1303_I2S_MODE_MASK, |
1133 | SMA1303_RJ_24BIT, |
1134 | NULL); |
1135 | break; |
1136 | } |
1137 | break; |
1138 | case SND_SOC_DAIFMT_DSP_A: |
1139 | ret += sma1303_regmap_update_bits(sma1303, |
1140 | SMA1303_01_INPUT1_CTRL1, |
1141 | SMA1303_I2S_MODE_MASK, |
1142 | SMA1303_STANDARD_I2S, |
1143 | NULL); |
1144 | ret += sma1303_regmap_update_bits(sma1303, |
1145 | SMA1303_A4_TOP_MAN3, |
1146 | SMA1303_O_FORMAT_MASK, |
1147 | SMA1303_O_FMT_TDM, |
1148 | NULL); |
1149 | break; |
1150 | } |
1151 | |
1152 | switch (params_width(p: params)) { |
1153 | case 16: |
1154 | case 24: |
1155 | case 32: |
1156 | break; |
1157 | default: |
1158 | dev_err(component->dev, |
1159 | "%s not support data bit : %d\n" , __func__, |
1160 | params_format(params)); |
1161 | return -EINVAL; |
1162 | } |
1163 | if (ret < 0) |
1164 | return -EINVAL; |
1165 | |
1166 | return 0; |
1167 | } |
1168 | |
1169 | static int sma1303_dai_set_sysclk_amp(struct snd_soc_dai *dai, |
1170 | int clk_id, unsigned int freq, int dir) |
1171 | { |
1172 | struct snd_soc_component *component = dai->component; |
1173 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
1174 | |
1175 | switch (clk_id) { |
1176 | case SMA1303_EXTERNAL_CLOCK_19_2: |
1177 | break; |
1178 | case SMA1303_EXTERNAL_CLOCK_24_576: |
1179 | break; |
1180 | case SMA1303_PLL_CLKIN_MCLK: |
1181 | break; |
1182 | case SMA1303_PLL_CLKIN_BCLK: |
1183 | break; |
1184 | default: |
1185 | dev_err(component->dev, "Invalid clk id: %d\n" , clk_id); |
1186 | return -EINVAL; |
1187 | } |
1188 | sma1303->sys_clk_id = clk_id; |
1189 | return 0; |
1190 | } |
1191 | |
1192 | static int sma1303_dai_mute(struct snd_soc_dai *dai, int mute, int stream) |
1193 | { |
1194 | struct snd_soc_component *component = dai->component; |
1195 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
1196 | int ret = 0; |
1197 | |
1198 | if (stream == SNDRV_PCM_STREAM_CAPTURE) |
1199 | return ret; |
1200 | |
1201 | if (mute) { |
1202 | dev_dbg(component->dev, "%s : %s\n" , __func__, "MUTE" ); |
1203 | |
1204 | ret += sma1303_regmap_update_bits(sma1303, |
1205 | SMA1303_0E_MUTE_VOL_CTRL, |
1206 | SMA1303_SPK_MUTE_MASK, |
1207 | SMA1303_SPK_MUTE, |
1208 | NULL); |
1209 | |
1210 | /* Need to wait time for mute slope */ |
1211 | msleep(msecs: 55); |
1212 | } else { |
1213 | if (!sma1303->force_mute_status) { |
1214 | dev_dbg(component->dev, "%s : %s\n" , |
1215 | __func__, "UNMUTE" ); |
1216 | ret += sma1303_regmap_update_bits(sma1303, |
1217 | SMA1303_0E_MUTE_VOL_CTRL, |
1218 | SMA1303_SPK_MUTE_MASK, |
1219 | SMA1303_SPK_UNMUTE, |
1220 | NULL); |
1221 | } else { |
1222 | dev_dbg(sma1303->dev, |
1223 | "%s : FORCE MUTE!!!\n" , __func__); |
1224 | } |
1225 | } |
1226 | |
1227 | if (ret < 0) |
1228 | return -EINVAL; |
1229 | return 0; |
1230 | } |
1231 | |
1232 | static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai, |
1233 | unsigned int fmt) |
1234 | { |
1235 | struct snd_soc_component *component = dai->component; |
1236 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
1237 | int ret = 0; |
1238 | |
1239 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
1240 | |
1241 | case SND_SOC_DAIFMT_CBC_CFC: |
1242 | dev_dbg(component->dev, |
1243 | "%s : %s\n" , __func__, "I2S/TDM Device mode" ); |
1244 | ret += sma1303_regmap_update_bits(sma1303, |
1245 | SMA1303_01_INPUT1_CTRL1, |
1246 | SMA1303_CONTROLLER_DEVICE_MASK, |
1247 | SMA1303_DEVICE_MODE, |
1248 | NULL); |
1249 | break; |
1250 | |
1251 | case SND_SOC_DAIFMT_CBP_CFP: |
1252 | dev_dbg(component->dev, |
1253 | "%s : %s\n" , __func__, "I2S/TDM Controller mode" ); |
1254 | ret += sma1303_regmap_update_bits(sma1303, |
1255 | SMA1303_01_INPUT1_CTRL1, |
1256 | SMA1303_CONTROLLER_DEVICE_MASK, |
1257 | SMA1303_CONTROLLER_MODE, |
1258 | NULL); |
1259 | break; |
1260 | |
1261 | default: |
1262 | dev_err(component->dev, |
1263 | "Unsupported Controller/Device : 0x%x\n" , fmt); |
1264 | return -EINVAL; |
1265 | } |
1266 | |
1267 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
1268 | |
1269 | case SND_SOC_DAIFMT_I2S: |
1270 | case SND_SOC_DAIFMT_RIGHT_J: |
1271 | case SND_SOC_DAIFMT_LEFT_J: |
1272 | case SND_SOC_DAIFMT_DSP_A: |
1273 | case SND_SOC_DAIFMT_DSP_B: |
1274 | sma1303->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; |
1275 | break; |
1276 | default: |
1277 | dev_err(component->dev, |
1278 | "Unsupported Audio Interface Format : 0x%x\n" , fmt); |
1279 | return -EINVAL; |
1280 | } |
1281 | |
1282 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
1283 | |
1284 | case SND_SOC_DAIFMT_IB_NF: |
1285 | dev_dbg(component->dev, "%s : %s\n" , |
1286 | __func__, "Invert BCLK + Normal Frame" ); |
1287 | ret += sma1303_regmap_update_bits(sma1303, |
1288 | SMA1303_01_INPUT1_CTRL1, |
1289 | SMA1303_SCK_RISING_MASK, |
1290 | SMA1303_SCK_RISING_EDGE, |
1291 | NULL); |
1292 | break; |
1293 | case SND_SOC_DAIFMT_IB_IF: |
1294 | dev_dbg(component->dev, "%s : %s\n" , |
1295 | __func__, "Invert BCLK + Invert Frame" ); |
1296 | ret += sma1303_regmap_update_bits(sma1303, |
1297 | SMA1303_01_INPUT1_CTRL1, |
1298 | SMA1303_LEFTPOL_MASK|SMA1303_SCK_RISING_MASK, |
1299 | SMA1303_HIGH_FIRST_CH|SMA1303_SCK_RISING_EDGE, |
1300 | NULL); |
1301 | break; |
1302 | case SND_SOC_DAIFMT_NB_IF: |
1303 | dev_dbg(component->dev, "%s : %s\n" , |
1304 | __func__, "Normal BCLK + Invert Frame" ); |
1305 | ret += sma1303_regmap_update_bits(sma1303, |
1306 | SMA1303_01_INPUT1_CTRL1, |
1307 | SMA1303_LEFTPOL_MASK, |
1308 | SMA1303_HIGH_FIRST_CH, |
1309 | NULL); |
1310 | break; |
1311 | case SND_SOC_DAIFMT_NB_NF: |
1312 | dev_dbg(component->dev, "%s : %s\n" , |
1313 | __func__, "Normal BCLK + Normal Frame" ); |
1314 | break; |
1315 | default: |
1316 | dev_err(component->dev, |
1317 | "Unsupported Bit & Frameclock : 0x%x\n" , fmt); |
1318 | return -EINVAL; |
1319 | } |
1320 | |
1321 | if (ret < 0) |
1322 | return -EINVAL; |
1323 | return 0; |
1324 | } |
1325 | |
1326 | static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai, |
1327 | unsigned int tx_mask, unsigned int rx_mask, |
1328 | int slots, int slot_width) |
1329 | { |
1330 | struct snd_soc_component *component = dai->component; |
1331 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
1332 | int ret = 0; |
1333 | |
1334 | dev_dbg(component->dev, "%s : slots = %d, slot_width - %d\n" , |
1335 | __func__, slots, slot_width); |
1336 | |
1337 | sma1303->frame_size = slot_width * slots; |
1338 | |
1339 | ret += sma1303_regmap_update_bits(sma1303, |
1340 | SMA1303_A4_TOP_MAN3, |
1341 | SMA1303_O_FORMAT_MASK, |
1342 | SMA1303_O_FMT_TDM, |
1343 | NULL); |
1344 | |
1345 | switch (slot_width) { |
1346 | case 16: |
1347 | ret += sma1303_regmap_update_bits(sma1303, |
1348 | SMA1303_A6_TDM2, |
1349 | SMA1303_TDM_DL_MASK, |
1350 | SMA1303_TDM_DL_16, |
1351 | NULL); |
1352 | break; |
1353 | case 32: |
1354 | ret += sma1303_regmap_update_bits(sma1303, |
1355 | SMA1303_A6_TDM2, |
1356 | SMA1303_TDM_DL_MASK, |
1357 | SMA1303_TDM_DL_32, |
1358 | NULL); |
1359 | break; |
1360 | default: |
1361 | dev_err(component->dev, "%s not support TDM %d slot_width\n" , |
1362 | __func__, slot_width); |
1363 | break; |
1364 | } |
1365 | |
1366 | switch (slots) { |
1367 | case 4: |
1368 | ret += sma1303_regmap_update_bits(sma1303, |
1369 | SMA1303_A6_TDM2, |
1370 | SMA1303_TDM_N_SLOT_MASK, |
1371 | SMA1303_TDM_N_SLOT_4, |
1372 | NULL); |
1373 | break; |
1374 | case 8: |
1375 | ret += sma1303_regmap_update_bits(sma1303, |
1376 | SMA1303_A6_TDM2, |
1377 | SMA1303_TDM_N_SLOT_MASK, |
1378 | SMA1303_TDM_N_SLOT_8, |
1379 | NULL); |
1380 | break; |
1381 | default: |
1382 | dev_err(component->dev, "%s not support TDM %d slots\n" , |
1383 | __func__, slots); |
1384 | break; |
1385 | } |
1386 | |
1387 | if (sma1303->tdm_slot_rx < slots) |
1388 | ret += sma1303_regmap_update_bits(sma1303, |
1389 | SMA1303_A5_TDM1, |
1390 | SMA1303_TDM_SLOT1_RX_POS_MASK, |
1391 | val: (sma1303->tdm_slot_rx) << 3, |
1392 | NULL); |
1393 | else |
1394 | dev_err(component->dev, "%s Incorrect tdm-slot-rx %d set\n" , |
1395 | __func__, sma1303->tdm_slot_rx); |
1396 | |
1397 | ret += sma1303_regmap_update_bits(sma1303, |
1398 | SMA1303_A5_TDM1, |
1399 | SMA1303_TDM_CLK_POL_MASK, |
1400 | SMA1303_TDM_CLK_POL_RISE, |
1401 | NULL); |
1402 | |
1403 | ret += sma1303_regmap_update_bits(sma1303, |
1404 | SMA1303_A5_TDM1, |
1405 | SMA1303_TDM_TX_MODE_MASK, |
1406 | SMA1303_TDM_TX_MONO, |
1407 | NULL); |
1408 | |
1409 | if (sma1303->tdm_slot_tx < slots) |
1410 | ret += sma1303_regmap_update_bits(sma1303, |
1411 | SMA1303_A6_TDM2, |
1412 | SMA1303_TDM_SLOT1_TX_POS_MASK, |
1413 | val: (sma1303->tdm_slot_tx) << 3, |
1414 | NULL); |
1415 | else |
1416 | dev_err(component->dev, "%s Incorrect tdm-slot-tx %d set\n" , |
1417 | __func__, sma1303->tdm_slot_tx); |
1418 | |
1419 | if (ret < 0) |
1420 | return -EINVAL; |
1421 | return 0; |
1422 | } |
1423 | |
1424 | static const struct snd_soc_dai_ops sma1303_dai_ops_amp = { |
1425 | .set_sysclk = sma1303_dai_set_sysclk_amp, |
1426 | .set_fmt = sma1303_dai_set_fmt_amp, |
1427 | .hw_params = sma1303_dai_hw_params_amp, |
1428 | .mute_stream = sma1303_dai_mute, |
1429 | .set_tdm_slot = sma1303_dai_set_tdm_slot, |
1430 | }; |
1431 | |
1432 | #define SMA1303_RATES SNDRV_PCM_RATE_8000_192000 |
1433 | #define SMA1303_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
1434 | SNDRV_PCM_FMTBIT_S32_LE) |
1435 | |
1436 | static struct snd_soc_dai_driver sma1303_dai[] = { |
1437 | { |
1438 | .name = "sma1303-amplifier" , |
1439 | .id = 0, |
1440 | .playback = { |
1441 | .stream_name = "Playback" , |
1442 | .channels_min = 1, |
1443 | .channels_max = 2, |
1444 | .rates = SMA1303_RATES, |
1445 | .formats = SMA1303_FORMATS, |
1446 | }, |
1447 | .capture = { |
1448 | .stream_name = "Capture" , |
1449 | .channels_min = 1, |
1450 | .channels_max = 2, |
1451 | .rates = SMA1303_RATES, |
1452 | .formats = SMA1303_FORMATS, |
1453 | }, |
1454 | .ops = &sma1303_dai_ops_amp, |
1455 | }, |
1456 | }; |
1457 | |
1458 | static void sma1303_check_fault_worker(struct work_struct *work) |
1459 | { |
1460 | struct sma1303_priv *sma1303 = |
1461 | container_of(work, struct sma1303_priv, check_fault_work.work); |
1462 | int ret = 0; |
1463 | unsigned int over_temp, ocp_val, uvlo_val; |
1464 | |
1465 | if (sma1303->tsdw_cnt) |
1466 | ret = sma1303_regmap_read(sma1303, |
1467 | SMA1303_0A_SPK_VOL, val: &sma1303->cur_vol); |
1468 | else |
1469 | ret = sma1303_regmap_read(sma1303, |
1470 | SMA1303_0A_SPK_VOL, val: &sma1303->init_vol); |
1471 | |
1472 | if (ret != 0) { |
1473 | dev_err(sma1303->dev, |
1474 | "failed to read SMA1303_0A_SPK_VOL : %d\n" , ret); |
1475 | return; |
1476 | } |
1477 | |
1478 | ret = sma1303_regmap_read(sma1303, SMA1303_FA_STATUS1, val: &over_temp); |
1479 | if (ret != 0) { |
1480 | dev_err(sma1303->dev, |
1481 | "failed to read SMA1303_FA_STATUS1 : %d\n" , ret); |
1482 | return; |
1483 | } |
1484 | |
1485 | ret = sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, val: &ocp_val); |
1486 | if (ret != 0) { |
1487 | dev_err(sma1303->dev, |
1488 | "failed to read SMA1303_FB_STATUS2 : %d\n" , ret); |
1489 | return; |
1490 | } |
1491 | |
1492 | ret = sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, val: &uvlo_val); |
1493 | if (ret != 0) { |
1494 | dev_err(sma1303->dev, |
1495 | "failed to read SMA1303_FF_DEVICE_INDEX : %d\n" , ret); |
1496 | return; |
1497 | } |
1498 | |
1499 | if (~over_temp & SMA1303_OT1_OK_STATUS) { |
1500 | dev_crit(sma1303->dev, |
1501 | "%s : OT1(Over Temperature Level 1)\n" , __func__); |
1502 | |
1503 | if ((sma1303->cur_vol + 6) <= 0xFF) |
1504 | sma1303_regmap_write(sma1303, |
1505 | SMA1303_0A_SPK_VOL, val: sma1303->cur_vol + 6); |
1506 | |
1507 | sma1303->tsdw_cnt++; |
1508 | } else if (sma1303->tsdw_cnt) { |
1509 | sma1303_regmap_write(sma1303, |
1510 | SMA1303_0A_SPK_VOL, val: sma1303->init_vol); |
1511 | sma1303->tsdw_cnt = 0; |
1512 | sma1303->cur_vol = sma1303->init_vol; |
1513 | } |
1514 | |
1515 | if (~over_temp & SMA1303_OT2_OK_STATUS) { |
1516 | dev_crit(sma1303->dev, |
1517 | "%s : OT2(Over Temperature Level 2)\n" , __func__); |
1518 | } |
1519 | if (ocp_val & SMA1303_OCP_SPK_STATUS) { |
1520 | dev_crit(sma1303->dev, |
1521 | "%s : OCP_SPK(Over Current Protect SPK)\n" , __func__); |
1522 | } |
1523 | if (ocp_val & SMA1303_OCP_BST_STATUS) { |
1524 | dev_crit(sma1303->dev, |
1525 | "%s : OCP_BST(Over Current Protect Boost)\n" , __func__); |
1526 | } |
1527 | if ((ocp_val & SMA1303_CLK_MON_STATUS) && (sma1303->amp_power_status)) { |
1528 | dev_crit(sma1303->dev, |
1529 | "%s : CLK_FAULT(No clock input)\n" , __func__); |
1530 | } |
1531 | if (uvlo_val & SMA1303_UVLO_BST_STATUS) { |
1532 | dev_crit(sma1303->dev, |
1533 | "%s : UVLO(Under Voltage Lock Out)\n" , __func__); |
1534 | } |
1535 | |
1536 | if ((over_temp != sma1303->last_over_temp) || |
1537 | (ocp_val != sma1303->last_ocp_val)) { |
1538 | |
1539 | dev_crit(sma1303->dev, "Please check AMP status" ); |
1540 | dev_dbg(sma1303->dev, "STATUS1=0x%02X : STATUS2=0x%02X\n" , |
1541 | over_temp, ocp_val); |
1542 | sma1303->last_over_temp = over_temp; |
1543 | sma1303->last_ocp_val = ocp_val; |
1544 | } |
1545 | |
1546 | if (sma1303->check_fault_status) { |
1547 | if (sma1303->check_fault_period > 0) |
1548 | queue_delayed_work(wq: system_freezable_wq, |
1549 | dwork: &sma1303->check_fault_work, |
1550 | delay: sma1303->check_fault_period * HZ); |
1551 | else |
1552 | queue_delayed_work(wq: system_freezable_wq, |
1553 | dwork: &sma1303->check_fault_work, |
1554 | CHECK_PERIOD_TIME * HZ); |
1555 | } |
1556 | |
1557 | if (!(~over_temp & SMA1303_OT1_OK_STATUS) |
1558 | && !(~over_temp & SMA1303_OT2_OK_STATUS) |
1559 | && !(ocp_val & SMA1303_OCP_SPK_STATUS) |
1560 | && !(ocp_val & SMA1303_OCP_BST_STATUS) |
1561 | && !(ocp_val & SMA1303_CLK_MON_STATUS) |
1562 | && !(uvlo_val & SMA1303_UVLO_BST_STATUS)) { |
1563 | } |
1564 | } |
1565 | |
1566 | static int sma1303_probe(struct snd_soc_component *component) |
1567 | { |
1568 | struct snd_soc_dapm_context *dapm = |
1569 | snd_soc_component_get_dapm(component); |
1570 | |
1571 | snd_soc_dapm_sync(dapm); |
1572 | |
1573 | return 0; |
1574 | } |
1575 | |
1576 | static void sma1303_remove(struct snd_soc_component *component) |
1577 | { |
1578 | struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(c: component); |
1579 | |
1580 | cancel_delayed_work_sync(dwork: &sma1303->check_fault_work); |
1581 | } |
1582 | |
1583 | static const struct snd_soc_component_driver sma1303_component = { |
1584 | .probe = sma1303_probe, |
1585 | .remove = sma1303_remove, |
1586 | .controls = sma1303_snd_controls, |
1587 | .num_controls = ARRAY_SIZE(sma1303_snd_controls), |
1588 | .dapm_widgets = sma1303_dapm_widgets, |
1589 | .num_dapm_widgets = ARRAY_SIZE(sma1303_dapm_widgets), |
1590 | .dapm_routes = sma1303_audio_map, |
1591 | .num_dapm_routes = ARRAY_SIZE(sma1303_audio_map), |
1592 | }; |
1593 | |
1594 | static const struct regmap_config sma_i2c_regmap = { |
1595 | .reg_bits = 8, |
1596 | .val_bits = 8, |
1597 | |
1598 | .max_register = SMA1303_FF_DEVICE_INDEX, |
1599 | .readable_reg = sma1303_readable_register, |
1600 | .writeable_reg = sma1303_writeable_register, |
1601 | .volatile_reg = sma1303_volatile_register, |
1602 | |
1603 | .cache_type = REGCACHE_NONE, |
1604 | .reg_defaults = sma1303_reg_def, |
1605 | .num_reg_defaults = ARRAY_SIZE(sma1303_reg_def), |
1606 | }; |
1607 | |
1608 | static ssize_t check_fault_period_show(struct device *dev, |
1609 | struct device_attribute *devattr, char *buf) |
1610 | { |
1611 | struct sma1303_priv *sma1303 = dev_get_drvdata(dev); |
1612 | |
1613 | return sysfs_emit(buf, fmt: "%ld\n" , sma1303->check_fault_period); |
1614 | } |
1615 | |
1616 | static ssize_t check_fault_period_store(struct device *dev, |
1617 | struct device_attribute *devattr, const char *buf, size_t count) |
1618 | { |
1619 | struct sma1303_priv *sma1303 = dev_get_drvdata(dev); |
1620 | int ret; |
1621 | |
1622 | ret = kstrtol(s: buf, base: 10, res: &sma1303->check_fault_period); |
1623 | |
1624 | if (ret) |
1625 | return -EINVAL; |
1626 | |
1627 | return (ssize_t)count; |
1628 | } |
1629 | |
1630 | static DEVICE_ATTR_RW(check_fault_period); |
1631 | |
1632 | static ssize_t check_fault_status_show(struct device *dev, |
1633 | struct device_attribute *devattr, char *buf) |
1634 | { |
1635 | struct sma1303_priv *sma1303 = dev_get_drvdata(dev); |
1636 | |
1637 | return sysfs_emit(buf, fmt: "%ld\n" , sma1303->check_fault_status); |
1638 | } |
1639 | |
1640 | static ssize_t check_fault_status_store(struct device *dev, |
1641 | struct device_attribute *devattr, const char *buf, size_t count) |
1642 | { |
1643 | struct sma1303_priv *sma1303 = dev_get_drvdata(dev); |
1644 | int ret; |
1645 | |
1646 | ret = kstrtol(s: buf, base: 10, res: &sma1303->check_fault_status); |
1647 | |
1648 | if (ret) |
1649 | return -EINVAL; |
1650 | |
1651 | if (sma1303->check_fault_status) { |
1652 | if (sma1303->check_fault_period > 0) |
1653 | queue_delayed_work(wq: system_freezable_wq, |
1654 | dwork: &sma1303->check_fault_work, |
1655 | delay: sma1303->check_fault_period * HZ); |
1656 | else |
1657 | queue_delayed_work(wq: system_freezable_wq, |
1658 | dwork: &sma1303->check_fault_work, |
1659 | CHECK_PERIOD_TIME * HZ); |
1660 | } |
1661 | |
1662 | return (ssize_t)count; |
1663 | } |
1664 | |
1665 | static DEVICE_ATTR_RW(check_fault_status); |
1666 | |
1667 | static struct attribute *sma1303_attr[] = { |
1668 | &dev_attr_check_fault_period.attr, |
1669 | &dev_attr_check_fault_status.attr, |
1670 | NULL, |
1671 | }; |
1672 | |
1673 | static struct attribute_group sma1303_attr_group = { |
1674 | .attrs = sma1303_attr, |
1675 | }; |
1676 | |
1677 | static int sma1303_i2c_probe(struct i2c_client *client) |
1678 | { |
1679 | struct sma1303_priv *sma1303; |
1680 | int ret, i = 0; |
1681 | unsigned int device_info, status, otp_stat; |
1682 | |
1683 | sma1303 = devm_kzalloc(dev: &client->dev, |
1684 | size: sizeof(struct sma1303_priv), GFP_KERNEL); |
1685 | if (!sma1303) |
1686 | return -ENOMEM; |
1687 | sma1303->dev = &client->dev; |
1688 | |
1689 | sma1303->regmap = devm_regmap_init_i2c(client, &sma_i2c_regmap); |
1690 | if (IS_ERR(ptr: sma1303->regmap)) { |
1691 | ret = PTR_ERR(ptr: sma1303->regmap); |
1692 | dev_err(&client->dev, |
1693 | "Failed to allocate register map: %d\n" , ret); |
1694 | |
1695 | return ret; |
1696 | } |
1697 | |
1698 | ret = sma1303_regmap_read(sma1303, |
1699 | SMA1303_FF_DEVICE_INDEX, val: &device_info); |
1700 | |
1701 | if ((ret != 0) || ((device_info & 0xF8) != SMA1303_DEVICE_ID)) { |
1702 | dev_err(&client->dev, "device initialization error (%d 0x%02X)" , |
1703 | ret, device_info); |
1704 | } |
1705 | dev_dbg(&client->dev, "chip version 0x%02X\n" , device_info); |
1706 | |
1707 | ret += sma1303_regmap_update_bits(sma1303, |
1708 | SMA1303_00_SYSTEM_CTRL, |
1709 | SMA1303_RESETBYI2C_MASK, SMA1303_RESETBYI2C_RESET, |
1710 | NULL); |
1711 | |
1712 | ret += sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, val: &status); |
1713 | sma1303->rev_num = status & SMA1303_REV_NUM_STATUS; |
1714 | if (sma1303->rev_num == SMA1303_REV_NUM_TV0) |
1715 | dev_dbg(&client->dev, "SMA1303 Trimming Version 0\n" ); |
1716 | else if (sma1303->rev_num == SMA1303_REV_NUM_TV1) |
1717 | dev_dbg(&client->dev, "SMA1303 Trimming Version 1\n" ); |
1718 | |
1719 | ret += sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, val: &otp_stat); |
1720 | if (ret < 0) |
1721 | dev_err(&client->dev, |
1722 | "failed to read, register: %02X, ret: %d\n" , |
1723 | SMA1303_FF_DEVICE_INDEX, ret); |
1724 | |
1725 | if (((sma1303->rev_num == SMA1303_REV_NUM_TV0) && |
1726 | ((otp_stat & 0x0E) == SMA1303_OTP_STAT_OK_0)) || |
1727 | ((sma1303->rev_num != SMA1303_REV_NUM_TV0) && |
1728 | ((otp_stat & 0x0C) == SMA1303_OTP_STAT_OK_1))) |
1729 | dev_dbg(&client->dev, "SMA1303 OTP Status Successful\n" ); |
1730 | else |
1731 | dev_dbg(&client->dev, "SMA1303 OTP Status Fail\n" ); |
1732 | |
1733 | for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1303_reg_def); i++) |
1734 | ret += sma1303_regmap_write(sma1303, |
1735 | reg: sma1303_reg_def[i].reg, |
1736 | val: sma1303_reg_def[i].def); |
1737 | |
1738 | sma1303->amp_mode = SMA1303_MONO; |
1739 | sma1303->amp_power_status = false; |
1740 | sma1303->check_fault_period = CHECK_PERIOD_TIME; |
1741 | sma1303->check_fault_status = true; |
1742 | sma1303->force_mute_status = false; |
1743 | sma1303->init_vol = 0x31; |
1744 | sma1303->cur_vol = sma1303->init_vol; |
1745 | sma1303->last_bclk = 0; |
1746 | sma1303->last_ocp_val = 0x08; |
1747 | sma1303->last_over_temp = 0xC0; |
1748 | sma1303->tsdw_cnt = 0; |
1749 | sma1303->retry_cnt = SMA1303_I2C_RETRY_COUNT; |
1750 | sma1303->tdm_slot_rx = 0; |
1751 | sma1303->tdm_slot_tx = 0; |
1752 | sma1303->sys_clk_id = SMA1303_PLL_CLKIN_BCLK; |
1753 | |
1754 | sma1303->dev = &client->dev; |
1755 | sma1303->kobj = &client->dev.kobj; |
1756 | |
1757 | INIT_DELAYED_WORK(&sma1303->check_fault_work, |
1758 | sma1303_check_fault_worker); |
1759 | |
1760 | i2c_set_clientdata(client, data: sma1303); |
1761 | |
1762 | sma1303->pll_matches = sma1303_pll_matches; |
1763 | sma1303->num_of_pll_matches = |
1764 | ARRAY_SIZE(sma1303_pll_matches); |
1765 | |
1766 | ret = devm_snd_soc_register_component(dev: &client->dev, |
1767 | component_driver: &sma1303_component, dai_drv: sma1303_dai, num_dai: 1); |
1768 | if (ret) { |
1769 | dev_err(&client->dev, "Failed to register component" ); |
1770 | |
1771 | return ret; |
1772 | } |
1773 | |
1774 | sma1303->attr_grp = &sma1303_attr_group; |
1775 | ret = sysfs_create_group(kobj: sma1303->kobj, grp: sma1303->attr_grp); |
1776 | if (ret) { |
1777 | dev_err(&client->dev, |
1778 | "failed to create attribute group [%d]\n" , ret); |
1779 | sma1303->attr_grp = NULL; |
1780 | } |
1781 | |
1782 | return ret; |
1783 | } |
1784 | |
1785 | static void sma1303_i2c_remove(struct i2c_client *client) |
1786 | { |
1787 | struct sma1303_priv *sma1303 = |
1788 | (struct sma1303_priv *) i2c_get_clientdata(client); |
1789 | |
1790 | cancel_delayed_work_sync(dwork: &sma1303->check_fault_work); |
1791 | } |
1792 | |
1793 | static const struct i2c_device_id sma1303_i2c_id[] = { |
1794 | {"sma1303" , 0}, |
1795 | {} |
1796 | }; |
1797 | MODULE_DEVICE_TABLE(i2c, sma1303_i2c_id); |
1798 | |
1799 | static const struct of_device_id sma1303_of_match[] = { |
1800 | { .compatible = "irondevice,sma1303" , }, |
1801 | { } |
1802 | }; |
1803 | MODULE_DEVICE_TABLE(of, sma1303_of_match); |
1804 | |
1805 | static struct i2c_driver sma1303_i2c_driver = { |
1806 | .driver = { |
1807 | .name = "sma1303" , |
1808 | .of_match_table = sma1303_of_match, |
1809 | }, |
1810 | .probe = sma1303_i2c_probe, |
1811 | .remove = sma1303_i2c_remove, |
1812 | .id_table = sma1303_i2c_id, |
1813 | }; |
1814 | |
1815 | module_i2c_driver(sma1303_i2c_driver); |
1816 | |
1817 | MODULE_DESCRIPTION("ALSA SoC SMA1303 driver" ); |
1818 | MODULE_AUTHOR("Gyuhwa Park, <gyuhwa.park@irondevice.com>" ); |
1819 | MODULE_AUTHOR("Kiseok Jo, <kiseok.jo@irondevice.com>" ); |
1820 | MODULE_LICENSE("GPL v2" ); |
1821 | |