~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/pcm3168a.c

Version: ~ [ linux-5.2-rc6 ] ~ [ linux-5.1.15 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.56 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.130 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.183 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.183 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.69 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * PCM3168A codec driver
  4  *
  5  * Copyright (C) 2015 Imagination Technologies Ltd.
  6  *
  7  * Author: Damien Horsley <Damien.Horsley@imgtec.com>
  8  */
  9 
 10 #include <linux/clk.h>
 11 #include <linux/delay.h>
 12 #include <linux/module.h>
 13 #include <linux/pm_runtime.h>
 14 #include <linux/regulator/consumer.h>
 15 
 16 #include <sound/pcm_params.h>
 17 #include <sound/soc.h>
 18 #include <sound/tlv.h>
 19 
 20 #include "pcm3168a.h"
 21 
 22 #define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
 23                          SNDRV_PCM_FMTBIT_S24_3LE | \
 24                          SNDRV_PCM_FMTBIT_S24_LE | \
 25                          SNDRV_PCM_FMTBIT_S32_LE)
 26 
 27 #define PCM3168A_FMT_I2S                0x0
 28 #define PCM3168A_FMT_LEFT_J             0x1
 29 #define PCM3168A_FMT_RIGHT_J            0x2
 30 #define PCM3168A_FMT_RIGHT_J_16         0x3
 31 #define PCM3168A_FMT_DSP_A              0x4
 32 #define PCM3168A_FMT_DSP_B              0x5
 33 #define PCM3168A_FMT_I2S_TDM            0x6
 34 #define PCM3168A_FMT_LEFT_J_TDM         0x7
 35 #define PCM3168A_FMT_DSP_MASK           0x4
 36 
 37 #define PCM3168A_NUM_SUPPLIES 6
 38 static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
 39         "VDD1",
 40         "VDD2",
 41         "VCCAD1",
 42         "VCCAD2",
 43         "VCCDA1",
 44         "VCCDA2"
 45 };
 46 
 47 struct pcm3168a_priv {
 48         struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
 49         struct regmap *regmap;
 50         struct clk *scki;
 51         bool adc_master_mode;
 52         bool dac_master_mode;
 53         unsigned long sysclk;
 54         unsigned int adc_fmt;
 55         unsigned int dac_fmt;
 56 };
 57 
 58 static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
 59 
 60 static SOC_ENUM_SINGLE_DECL(pcm3168a_d1_roll_off, PCM3168A_DAC_OP_FLT,
 61                 PCM3168A_DAC_FLT_SHIFT, pcm3168a_roll_off);
 62 static SOC_ENUM_SINGLE_DECL(pcm3168a_d2_roll_off, PCM3168A_DAC_OP_FLT,
 63                 PCM3168A_DAC_FLT_SHIFT + 1, pcm3168a_roll_off);
 64 static SOC_ENUM_SINGLE_DECL(pcm3168a_d3_roll_off, PCM3168A_DAC_OP_FLT,
 65                 PCM3168A_DAC_FLT_SHIFT + 2, pcm3168a_roll_off);
 66 static SOC_ENUM_SINGLE_DECL(pcm3168a_d4_roll_off, PCM3168A_DAC_OP_FLT,
 67                 PCM3168A_DAC_FLT_SHIFT + 3, pcm3168a_roll_off);
 68 
 69 static const char *const pcm3168a_volume_type[] = {
 70                 "Individual", "Master + Individual" };
 71 
 72 static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_volume_type, PCM3168A_DAC_ATT_DEMP_ZF,
 73                 PCM3168A_DAC_ATMDDA_SHIFT, pcm3168a_volume_type);
 74 
 75 static const char *const pcm3168a_att_speed_mult[] = { "2048", "4096" };
 76 
 77 static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_att_mult, PCM3168A_DAC_ATT_DEMP_ZF,
 78                 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_att_speed_mult);
 79 
 80 static const char *const pcm3168a_demp[] = {
 81                 "Disabled", "48khz", "44.1khz", "32khz" };
 82 
 83 static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_demp, PCM3168A_DAC_ATT_DEMP_ZF,
 84                 PCM3168A_DAC_DEMP_SHIFT, pcm3168a_demp);
 85 
 86 static const char *const pcm3168a_zf_func[] = {
 87                 "DAC 1/2/3/4 AND", "DAC 1/2/3/4 OR", "DAC 1/2/3 AND",
 88                 "DAC 1/2/3 OR", "DAC 4 AND", "DAC 4 OR" };
 89 
 90 static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_func, PCM3168A_DAC_ATT_DEMP_ZF,
 91                 PCM3168A_DAC_AZRO_SHIFT, pcm3168a_zf_func);
 92 
 93 static const char *const pcm3168a_pol[] = { "Active High", "Active Low" };
 94 
 95 static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_pol, PCM3168A_DAC_ATT_DEMP_ZF,
 96                 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_pol);
 97 
 98 static const char *const pcm3168a_con[] = { "Differential", "Single-Ended" };
 99 
100 static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc1_con, PCM3168A_ADC_SEAD,
101                                 0, 1, pcm3168a_con);
102 static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc2_con, PCM3168A_ADC_SEAD,
103                                 2, 3, pcm3168a_con);
104 static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc3_con, PCM3168A_ADC_SEAD,
105                                 4, 5, pcm3168a_con);
106 
107 static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_volume_type, PCM3168A_ADC_ATT_OVF,
108                 PCM3168A_ADC_ATMDAD_SHIFT, pcm3168a_volume_type);
109 
110 static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_att_mult, PCM3168A_ADC_ATT_OVF,
111                 PCM3168A_ADC_ATSPAD_SHIFT, pcm3168a_att_speed_mult);
112 
113 static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_ov_pol, PCM3168A_ADC_ATT_OVF,
114                 PCM3168A_ADC_OVFP_SHIFT, pcm3168a_pol);
115 
116 /* -100db to 0db, register values 0-54 cause mute */
117 static const DECLARE_TLV_DB_SCALE(pcm3168a_dac_tlv, -10050, 50, 1);
118 
119 /* -100db to 20db, register values 0-14 cause mute */
120 static const DECLARE_TLV_DB_SCALE(pcm3168a_adc_tlv, -10050, 50, 1);
121 
122 static const struct snd_kcontrol_new pcm3168a_snd_controls[] = {
123         SOC_SINGLE("DAC Power-Save Switch", PCM3168A_DAC_PWR_MST_FMT,
124                         PCM3168A_DAC_PSMDA_SHIFT, 1, 1),
125         SOC_ENUM("DAC1 Digital Filter roll-off", pcm3168a_d1_roll_off),
126         SOC_ENUM("DAC2 Digital Filter roll-off", pcm3168a_d2_roll_off),
127         SOC_ENUM("DAC3 Digital Filter roll-off", pcm3168a_d3_roll_off),
128         SOC_ENUM("DAC4 Digital Filter roll-off", pcm3168a_d4_roll_off),
129         SOC_DOUBLE("DAC1 Invert Switch", PCM3168A_DAC_INV, 0, 1, 1, 0),
130         SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
131         SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
132         SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
133         SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type),
134         SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult),
135         SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
136         SOC_ENUM("DAC Zero Flag Function", pcm3168a_dac_zf_func),
137         SOC_ENUM("DAC Zero Flag Polarity", pcm3168a_dac_zf_pol),
138         SOC_SINGLE_RANGE_TLV("Master Playback Volume",
139                         PCM3168A_DAC_VOL_MASTER, 0, 54, 255, 0,
140                         pcm3168a_dac_tlv),
141         SOC_DOUBLE_R_RANGE_TLV("DAC1 Playback Volume",
142                         PCM3168A_DAC_VOL_CHAN_START,
143                         PCM3168A_DAC_VOL_CHAN_START + 1,
144                         0, 54, 255, 0, pcm3168a_dac_tlv),
145         SOC_DOUBLE_R_RANGE_TLV("DAC2 Playback Volume",
146                         PCM3168A_DAC_VOL_CHAN_START + 2,
147                         PCM3168A_DAC_VOL_CHAN_START + 3,
148                         0, 54, 255, 0, pcm3168a_dac_tlv),
149         SOC_DOUBLE_R_RANGE_TLV("DAC3 Playback Volume",
150                         PCM3168A_DAC_VOL_CHAN_START + 4,
151                         PCM3168A_DAC_VOL_CHAN_START + 5,
152                         0, 54, 255, 0, pcm3168a_dac_tlv),
153         SOC_DOUBLE_R_RANGE_TLV("DAC4 Playback Volume",
154                         PCM3168A_DAC_VOL_CHAN_START + 6,
155                         PCM3168A_DAC_VOL_CHAN_START + 7,
156                         0, 54, 255, 0, pcm3168a_dac_tlv),
157         SOC_SINGLE("ADC1 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
158                         PCM3168A_ADC_BYP_SHIFT, 1, 1),
159         SOC_SINGLE("ADC2 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
160                         PCM3168A_ADC_BYP_SHIFT + 1, 1, 1),
161         SOC_SINGLE("ADC3 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
162                         PCM3168A_ADC_BYP_SHIFT + 2, 1, 1),
163         SOC_ENUM("ADC1 Connection Type", pcm3168a_adc1_con),
164         SOC_ENUM("ADC2 Connection Type", pcm3168a_adc2_con),
165         SOC_ENUM("ADC3 Connection Type", pcm3168a_adc3_con),
166         SOC_DOUBLE("ADC1 Invert Switch", PCM3168A_ADC_INV, 0, 1, 1, 0),
167         SOC_DOUBLE("ADC2 Invert Switch", PCM3168A_ADC_INV, 2, 3, 1, 0),
168         SOC_DOUBLE("ADC3 Invert Switch", PCM3168A_ADC_INV, 4, 5, 1, 0),
169         SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0),
170         SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0),
171         SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0),
172         SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type),
173         SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult),
174         SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol),
175         SOC_SINGLE_RANGE_TLV("Master Capture Volume",
176                         PCM3168A_ADC_VOL_MASTER, 0, 14, 255, 0,
177                         pcm3168a_adc_tlv),
178         SOC_DOUBLE_R_RANGE_TLV("ADC1 Capture Volume",
179                         PCM3168A_ADC_VOL_CHAN_START,
180                         PCM3168A_ADC_VOL_CHAN_START + 1,
181                         0, 14, 255, 0, pcm3168a_adc_tlv),
182         SOC_DOUBLE_R_RANGE_TLV("ADC2 Capture Volume",
183                         PCM3168A_ADC_VOL_CHAN_START + 2,
184                         PCM3168A_ADC_VOL_CHAN_START + 3,
185                         0, 14, 255, 0, pcm3168a_adc_tlv),
186         SOC_DOUBLE_R_RANGE_TLV("ADC3 Capture Volume",
187                         PCM3168A_ADC_VOL_CHAN_START + 4,
188                         PCM3168A_ADC_VOL_CHAN_START + 5,
189                         0, 14, 255, 0, pcm3168a_adc_tlv)
190 };
191 
192 static const struct snd_soc_dapm_widget pcm3168a_dapm_widgets[] = {
193         SND_SOC_DAPM_DAC("DAC1", "Playback", PCM3168A_DAC_OP_FLT,
194                         PCM3168A_DAC_OPEDA_SHIFT, 1),
195         SND_SOC_DAPM_DAC("DAC2", "Playback", PCM3168A_DAC_OP_FLT,
196                         PCM3168A_DAC_OPEDA_SHIFT + 1, 1),
197         SND_SOC_DAPM_DAC("DAC3", "Playback", PCM3168A_DAC_OP_FLT,
198                         PCM3168A_DAC_OPEDA_SHIFT + 2, 1),
199         SND_SOC_DAPM_DAC("DAC4", "Playback", PCM3168A_DAC_OP_FLT,
200                         PCM3168A_DAC_OPEDA_SHIFT + 3, 1),
201 
202         SND_SOC_DAPM_OUTPUT("AOUT1L"),
203         SND_SOC_DAPM_OUTPUT("AOUT1R"),
204         SND_SOC_DAPM_OUTPUT("AOUT2L"),
205         SND_SOC_DAPM_OUTPUT("AOUT2R"),
206         SND_SOC_DAPM_OUTPUT("AOUT3L"),
207         SND_SOC_DAPM_OUTPUT("AOUT3R"),
208         SND_SOC_DAPM_OUTPUT("AOUT4L"),
209         SND_SOC_DAPM_OUTPUT("AOUT4R"),
210 
211         SND_SOC_DAPM_ADC("ADC1", "Capture", PCM3168A_ADC_PWR_HPFB,
212                         PCM3168A_ADC_PSVAD_SHIFT, 1),
213         SND_SOC_DAPM_ADC("ADC2", "Capture", PCM3168A_ADC_PWR_HPFB,
214                         PCM3168A_ADC_PSVAD_SHIFT + 1, 1),
215         SND_SOC_DAPM_ADC("ADC3", "Capture", PCM3168A_ADC_PWR_HPFB,
216                         PCM3168A_ADC_PSVAD_SHIFT + 2, 1),
217 
218         SND_SOC_DAPM_INPUT("AIN1L"),
219         SND_SOC_DAPM_INPUT("AIN1R"),
220         SND_SOC_DAPM_INPUT("AIN2L"),
221         SND_SOC_DAPM_INPUT("AIN2R"),
222         SND_SOC_DAPM_INPUT("AIN3L"),
223         SND_SOC_DAPM_INPUT("AIN3R")
224 };
225 
226 static const struct snd_soc_dapm_route pcm3168a_dapm_routes[] = {
227         /* Playback */
228         { "AOUT1L", NULL, "DAC1" },
229         { "AOUT1R", NULL, "DAC1" },
230 
231         { "AOUT2L", NULL, "DAC2" },
232         { "AOUT2R", NULL, "DAC2" },
233 
234         { "AOUT3L", NULL, "DAC3" },
235         { "AOUT3R", NULL, "DAC3" },
236 
237         { "AOUT4L", NULL, "DAC4" },
238         { "AOUT4R", NULL, "DAC4" },
239 
240         /* Capture */
241         { "ADC1", NULL, "AIN1L" },
242         { "ADC1", NULL, "AIN1R" },
243 
244         { "ADC2", NULL, "AIN2L" },
245         { "ADC2", NULL, "AIN2R" },
246 
247         { "ADC3", NULL, "AIN3L" },
248         { "ADC3", NULL, "AIN3R" }
249 };
250 
251 static unsigned int pcm3168a_scki_ratios[] = {
252         768,
253         512,
254         384,
255         256,
256         192,
257         128
258 };
259 
260 #define PCM3168A_NUM_SCKI_RATIOS_DAC    ARRAY_SIZE(pcm3168a_scki_ratios)
261 #define PCM3168A_NUM_SCKI_RATIOS_ADC    (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
262 
263 #define PCM1368A_MAX_SYSCLK             36864000
264 
265 static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
266 {
267         int ret;
268 
269         ret = regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE, 0);
270         if (ret)
271                 return ret;
272 
273         /* Internal reset is de-asserted after 3846 SCKI cycles */
274         msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk));
275 
276         return regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE,
277                         PCM3168A_MRST_MASK | PCM3168A_SRST_MASK);
278 }
279 
280 static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
281 {
282         struct snd_soc_component *component = dai->component;
283         struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
284 
285         regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0);
286 
287         return 0;
288 }
289 
290 static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
291                                   int clk_id, unsigned int freq, int dir)
292 {
293         struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
294         int ret;
295 
296         if (freq > PCM1368A_MAX_SYSCLK)
297                 return -EINVAL;
298 
299         ret = clk_set_rate(pcm3168a->scki, freq);
300         if (ret)
301                 return ret;
302 
303         pcm3168a->sysclk = freq;
304 
305         return 0;
306 }
307 
308 static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
309                                unsigned int format, bool dac)
310 {
311         struct snd_soc_component *component = dai->component;
312         struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
313         u32 fmt, reg, mask, shift;
314         bool master_mode;
315 
316         switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
317         case SND_SOC_DAIFMT_LEFT_J:
318                 fmt = PCM3168A_FMT_LEFT_J;
319                 break;
320         case SND_SOC_DAIFMT_I2S:
321                 fmt = PCM3168A_FMT_I2S;
322                 break;
323         case SND_SOC_DAIFMT_RIGHT_J:
324                 fmt = PCM3168A_FMT_RIGHT_J;
325                 break;
326         case SND_SOC_DAIFMT_DSP_A:
327                 fmt = PCM3168A_FMT_DSP_A;
328                 break;
329         case SND_SOC_DAIFMT_DSP_B:
330                 fmt = PCM3168A_FMT_DSP_B;
331                 break;
332         default:
333                 dev_err(component->dev, "unsupported dai format\n");
334                 return -EINVAL;
335         }
336 
337         switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
338         case SND_SOC_DAIFMT_CBS_CFS:
339                 master_mode = false;
340                 break;
341         case SND_SOC_DAIFMT_CBM_CFM:
342                 master_mode = true;
343                 break;
344         default:
345                 dev_err(component->dev, "unsupported master/slave mode\n");
346                 return -EINVAL;
347         }
348 
349         switch (format & SND_SOC_DAIFMT_INV_MASK) {
350         case SND_SOC_DAIFMT_NB_NF:
351                 break;
352         default:
353                 return -EINVAL;
354         }
355 
356         if (dac) {
357                 reg = PCM3168A_DAC_PWR_MST_FMT;
358                 mask = PCM3168A_DAC_FMT_MASK;
359                 shift = PCM3168A_DAC_FMT_SHIFT;
360                 pcm3168a->dac_master_mode = master_mode;
361                 pcm3168a->dac_fmt = fmt;
362         } else {
363                 reg = PCM3168A_ADC_MST_FMT;
364                 mask = PCM3168A_ADC_FMTAD_MASK;
365                 shift = PCM3168A_ADC_FMTAD_SHIFT;
366                 pcm3168a->adc_master_mode = master_mode;
367                 pcm3168a->adc_fmt = fmt;
368         }
369 
370         regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
371 
372         return 0;
373 }
374 
375 static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
376                                unsigned int format)
377 {
378         return pcm3168a_set_dai_fmt(dai, format, true);
379 }
380 
381 static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
382                                unsigned int format)
383 {
384         return pcm3168a_set_dai_fmt(dai, format, false);
385 }
386 
387 static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
388                              struct snd_pcm_hw_params *params,
389                              struct snd_soc_dai *dai)
390 {
391         struct snd_soc_component *component = dai->component;
392         struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
393         bool tx, master_mode;
394         u32 val, mask, shift, reg;
395         unsigned int rate, fmt, ratio, max_ratio;
396         unsigned int chan;
397         int i, min_frame_size;
398 
399         rate = params_rate(params);
400         chan = params_channels(params);
401 
402         ratio = pcm3168a->sysclk / rate;
403 
404         tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
405         if (tx) {
406                 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
407                 reg = PCM3168A_DAC_PWR_MST_FMT;
408                 mask = PCM3168A_DAC_MSDA_MASK;
409                 shift = PCM3168A_DAC_MSDA_SHIFT;
410                 master_mode = pcm3168a->dac_master_mode;
411                 fmt = pcm3168a->dac_fmt;
412         } else {
413                 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
414                 reg = PCM3168A_ADC_MST_FMT;
415                 mask = PCM3168A_ADC_MSAD_MASK;
416                 shift = PCM3168A_ADC_MSAD_SHIFT;
417                 master_mode = pcm3168a->adc_master_mode;
418                 fmt = pcm3168a->adc_fmt;
419         }
420 
421         for (i = 0; i < max_ratio; i++) {
422                 if (pcm3168a_scki_ratios[i] == ratio)
423                         break;
424         }
425 
426         if (i == max_ratio) {
427                 dev_err(component->dev, "unsupported sysclk ratio\n");
428                 return -EINVAL;
429         }
430 
431         min_frame_size = params_width(params) * 2;
432         switch (min_frame_size) {
433         case 32:
434                 if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
435                         dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
436                         return -EINVAL;
437                 }
438                 fmt = PCM3168A_FMT_RIGHT_J_16;
439                 break;
440         case 48:
441                 if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
442                         dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
443                         return -EINVAL;
444                 }
445                 break;
446         case 64:
447                 break;
448         default:
449                 dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
450                 return -EINVAL;
451         }
452 
453         /* for TDM */
454         if (chan > 2) {
455                 switch (fmt) {
456                 case PCM3168A_FMT_I2S:
457                 case PCM3168A_FMT_DSP_A:
458                         fmt = PCM3168A_FMT_I2S_TDM;
459                         break;
460                 case PCM3168A_FMT_LEFT_J:
461                 case PCM3168A_FMT_DSP_B:
462                         fmt = PCM3168A_FMT_LEFT_J_TDM;
463                         break;
464                 default:
465                         dev_err(component->dev,
466                                 "TDM is supported under DSP/I2S/Left_J only\n");
467                         return -EINVAL;
468                 }
469         }
470 
471         if (master_mode)
472                 val = ((i + 1) << shift);
473         else
474                 val = 0;
475 
476         regmap_update_bits(pcm3168a->regmap, reg, mask, val);
477 
478         if (tx) {
479                 mask = PCM3168A_DAC_FMT_MASK;
480                 shift = PCM3168A_DAC_FMT_SHIFT;
481         } else {
482                 mask = PCM3168A_ADC_FMTAD_MASK;
483                 shift = PCM3168A_ADC_FMTAD_SHIFT;
484         }
485 
486         regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
487 
488         return 0;
489 }
490 
491 static int pcm3168a_startup(struct snd_pcm_substream *substream,
492                             struct snd_soc_dai *dai)
493 {
494         struct snd_soc_component *component = dai->component;
495         struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
496         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
497         unsigned int fmt;
498         unsigned int sample_min;
499         unsigned int channel_max;
500         unsigned int channel_maxs[] = {
501                 6, /* rx */
502                 8  /* tx */
503         };
504 
505         if (tx)
506                 fmt = pcm3168a->dac_fmt;
507         else
508                 fmt = pcm3168a->adc_fmt;
509 
510         /*
511          * Available Data Bits
512          *
513          * RIGHT_J : 24 / 16
514          * LEFT_J  : 24
515          * I2S     : 24
516          *
517          * TDM available
518          *
519          * I2S
520          * LEFT_J
521          */
522         switch (fmt) {
523         case PCM3168A_FMT_RIGHT_J:
524                 sample_min  = 16;
525                 channel_max =  2;
526                 break;
527         case PCM3168A_FMT_LEFT_J:
528         case PCM3168A_FMT_I2S:
529         case PCM3168A_FMT_DSP_A:
530         case PCM3168A_FMT_DSP_B:
531                 sample_min  = 24;
532                 channel_max = channel_maxs[tx];
533                 break;
534         default:
535                 sample_min  = 24;
536                 channel_max =  2;
537         }
538 
539         snd_pcm_hw_constraint_minmax(substream->runtime,
540                                      SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
541                                      sample_min, 32);
542 
543         snd_pcm_hw_constraint_minmax(substream->runtime,
544                                      SNDRV_PCM_HW_PARAM_CHANNELS,
545                                      2, channel_max);
546 
547         return 0;
548 }
549 static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
550         .startup        = pcm3168a_startup,
551         .set_fmt        = pcm3168a_set_dai_fmt_dac,
552         .set_sysclk     = pcm3168a_set_dai_sysclk,
553         .hw_params      = pcm3168a_hw_params,
554         .digital_mute   = pcm3168a_digital_mute
555 };
556 
557 static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
558         .startup        = pcm3168a_startup,
559         .set_fmt        = pcm3168a_set_dai_fmt_adc,
560         .set_sysclk     = pcm3168a_set_dai_sysclk,
561         .hw_params      = pcm3168a_hw_params
562 };
563 
564 static struct snd_soc_dai_driver pcm3168a_dais[] = {
565         {
566                 .name = "pcm3168a-dac",
567                 .playback = {
568                         .stream_name = "Playback",
569                         .channels_min = 1,
570                         .channels_max = 8,
571                         .rates = SNDRV_PCM_RATE_8000_192000,
572                         .formats = PCM3168A_FORMATS
573                 },
574                 .ops = &pcm3168a_dac_dai_ops
575         },
576         {
577                 .name = "pcm3168a-adc",
578                 .capture = {
579                         .stream_name = "Capture",
580                         .channels_min = 1,
581                         .channels_max = 6,
582                         .rates = SNDRV_PCM_RATE_8000_96000,
583                         .formats = PCM3168A_FORMATS
584                 },
585                 .ops = &pcm3168a_adc_dai_ops
586         },
587 };
588 
589 static const struct reg_default pcm3168a_reg_default[] = {
590         { PCM3168A_RST_SMODE, PCM3168A_MRST_MASK | PCM3168A_SRST_MASK },
591         { PCM3168A_DAC_PWR_MST_FMT, 0x00 },
592         { PCM3168A_DAC_OP_FLT, 0x00 },
593         { PCM3168A_DAC_INV, 0x00 },
594         { PCM3168A_DAC_MUTE, 0x00 },
595         { PCM3168A_DAC_ZERO, 0x00 },
596         { PCM3168A_DAC_ATT_DEMP_ZF, 0x00 },
597         { PCM3168A_DAC_VOL_MASTER, 0xff },
598         { PCM3168A_DAC_VOL_CHAN_START, 0xff },
599         { PCM3168A_DAC_VOL_CHAN_START + 1, 0xff },
600         { PCM3168A_DAC_VOL_CHAN_START + 2, 0xff },
601         { PCM3168A_DAC_VOL_CHAN_START + 3, 0xff },
602         { PCM3168A_DAC_VOL_CHAN_START + 4, 0xff },
603         { PCM3168A_DAC_VOL_CHAN_START + 5, 0xff },
604         { PCM3168A_DAC_VOL_CHAN_START + 6, 0xff },
605         { PCM3168A_DAC_VOL_CHAN_START + 7, 0xff },
606         { PCM3168A_ADC_SMODE, 0x00 },
607         { PCM3168A_ADC_MST_FMT, 0x00 },
608         { PCM3168A_ADC_PWR_HPFB, 0x00 },
609         { PCM3168A_ADC_SEAD, 0x00 },
610         { PCM3168A_ADC_INV, 0x00 },
611         { PCM3168A_ADC_MUTE, 0x00 },
612         { PCM3168A_ADC_OV, 0x00 },
613         { PCM3168A_ADC_ATT_OVF, 0x00 },
614         { PCM3168A_ADC_VOL_MASTER, 0xd3 },
615         { PCM3168A_ADC_VOL_CHAN_START, 0xd3 },
616         { PCM3168A_ADC_VOL_CHAN_START + 1, 0xd3 },
617         { PCM3168A_ADC_VOL_CHAN_START + 2, 0xd3 },
618         { PCM3168A_ADC_VOL_CHAN_START + 3, 0xd3 },
619         { PCM3168A_ADC_VOL_CHAN_START + 4, 0xd3 },
620         { PCM3168A_ADC_VOL_CHAN_START + 5, 0xd3 }
621 };
622 
623 static bool pcm3168a_readable_register(struct device *dev, unsigned int reg)
624 {
625         if (reg >= PCM3168A_RST_SMODE)
626                 return true;
627         else
628                 return false;
629 }
630 
631 static bool pcm3168a_volatile_register(struct device *dev, unsigned int reg)
632 {
633         switch (reg) {
634         case PCM3168A_DAC_ZERO:
635         case PCM3168A_ADC_OV:
636                 return true;
637         default:
638                 return false;
639         }
640 }
641 
642 static bool pcm3168a_writeable_register(struct device *dev, unsigned int reg)
643 {
644         if (reg < PCM3168A_RST_SMODE)
645                 return false;
646 
647         switch (reg) {
648         case PCM3168A_DAC_ZERO:
649         case PCM3168A_ADC_OV:
650                 return false;
651         default:
652                 return true;
653         }
654 }
655 
656 const struct regmap_config pcm3168a_regmap = {
657         .reg_bits = 8,
658         .val_bits = 8,
659 
660         .max_register = PCM3168A_ADC_VOL_CHAN_START + 5,
661         .reg_defaults = pcm3168a_reg_default,
662         .num_reg_defaults = ARRAY_SIZE(pcm3168a_reg_default),
663         .readable_reg = pcm3168a_readable_register,
664         .volatile_reg = pcm3168a_volatile_register,
665         .writeable_reg = pcm3168a_writeable_register,
666         .cache_type = REGCACHE_FLAT
667 };
668 EXPORT_SYMBOL_GPL(pcm3168a_regmap);
669 
670 static const struct snd_soc_component_driver pcm3168a_driver = {
671         .controls               = pcm3168a_snd_controls,
672         .num_controls           = ARRAY_SIZE(pcm3168a_snd_controls),
673         .dapm_widgets           = pcm3168a_dapm_widgets,
674         .num_dapm_widgets       = ARRAY_SIZE(pcm3168a_dapm_widgets),
675         .dapm_routes            = pcm3168a_dapm_routes,
676         .num_dapm_routes        = ARRAY_SIZE(pcm3168a_dapm_routes),
677         .use_pmdown_time        = 1,
678         .endianness             = 1,
679         .non_legacy_dai_naming  = 1,
680 };
681 
682 int pcm3168a_probe(struct device *dev, struct regmap *regmap)
683 {
684         struct pcm3168a_priv *pcm3168a;
685         int ret, i;
686 
687         pcm3168a = devm_kzalloc(dev, sizeof(*pcm3168a), GFP_KERNEL);
688         if (pcm3168a == NULL)
689                 return -ENOMEM;
690 
691         dev_set_drvdata(dev, pcm3168a);
692 
693         pcm3168a->scki = devm_clk_get(dev, "scki");
694         if (IS_ERR(pcm3168a->scki)) {
695                 ret = PTR_ERR(pcm3168a->scki);
696                 if (ret != -EPROBE_DEFER)
697                         dev_err(dev, "failed to acquire clock 'scki': %d\n", ret);
698                 return ret;
699         }
700 
701         ret = clk_prepare_enable(pcm3168a->scki);
702         if (ret) {
703                 dev_err(dev, "Failed to enable mclk: %d\n", ret);
704                 return ret;
705         }
706 
707         pcm3168a->sysclk = clk_get_rate(pcm3168a->scki);
708 
709         for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++)
710                 pcm3168a->supplies[i].supply = pcm3168a_supply_names[i];
711 
712         ret = devm_regulator_bulk_get(dev,
713                         ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies);
714         if (ret) {
715                 if (ret != -EPROBE_DEFER)
716                         dev_err(dev, "failed to request supplies: %d\n", ret);
717                 goto err_clk;
718         }
719 
720         ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
721                                     pcm3168a->supplies);
722         if (ret) {
723                 dev_err(dev, "failed to enable supplies: %d\n", ret);
724                 goto err_clk;
725         }
726 
727         pcm3168a->regmap = regmap;
728         if (IS_ERR(pcm3168a->regmap)) {
729                 ret = PTR_ERR(pcm3168a->regmap);
730                 dev_err(dev, "failed to allocate regmap: %d\n", ret);
731                 goto err_regulator;
732         }
733 
734         ret = pcm3168a_reset(pcm3168a);
735         if (ret) {
736                 dev_err(dev, "Failed to reset device: %d\n", ret);
737                 goto err_regulator;
738         }
739 
740         pm_runtime_set_active(dev);
741         pm_runtime_enable(dev);
742         pm_runtime_idle(dev);
743 
744         ret = devm_snd_soc_register_component(dev, &pcm3168a_driver, pcm3168a_dais,
745                         ARRAY_SIZE(pcm3168a_dais));
746         if (ret) {
747                 dev_err(dev, "failed to register component: %d\n", ret);
748                 goto err_regulator;
749         }
750 
751         return 0;
752 
753 err_regulator:
754         regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
755                         pcm3168a->supplies);
756 err_clk:
757         clk_disable_unprepare(pcm3168a->scki);
758 
759         return ret;
760 }
761 EXPORT_SYMBOL_GPL(pcm3168a_probe);
762 
763 static void pcm3168a_disable(struct device *dev)
764 {
765         struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
766 
767         regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
768                                pcm3168a->supplies);
769         clk_disable_unprepare(pcm3168a->scki);
770 }
771 
772 void pcm3168a_remove(struct device *dev)
773 {
774         pm_runtime_disable(dev);
775 #ifndef CONFIG_PM
776         pcm3168a_disable(dev);
777 #endif
778 }
779 EXPORT_SYMBOL_GPL(pcm3168a_remove);
780 
781 #ifdef CONFIG_PM
782 static int pcm3168a_rt_resume(struct device *dev)
783 {
784         struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
785         int ret;
786 
787         ret = clk_prepare_enable(pcm3168a->scki);
788         if (ret) {
789                 dev_err(dev, "Failed to enable mclk: %d\n", ret);
790                 return ret;
791         }
792 
793         ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
794                                     pcm3168a->supplies);
795         if (ret) {
796                 dev_err(dev, "Failed to enable supplies: %d\n", ret);
797                 goto err_clk;
798         }
799 
800         ret = pcm3168a_reset(pcm3168a);
801         if (ret) {
802                 dev_err(dev, "Failed to reset device: %d\n", ret);
803                 goto err_regulator;
804         }
805 
806         regcache_cache_only(pcm3168a->regmap, false);
807 
808         regcache_mark_dirty(pcm3168a->regmap);
809 
810         ret = regcache_sync(pcm3168a->regmap);
811         if (ret) {
812                 dev_err(dev, "Failed to sync regmap: %d\n", ret);
813                 goto err_regulator;
814         }
815 
816         return 0;
817 
818 err_regulator:
819         regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
820                                pcm3168a->supplies);
821 err_clk:
822         clk_disable_unprepare(pcm3168a->scki);
823 
824         return ret;
825 }
826 
827 static int pcm3168a_rt_suspend(struct device *dev)
828 {
829         struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
830 
831         regcache_cache_only(pcm3168a->regmap, true);
832 
833         pcm3168a_disable(dev);
834 
835         return 0;
836 }
837 #endif
838 
839 const struct dev_pm_ops pcm3168a_pm_ops = {
840         SET_RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL)
841 };
842 EXPORT_SYMBOL_GPL(pcm3168a_pm_ops);
843 
844 MODULE_DESCRIPTION("PCM3168A codec driver");
845 MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
846 MODULE_LICENSE("GPL v2");
847 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp