blob: 97091e3b9a0bce92da93e37b0445ec755d0fb33e [file] [log] [blame]
Johannes Stezenbachc034abf2011-06-22 14:59:24 +02001/*
2 * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
3 *
4 * Copyright: 2011 Raumfeld GmbH
5 * Author: Johannes Stezenbach <js@sig21.net>
6 *
7 * based on code from:
8 * Wolfson Microelectronics PLC.
9 * Mark Brown <broonie@opensource.wolfsonmicro.com>
10 * Freescale Semiconductor, Inc.
11 * Timur Tabi <timur@freescale.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <linux/regulator/consumer.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
Johannes Stezenbache012ba22011-11-14 17:23:17 +010038#include <sound/sta32x.h>
Johannes Stezenbachc034abf2011-06-22 14:59:24 +020039#include "sta32x.h"
40
41#define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
42 SNDRV_PCM_RATE_44100 | \
43 SNDRV_PCM_RATE_48000 | \
44 SNDRV_PCM_RATE_88200 | \
45 SNDRV_PCM_RATE_96000 | \
46 SNDRV_PCM_RATE_176400 | \
47 SNDRV_PCM_RATE_192000)
48
49#define STA32X_FORMATS \
50 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
51 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
53 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
54 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
55 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
56
57/* Power-up register defaults */
58static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = {
59 0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60,
60 0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69,
61 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
63 0xc0, 0xf3, 0x33, 0x00, 0x0c,
64};
65
66/* regulator power supply names */
67static const char *sta32x_supply_names[] = {
68 "Vdda", /* analog supply, 3.3VV */
69 "Vdd3", /* digital supply, 3.3V */
70 "Vcc" /* power amp spply, 10V - 36V */
71};
72
73/* codec private data */
74struct sta32x_priv {
75 struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
76 struct snd_soc_codec *codec;
Johannes Stezenbache012ba22011-11-14 17:23:17 +010077 struct sta32x_platform_data *pdata;
Johannes Stezenbachc034abf2011-06-22 14:59:24 +020078
79 unsigned int mclk;
80 unsigned int format;
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +010081
82 u32 coef_shadow[STA32X_COEF_COUNT];
Johannes Stezenbachc034abf2011-06-22 14:59:24 +020083};
84
85static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
86static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);
87static const DECLARE_TLV_DB_SCALE(tone_tlv, -120, 200, 0);
88
89static const char *sta32x_drc_ac[] = {
90 "Anti-Clipping", "Dynamic Range Compression" };
91static const char *sta32x_auto_eq_mode[] = {
92 "User", "Preset", "Loudness" };
93static const char *sta32x_auto_gc_mode[] = {
94 "User", "AC no clipping", "AC limited clipping (10%)",
95 "DRC nighttime listening mode" };
96static const char *sta32x_auto_xo_mode[] = {
97 "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", "200Hz",
98 "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", "340Hz", "360Hz" };
99static const char *sta32x_preset_eq_mode[] = {
100 "Flat", "Rock", "Soft Rock", "Jazz", "Classical", "Dance", "Pop", "Soft",
101 "Hard", "Party", "Vocal", "Hip-Hop", "Dialog", "Bass-boost #1",
102 "Bass-boost #2", "Bass-boost #3", "Loudness 1", "Loudness 2",
103 "Loudness 3", "Loudness 4", "Loudness 5", "Loudness 6", "Loudness 7",
104 "Loudness 8", "Loudness 9", "Loudness 10", "Loudness 11", "Loudness 12",
105 "Loudness 13", "Loudness 14", "Loudness 15", "Loudness 16" };
106static const char *sta32x_limiter_select[] = {
107 "Limiter Disabled", "Limiter #1", "Limiter #2" };
108static const char *sta32x_limiter_attack_rate[] = {
109 "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024",
110 "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752",
111 "0.0645", "0.0564", "0.0501", "0.0451" };
112static const char *sta32x_limiter_release_rate[] = {
113 "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",
114 "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",
115 "0.0134", "0.0117", "0.0110", "0.0104" };
116
117static const unsigned int sta32x_limiter_ac_attack_tlv[] = {
118 TLV_DB_RANGE_HEAD(2),
119 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
120 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),
121};
122
123static const unsigned int sta32x_limiter_ac_release_tlv[] = {
124 TLV_DB_RANGE_HEAD(5),
125 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
126 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
127 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
128 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
129 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
130};
131
132static const unsigned int sta32x_limiter_drc_attack_tlv[] = {
133 TLV_DB_RANGE_HEAD(3),
134 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
135 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
136 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
137};
138
139static const unsigned int sta32x_limiter_drc_release_tlv[] = {
140 TLV_DB_RANGE_HEAD(5),
141 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
142 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
143 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
144 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
145 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
146};
147
148static const struct soc_enum sta32x_drc_ac_enum =
149 SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
150 2, sta32x_drc_ac);
151static const struct soc_enum sta32x_auto_eq_enum =
152 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
153 3, sta32x_auto_eq_mode);
154static const struct soc_enum sta32x_auto_gc_enum =
155 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
156 4, sta32x_auto_gc_mode);
157static const struct soc_enum sta32x_auto_xo_enum =
158 SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
159 16, sta32x_auto_xo_mode);
160static const struct soc_enum sta32x_preset_eq_enum =
161 SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
162 32, sta32x_preset_eq_mode);
163static const struct soc_enum sta32x_limiter_ch1_enum =
164 SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
165 3, sta32x_limiter_select);
166static const struct soc_enum sta32x_limiter_ch2_enum =
167 SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
168 3, sta32x_limiter_select);
169static const struct soc_enum sta32x_limiter_ch3_enum =
170 SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
171 3, sta32x_limiter_select);
172static const struct soc_enum sta32x_limiter1_attack_rate_enum =
173 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT,
174 16, sta32x_limiter_attack_rate);
175static const struct soc_enum sta32x_limiter2_attack_rate_enum =
176 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT,
177 16, sta32x_limiter_attack_rate);
178static const struct soc_enum sta32x_limiter1_release_rate_enum =
179 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT,
180 16, sta32x_limiter_release_rate);
181static const struct soc_enum sta32x_limiter2_release_rate_enum =
182 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT,
183 16, sta32x_limiter_release_rate);
Johannes Stezenbach79688432011-07-11 17:01:23 +0200184
185/* byte array controls for setting biquad, mixer, scaling coefficients;
186 * for biquads all five coefficients need to be set in one go,
187 * mixer and pre/postscale coefs can be set individually;
188 * each coef is 24bit, the bytes are ordered in the same way
189 * as given in the STA32x data sheet (big endian; b1, b2, a1, a2, b0)
190 */
191
192static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
193 struct snd_ctl_elem_info *uinfo)
194{
195 int numcoef = kcontrol->private_value >> 16;
196 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
197 uinfo->count = 3 * numcoef;
198 return 0;
199}
200
201static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
202 struct snd_ctl_elem_value *ucontrol)
203{
204 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
205 int numcoef = kcontrol->private_value >> 16;
206 int index = kcontrol->private_value & 0xffff;
207 unsigned int cfud;
208 int i;
209
210 /* preserve reserved bits in STA32X_CFUD */
211 cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
212 /* chip documentation does not say if the bits are self clearing,
213 * so do it explicitly */
214 snd_soc_write(codec, STA32X_CFUD, cfud);
215
216 snd_soc_write(codec, STA32X_CFADDR2, index);
217 if (numcoef == 1)
218 snd_soc_write(codec, STA32X_CFUD, cfud | 0x04);
219 else if (numcoef == 5)
220 snd_soc_write(codec, STA32X_CFUD, cfud | 0x08);
221 else
222 return -EINVAL;
223 for (i = 0; i < 3 * numcoef; i++)
224 ucontrol->value.bytes.data[i] =
225 snd_soc_read(codec, STA32X_B1CF1 + i);
226
227 return 0;
228}
229
230static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_value *ucontrol)
232{
233 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +0100234 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
Johannes Stezenbach79688432011-07-11 17:01:23 +0200235 int numcoef = kcontrol->private_value >> 16;
236 int index = kcontrol->private_value & 0xffff;
237 unsigned int cfud;
238 int i;
239
240 /* preserve reserved bits in STA32X_CFUD */
241 cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
242 /* chip documentation does not say if the bits are self clearing,
243 * so do it explicitly */
244 snd_soc_write(codec, STA32X_CFUD, cfud);
245
246 snd_soc_write(codec, STA32X_CFADDR2, index);
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +0100247 for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
248 sta32x->coef_shadow[index + i] =
249 (ucontrol->value.bytes.data[3 * i] << 16)
250 | (ucontrol->value.bytes.data[3 * i + 1] << 8)
251 | (ucontrol->value.bytes.data[3 * i + 2]);
Johannes Stezenbach79688432011-07-11 17:01:23 +0200252 for (i = 0; i < 3 * numcoef; i++)
253 snd_soc_write(codec, STA32X_B1CF1 + i,
254 ucontrol->value.bytes.data[i]);
255 if (numcoef == 1)
256 snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
257 else if (numcoef == 5)
258 snd_soc_write(codec, STA32X_CFUD, cfud | 0x02);
259 else
260 return -EINVAL;
261
262 return 0;
263}
264
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +0100265int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
266{
267 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
268 unsigned int cfud;
269 int i;
270
271 /* preserve reserved bits in STA32X_CFUD */
272 cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
273
274 for (i = 0; i < STA32X_COEF_COUNT; i++) {
275 snd_soc_write(codec, STA32X_CFADDR2, i);
276 snd_soc_write(codec, STA32X_B1CF1,
277 (sta32x->coef_shadow[i] >> 16) & 0xff);
278 snd_soc_write(codec, STA32X_B1CF2,
279 (sta32x->coef_shadow[i] >> 8) & 0xff);
280 snd_soc_write(codec, STA32X_B1CF3,
281 (sta32x->coef_shadow[i]) & 0xff);
282 /* chip documentation does not say if the bits are
283 * self-clearing, so do it explicitly */
284 snd_soc_write(codec, STA32X_CFUD, cfud);
285 snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
286 }
287 return 0;
288}
289
290int sta32x_cache_sync(struct snd_soc_codec *codec)
291{
292 unsigned int mute;
293 int rc;
294
295 if (!codec->cache_sync)
296 return 0;
297
298 /* mute during register sync */
299 mute = snd_soc_read(codec, STA32X_MMUTE);
300 snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
301 sta32x_sync_coef_shadow(codec);
302 rc = snd_soc_cache_sync(codec);
303 snd_soc_write(codec, STA32X_MMUTE, mute);
304 return rc;
305}
306
Johannes Stezenbach79688432011-07-11 17:01:23 +0200307#define SINGLE_COEF(xname, index) \
308{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
309 .info = sta32x_coefficient_info, \
310 .get = sta32x_coefficient_get,\
311 .put = sta32x_coefficient_put, \
312 .private_value = index | (1 << 16) }
313
314#define BIQUAD_COEFS(xname, index) \
315{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
316 .info = sta32x_coefficient_info, \
317 .get = sta32x_coefficient_get,\
318 .put = sta32x_coefficient_put, \
319 .private_value = index | (5 << 16) }
320
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200321static const struct snd_kcontrol_new sta32x_snd_controls[] = {
322SOC_SINGLE_TLV("Master Volume", STA32X_MVOL, 0, 0xff, 1, mvol_tlv),
323SOC_SINGLE("Master Switch", STA32X_MMUTE, 0, 1, 1),
324SOC_SINGLE("Ch1 Switch", STA32X_MMUTE, 1, 1, 1),
325SOC_SINGLE("Ch2 Switch", STA32X_MMUTE, 2, 1, 1),
326SOC_SINGLE("Ch3 Switch", STA32X_MMUTE, 3, 1, 1),
327SOC_SINGLE_TLV("Ch1 Volume", STA32X_C1VOL, 0, 0xff, 1, chvol_tlv),
328SOC_SINGLE_TLV("Ch2 Volume", STA32X_C2VOL, 0, 0xff, 1, chvol_tlv),
329SOC_SINGLE_TLV("Ch3 Volume", STA32X_C3VOL, 0, 0xff, 1, chvol_tlv),
330SOC_SINGLE("De-emphasis Filter Switch", STA32X_CONFD, STA32X_CONFD_DEMP_SHIFT, 1, 0),
331SOC_ENUM("Compressor/Limiter Switch", sta32x_drc_ac_enum),
332SOC_SINGLE("Miami Mode Switch", STA32X_CONFD, STA32X_CONFD_MME_SHIFT, 1, 0),
333SOC_SINGLE("Zero Cross Switch", STA32X_CONFE, STA32X_CONFE_ZCE_SHIFT, 1, 0),
334SOC_SINGLE("Soft Ramp Switch", STA32X_CONFE, STA32X_CONFE_SVE_SHIFT, 1, 0),
335SOC_SINGLE("Auto-Mute Switch", STA32X_CONFF, STA32X_CONFF_IDE_SHIFT, 1, 0),
336SOC_ENUM("Automode EQ", sta32x_auto_eq_enum),
337SOC_ENUM("Automode GC", sta32x_auto_gc_enum),
338SOC_ENUM("Automode XO", sta32x_auto_xo_enum),
339SOC_ENUM("Preset EQ", sta32x_preset_eq_enum),
340SOC_SINGLE("Ch1 Tone Control Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
341SOC_SINGLE("Ch2 Tone Control Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
342SOC_SINGLE("Ch1 EQ Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
343SOC_SINGLE("Ch2 EQ Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
344SOC_SINGLE("Ch1 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
345SOC_SINGLE("Ch2 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
346SOC_SINGLE("Ch3 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
347SOC_ENUM("Ch1 Limiter Select", sta32x_limiter_ch1_enum),
348SOC_ENUM("Ch2 Limiter Select", sta32x_limiter_ch2_enum),
349SOC_ENUM("Ch3 Limiter Select", sta32x_limiter_ch3_enum),
350SOC_SINGLE_TLV("Bass Tone Control", STA32X_TONE, STA32X_TONE_BTC_SHIFT, 15, 0, tone_tlv),
351SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, tone_tlv),
352SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),
353SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),
354SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
355SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
356
357/* depending on mode, the attack/release thresholds have
358 * two different enum definitions; provide both
359 */
360SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
361 16, 0, sta32x_limiter_ac_attack_tlv),
362SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
363 16, 0, sta32x_limiter_ac_attack_tlv),
364SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
365 16, 0, sta32x_limiter_ac_release_tlv),
366SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
367 16, 0, sta32x_limiter_ac_release_tlv),
368SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
369 16, 0, sta32x_limiter_drc_attack_tlv),
370SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
371 16, 0, sta32x_limiter_drc_attack_tlv),
372SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
373 16, 0, sta32x_limiter_drc_release_tlv),
374SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
375 16, 0, sta32x_limiter_drc_release_tlv),
Johannes Stezenbach79688432011-07-11 17:01:23 +0200376
377BIQUAD_COEFS("Ch1 - Biquad 1", 0),
378BIQUAD_COEFS("Ch1 - Biquad 2", 5),
379BIQUAD_COEFS("Ch1 - Biquad 3", 10),
380BIQUAD_COEFS("Ch1 - Biquad 4", 15),
381BIQUAD_COEFS("Ch2 - Biquad 1", 20),
382BIQUAD_COEFS("Ch2 - Biquad 2", 25),
383BIQUAD_COEFS("Ch2 - Biquad 3", 30),
384BIQUAD_COEFS("Ch2 - Biquad 4", 35),
385BIQUAD_COEFS("High-pass", 40),
386BIQUAD_COEFS("Low-pass", 45),
387SINGLE_COEF("Ch1 - Prescale", 50),
388SINGLE_COEF("Ch2 - Prescale", 51),
389SINGLE_COEF("Ch1 - Postscale", 52),
390SINGLE_COEF("Ch2 - Postscale", 53),
391SINGLE_COEF("Ch3 - Postscale", 54),
392SINGLE_COEF("Thermal warning - Postscale", 55),
393SINGLE_COEF("Ch1 - Mix 1", 56),
394SINGLE_COEF("Ch1 - Mix 2", 57),
395SINGLE_COEF("Ch2 - Mix 1", 58),
396SINGLE_COEF("Ch2 - Mix 2", 59),
397SINGLE_COEF("Ch3 - Mix 1", 60),
398SINGLE_COEF("Ch3 - Mix 2", 61),
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200399};
400
401static const struct snd_soc_dapm_widget sta32x_dapm_widgets[] = {
402SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
403SND_SOC_DAPM_OUTPUT("LEFT"),
404SND_SOC_DAPM_OUTPUT("RIGHT"),
405SND_SOC_DAPM_OUTPUT("SUB"),
406};
407
408static const struct snd_soc_dapm_route sta32x_dapm_routes[] = {
409 { "LEFT", NULL, "DAC" },
410 { "RIGHT", NULL, "DAC" },
411 { "SUB", NULL, "DAC" },
412};
413
414/* MCLK interpolation ratio per fs */
415static struct {
416 int fs;
417 int ir;
418} interpolation_ratios[] = {
419 { 32000, 0 },
420 { 44100, 0 },
421 { 48000, 0 },
422 { 88200, 1 },
423 { 96000, 1 },
424 { 176400, 2 },
425 { 192000, 2 },
426};
427
428/* MCLK to fs clock ratios */
429static struct {
430 int ratio;
431 int mcs;
432} mclk_ratios[3][7] = {
433 { { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 },
434 { 128, 4 }, { 576, 5 }, { 0, 0 } },
435 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
436 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
437};
438
439
440/**
441 * sta32x_set_dai_sysclk - configure MCLK
442 * @codec_dai: the codec DAI
443 * @clk_id: the clock ID (ignored)
444 * @freq: the MCLK input frequency
445 * @dir: the clock direction (ignored)
446 *
447 * The value of MCLK is used to determine which sample rates are supported
448 * by the STA32X, based on the mclk_ratios table.
449 *
450 * This function must be called by the machine driver's 'startup' function,
451 * otherwise the list of supported sample rates will not be available in
452 * time for ALSA.
453 *
454 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
455 * theoretically possible sample rates to be enabled. Call it again with a
456 * proper value set one the external clock is set (most probably you would do
457 * that from a machine's driver 'hw_param' hook.
458 */
459static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
460 int clk_id, unsigned int freq, int dir)
461{
462 struct snd_soc_codec *codec = codec_dai->codec;
463 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
464 int i, j, ir, fs;
465 unsigned int rates = 0;
466 unsigned int rate_min = -1;
467 unsigned int rate_max = 0;
468
469 pr_debug("mclk=%u\n", freq);
470 sta32x->mclk = freq;
471
472 if (sta32x->mclk) {
473 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
474 ir = interpolation_ratios[i].ir;
475 fs = interpolation_ratios[i].fs;
476 for (j = 0; mclk_ratios[ir][j].ratio; j++) {
477 if (mclk_ratios[ir][j].ratio * fs == freq) {
478 rates |= snd_pcm_rate_to_rate_bit(fs);
479 if (fs < rate_min)
480 rate_min = fs;
481 if (fs > rate_max)
482 rate_max = fs;
483 }
484 }
485 }
486 /* FIXME: soc should support a rate list */
487 rates &= ~SNDRV_PCM_RATE_KNOT;
488
489 if (!rates) {
490 dev_err(codec->dev, "could not find a valid sample rate\n");
491 return -EINVAL;
492 }
493 } else {
494 /* enable all possible rates */
495 rates = STA32X_RATES;
496 rate_min = 32000;
497 rate_max = 192000;
498 }
499
500 codec_dai->driver->playback.rates = rates;
501 codec_dai->driver->playback.rate_min = rate_min;
502 codec_dai->driver->playback.rate_max = rate_max;
503 return 0;
504}
505
506/**
507 * sta32x_set_dai_fmt - configure the codec for the selected audio format
508 * @codec_dai: the codec DAI
509 * @fmt: a SND_SOC_DAIFMT_x value indicating the data format
510 *
511 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
512 * codec accordingly.
513 */
514static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
515 unsigned int fmt)
516{
517 struct snd_soc_codec *codec = codec_dai->codec;
518 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
519 u8 confb = snd_soc_read(codec, STA32X_CONFB);
520
521 pr_debug("\n");
522 confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM);
523
524 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
525 case SND_SOC_DAIFMT_CBS_CFS:
526 break;
527 default:
528 return -EINVAL;
529 }
530
531 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
532 case SND_SOC_DAIFMT_I2S:
533 case SND_SOC_DAIFMT_RIGHT_J:
534 case SND_SOC_DAIFMT_LEFT_J:
535 sta32x->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
536 break;
537 default:
538 return -EINVAL;
539 }
540
541 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
542 case SND_SOC_DAIFMT_NB_NF:
543 confb |= STA32X_CONFB_C2IM;
544 break;
545 case SND_SOC_DAIFMT_NB_IF:
546 confb |= STA32X_CONFB_C1IM;
547 break;
548 default:
549 return -EINVAL;
550 }
551
552 snd_soc_write(codec, STA32X_CONFB, confb);
553 return 0;
554}
555
556/**
557 * sta32x_hw_params - program the STA32X with the given hardware parameters.
558 * @substream: the audio stream
559 * @params: the hardware parameters to set
560 * @dai: the SOC DAI (ignored)
561 *
562 * This function programs the hardware with the values provided.
563 * Specifically, the sample rate and the data format.
564 */
565static int sta32x_hw_params(struct snd_pcm_substream *substream,
566 struct snd_pcm_hw_params *params,
567 struct snd_soc_dai *dai)
568{
569 struct snd_soc_pcm_runtime *rtd = substream->private_data;
570 struct snd_soc_codec *codec = rtd->codec;
571 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
572 unsigned int rate;
573 int i, mcs = -1, ir = -1;
574 u8 confa, confb;
575
576 rate = params_rate(params);
577 pr_debug("rate: %u\n", rate);
578 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
Axel Lina5952382011-08-14 11:31:04 +0800579 if (interpolation_ratios[i].fs == rate) {
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200580 ir = interpolation_ratios[i].ir;
Axel Lina5952382011-08-14 11:31:04 +0800581 break;
582 }
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200583 if (ir < 0)
584 return -EINVAL;
585 for (i = 0; mclk_ratios[ir][i].ratio; i++)
Axel Lina5952382011-08-14 11:31:04 +0800586 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200587 mcs = mclk_ratios[ir][i].mcs;
Axel Lina5952382011-08-14 11:31:04 +0800588 break;
589 }
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200590 if (mcs < 0)
591 return -EINVAL;
592
593 confa = snd_soc_read(codec, STA32X_CONFA);
594 confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
595 confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);
596
597 confb = snd_soc_read(codec, STA32X_CONFB);
598 confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
599 switch (params_format(params)) {
600 case SNDRV_PCM_FORMAT_S24_LE:
601 case SNDRV_PCM_FORMAT_S24_BE:
602 case SNDRV_PCM_FORMAT_S24_3LE:
603 case SNDRV_PCM_FORMAT_S24_3BE:
604 pr_debug("24bit\n");
605 /* fall through */
606 case SNDRV_PCM_FORMAT_S32_LE:
607 case SNDRV_PCM_FORMAT_S32_BE:
608 pr_debug("24bit or 32bit\n");
609 switch (sta32x->format) {
610 case SND_SOC_DAIFMT_I2S:
611 confb |= 0x0;
612 break;
613 case SND_SOC_DAIFMT_LEFT_J:
614 confb |= 0x1;
615 break;
616 case SND_SOC_DAIFMT_RIGHT_J:
617 confb |= 0x2;
618 break;
619 }
620
621 break;
622 case SNDRV_PCM_FORMAT_S20_3LE:
623 case SNDRV_PCM_FORMAT_S20_3BE:
624 pr_debug("20bit\n");
625 switch (sta32x->format) {
626 case SND_SOC_DAIFMT_I2S:
627 confb |= 0x4;
628 break;
629 case SND_SOC_DAIFMT_LEFT_J:
630 confb |= 0x5;
631 break;
632 case SND_SOC_DAIFMT_RIGHT_J:
633 confb |= 0x6;
634 break;
635 }
636
637 break;
638 case SNDRV_PCM_FORMAT_S18_3LE:
639 case SNDRV_PCM_FORMAT_S18_3BE:
640 pr_debug("18bit\n");
641 switch (sta32x->format) {
642 case SND_SOC_DAIFMT_I2S:
643 confb |= 0x8;
644 break;
645 case SND_SOC_DAIFMT_LEFT_J:
646 confb |= 0x9;
647 break;
648 case SND_SOC_DAIFMT_RIGHT_J:
649 confb |= 0xa;
650 break;
651 }
652
653 break;
654 case SNDRV_PCM_FORMAT_S16_LE:
655 case SNDRV_PCM_FORMAT_S16_BE:
656 pr_debug("16bit\n");
657 switch (sta32x->format) {
658 case SND_SOC_DAIFMT_I2S:
659 confb |= 0x0;
660 break;
661 case SND_SOC_DAIFMT_LEFT_J:
662 confb |= 0xd;
663 break;
664 case SND_SOC_DAIFMT_RIGHT_J:
665 confb |= 0xe;
666 break;
667 }
668
669 break;
670 default:
671 return -EINVAL;
672 }
673
674 snd_soc_write(codec, STA32X_CONFA, confa);
675 snd_soc_write(codec, STA32X_CONFB, confb);
676 return 0;
677}
678
679/**
680 * sta32x_set_bias_level - DAPM callback
681 * @codec: the codec device
682 * @level: DAPM power level
683 *
684 * This is called by ALSA to put the codec into low power mode
685 * or to wake it up. If the codec is powered off completely
686 * all registers must be restored after power on.
687 */
688static int sta32x_set_bias_level(struct snd_soc_codec *codec,
689 enum snd_soc_bias_level level)
690{
691 int ret;
692 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
693
694 pr_debug("level = %d\n", level);
695 switch (level) {
696 case SND_SOC_BIAS_ON:
697 break;
698
699 case SND_SOC_BIAS_PREPARE:
700 /* Full power on */
701 snd_soc_update_bits(codec, STA32X_CONFF,
702 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
703 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
704 break;
705
706 case SND_SOC_BIAS_STANDBY:
707 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
708 ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
709 sta32x->supplies);
710 if (ret != 0) {
711 dev_err(codec->dev,
712 "Failed to enable supplies: %d\n", ret);
713 return ret;
714 }
715
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +0100716 sta32x_cache_sync(codec);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200717 }
718
719 /* Power up to mute */
720 /* FIXME */
721 snd_soc_update_bits(codec, STA32X_CONFF,
722 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
723 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
724
725 break;
726
727 case SND_SOC_BIAS_OFF:
728 /* The chip runs through the power down sequence for us. */
729 snd_soc_update_bits(codec, STA32X_CONFF,
730 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
731 STA32X_CONFF_PWDN);
732 msleep(300);
733
734 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
735 sta32x->supplies);
736 break;
737 }
738 codec->dapm.bias_level = level;
739 return 0;
740}
741
742static struct snd_soc_dai_ops sta32x_dai_ops = {
743 .hw_params = sta32x_hw_params,
744 .set_sysclk = sta32x_set_dai_sysclk,
745 .set_fmt = sta32x_set_dai_fmt,
746};
747
748static struct snd_soc_dai_driver sta32x_dai = {
749 .name = "STA32X",
750 .playback = {
751 .stream_name = "Playback",
752 .channels_min = 2,
753 .channels_max = 2,
754 .rates = STA32X_RATES,
755 .formats = STA32X_FORMATS,
756 },
757 .ops = &sta32x_dai_ops,
758};
759
760#ifdef CONFIG_PM
761static int sta32x_suspend(struct snd_soc_codec *codec, pm_message_t state)
762{
763 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
764 return 0;
765}
766
767static int sta32x_resume(struct snd_soc_codec *codec)
768{
769 sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
770 return 0;
771}
772#else
773#define sta32x_suspend NULL
774#define sta32x_resume NULL
775#endif
776
777static int sta32x_probe(struct snd_soc_codec *codec)
778{
779 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100780 int i, ret = 0, thermal = 0;
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200781
782 sta32x->codec = codec;
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100783 sta32x->pdata = dev_get_platdata(codec->dev);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200784
785 /* regulators */
786 for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
787 sta32x->supplies[i].supply = sta32x_supply_names[i];
788
789 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies),
790 sta32x->supplies);
791 if (ret != 0) {
792 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
793 goto err;
794 }
795
796 ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
797 sta32x->supplies);
798 if (ret != 0) {
799 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
800 goto err_get;
801 }
802
803 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
804 * then do the I2C transactions itself.
805 */
806 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
807 if (ret < 0) {
808 dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
809 return ret;
810 }
811
Axel Linedf413f2011-10-13 14:57:31 +0800812 /* Chip documentation explicitly requires that the reset values
813 * of reserved register bits are left untouched.
814 * Write the register default value to cache for reserved registers,
815 * so the write to the these registers are suppressed by the cache
816 * restore code when it skips writes of default registers.
817 */
818 snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
819 snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
820 snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
821 snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
822 snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
823 snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
824 snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
Johannes Stezenbach889ebae2011-07-11 17:01:24 +0200825
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100826 /* set thermal warning adjustment and recovery */
827 if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
828 thermal |= STA32X_CONFA_TWAB;
829 if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
830 thermal |= STA32X_CONFA_TWRB;
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200831 snd_soc_update_bits(codec, STA32X_CONFA,
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100832 STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
833 thermal);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200834
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100835 /* select output configuration */
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200836 snd_soc_update_bits(codec, STA32X_CONFF,
837 STA32X_CONFF_OCFG_MASK,
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100838 sta32x->pdata->output_conf
839 << STA32X_CONFF_OCFG_SHIFT);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200840
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100841 /* channel to output mapping */
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200842 snd_soc_update_bits(codec, STA32X_C1CFG,
843 STA32X_CxCFG_OM_MASK,
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100844 sta32x->pdata->ch1_output_mapping
845 << STA32X_CxCFG_OM_SHIFT);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200846 snd_soc_update_bits(codec, STA32X_C2CFG,
847 STA32X_CxCFG_OM_MASK,
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100848 sta32x->pdata->ch2_output_mapping
849 << STA32X_CxCFG_OM_SHIFT);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200850 snd_soc_update_bits(codec, STA32X_C3CFG,
851 STA32X_CxCFG_OM_MASK,
Johannes Stezenbache012ba22011-11-14 17:23:17 +0100852 sta32x->pdata->ch3_output_mapping
853 << STA32X_CxCFG_OM_SHIFT);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200854
Johannes Stezenbach54dc6ca2011-11-14 17:23:16 +0100855 /* initialize coefficient shadow RAM with reset values */
856 for (i = 4; i <= 49; i += 5)
857 sta32x->coef_shadow[i] = 0x400000;
858 for (i = 50; i <= 54; i++)
859 sta32x->coef_shadow[i] = 0x7fffff;
860 sta32x->coef_shadow[55] = 0x5a9df7;
861 sta32x->coef_shadow[56] = 0x7fffff;
862 sta32x->coef_shadow[59] = 0x7fffff;
863 sta32x->coef_shadow[60] = 0x400000;
864 sta32x->coef_shadow[61] = 0x400000;
865
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200866 sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
867 /* Bias level configuration will have done an extra enable */
868 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
869
870 return 0;
871
872err_get:
873 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
874err:
875 return ret;
876}
877
878static int sta32x_remove(struct snd_soc_codec *codec)
879{
880 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
881
Axel Line3d73c12011-08-18 15:31:04 +0800882 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200883 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
884 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
885
886 return 0;
887}
888
Johannes Stezenbach79688432011-07-11 17:01:23 +0200889static int sta32x_reg_is_volatile(struct snd_soc_codec *codec,
890 unsigned int reg)
891{
892 switch (reg) {
893 case STA32X_CONFA ... STA32X_L2ATRT:
894 case STA32X_MPCC1 ... STA32X_FDRC2:
895 return 0;
896 }
897 return 1;
898}
899
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200900static const struct snd_soc_codec_driver sta32x_codec = {
901 .probe = sta32x_probe,
902 .remove = sta32x_remove,
903 .suspend = sta32x_suspend,
904 .resume = sta32x_resume,
905 .reg_cache_size = STA32X_REGISTER_COUNT,
906 .reg_word_size = sizeof(u8),
Axel Linf0bbc2b2011-10-13 14:40:08 +0800907 .reg_cache_default = sta32x_regs,
Johannes Stezenbach79688432011-07-11 17:01:23 +0200908 .volatile_register = sta32x_reg_is_volatile,
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200909 .set_bias_level = sta32x_set_bias_level,
910 .controls = sta32x_snd_controls,
911 .num_controls = ARRAY_SIZE(sta32x_snd_controls),
912 .dapm_widgets = sta32x_dapm_widgets,
913 .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets),
914 .dapm_routes = sta32x_dapm_routes,
915 .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes),
916};
917
918static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
919 const struct i2c_device_id *id)
920{
921 struct sta32x_priv *sta32x;
922 int ret;
923
924 sta32x = kzalloc(sizeof(struct sta32x_priv), GFP_KERNEL);
925 if (!sta32x)
926 return -ENOMEM;
927
928 i2c_set_clientdata(i2c, sta32x);
929
930 ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
931 if (ret != 0) {
932 dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
Axel Lin161d55c2011-08-13 11:33:08 +0800933 kfree(sta32x);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200934 return ret;
935 }
936
937 return 0;
938}
939
940static __devexit int sta32x_i2c_remove(struct i2c_client *client)
941{
942 struct sta32x_priv *sta32x = i2c_get_clientdata(client);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200943
Axel Line3d73c12011-08-18 15:31:04 +0800944 snd_soc_unregister_codec(&client->dev);
Johannes Stezenbachc034abf2011-06-22 14:59:24 +0200945 kfree(sta32x);
946 return 0;
947}
948
949static const struct i2c_device_id sta32x_i2c_id[] = {
950 { "sta326", 0 },
951 { "sta328", 0 },
952 { "sta329", 0 },
953 { }
954};
955MODULE_DEVICE_TABLE(i2c, sta32x_i2c_id);
956
957static struct i2c_driver sta32x_i2c_driver = {
958 .driver = {
959 .name = "sta32x",
960 .owner = THIS_MODULE,
961 },
962 .probe = sta32x_i2c_probe,
963 .remove = __devexit_p(sta32x_i2c_remove),
964 .id_table = sta32x_i2c_id,
965};
966
967static int __init sta32x_init(void)
968{
969 return i2c_add_driver(&sta32x_i2c_driver);
970}
971module_init(sta32x_init);
972
973static void __exit sta32x_exit(void)
974{
975 i2c_del_driver(&sta32x_i2c_driver);
976}
977module_exit(sta32x_exit);
978
979MODULE_DESCRIPTION("ASoC STA32X driver");
980MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
981MODULE_LICENSE("GPL");