Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * cs35l32.c -- CS35L32 ALSA SoC audio driver
  4 *
  5 * Copyright 2014 CirrusLogic, Inc.
  6 *
  7 * Author: Brian Austin <brian.austin@cirrus.com>
 
 
 
 
 
  8 */
  9
 10#include <linux/module.h>
 11#include <linux/moduleparam.h>
 12#include <linux/kernel.h>
 13#include <linux/init.h>
 14#include <linux/delay.h>
 15#include <linux/i2c.h>
 
 16#include <linux/regmap.h>
 17#include <linux/slab.h>
 18#include <linux/platform_device.h>
 19#include <linux/regulator/consumer.h>
 20#include <linux/gpio/consumer.h>
 21#include <linux/of.h>
 22#include <sound/core.h>
 23#include <sound/pcm.h>
 24#include <sound/pcm_params.h>
 25#include <sound/soc.h>
 26#include <sound/soc-dapm.h>
 27#include <sound/initval.h>
 28#include <sound/tlv.h>
 29#include <dt-bindings/sound/cs35l32.h>
 30
 31#include "cs35l32.h"
 32#include "cirrus_legacy.h"
 33
 34#define CS35L32_NUM_SUPPLIES 2
 35static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = {
 36	"VA",
 37	"VP",
 38};
 39
 40struct  cs35l32_private {
 41	struct regmap *regmap;
 42	struct snd_soc_component *component;
 43	struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES];
 44	struct cs35l32_platform_data pdata;
 45	struct gpio_desc *reset_gpio;
 46};
 47
 48static const struct reg_default cs35l32_reg_defaults[] = {
 49
 50	{ 0x06, 0x04 }, /* Power Ctl 1 */
 51	{ 0x07, 0xE8 }, /* Power Ctl 2 */
 52	{ 0x08, 0x40 }, /* Clock Ctl */
 53	{ 0x09, 0x20 }, /* Low Battery Threshold */
 54	{ 0x0A, 0x00 }, /* Voltage Monitor [RO] */
 55	{ 0x0B, 0x40 }, /* Conv Peak Curr Protection CTL */
 56	{ 0x0C, 0x07 }, /* IMON Scaling */
 57	{ 0x0D, 0x03 }, /* Audio/LED Pwr Manager */
 58	{ 0x0F, 0x20 }, /* Serial Port Control */
 59	{ 0x10, 0x14 }, /* Class D Amp CTL */
 60	{ 0x11, 0x00 }, /* Protection Release CTL */
 61	{ 0x12, 0xFF }, /* Interrupt Mask 1 */
 62	{ 0x13, 0xFF }, /* Interrupt Mask 2 */
 63	{ 0x14, 0xFF }, /* Interrupt Mask 3 */
 64	{ 0x19, 0x00 }, /* LED Flash Mode Current */
 65	{ 0x1A, 0x00 }, /* LED Movie Mode Current */
 66	{ 0x1B, 0x20 }, /* LED Flash Timer */
 67	{ 0x1C, 0x00 }, /* LED Flash Inhibit Current */
 68};
 69
 70static bool cs35l32_readable_register(struct device *dev, unsigned int reg)
 71{
 72	switch (reg) {
 73	case CS35L32_DEVID_AB ... CS35L32_AUDIO_LED_MNGR:
 74	case CS35L32_ADSP_CTL ... CS35L32_FLASH_INHIBIT:
 75		return true;
 76	default:
 77		return false;
 78	}
 79}
 80
 81static bool cs35l32_volatile_register(struct device *dev, unsigned int reg)
 82{
 83	switch (reg) {
 84	case CS35L32_DEVID_AB ... CS35L32_REV_ID:
 85	case CS35L32_INT_STATUS_1 ... CS35L32_LED_STATUS:
 86		return true;
 87	default:
 88		return false;
 89	}
 90}
 91
 92static bool cs35l32_precious_register(struct device *dev, unsigned int reg)
 93{
 94	switch (reg) {
 95	case CS35L32_INT_STATUS_1 ... CS35L32_LED_STATUS:
 96		return true;
 97	default:
 98		return false;
 99	}
100}
101
102static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 300, 0);
103
104static const struct snd_kcontrol_new imon_ctl =
105	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 6, 1, 1);
106
107static const struct snd_kcontrol_new vmon_ctl =
108	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 7, 1, 1);
109
110static const struct snd_kcontrol_new vpmon_ctl =
111	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 5, 1, 1);
112
113static const struct snd_kcontrol_new cs35l32_snd_controls[] = {
114	SOC_SINGLE_TLV("Speaker Volume", CS35L32_CLASSD_CTL,
115		       3, 0x04, 1, classd_ctl_tlv),
116	SOC_SINGLE("Zero Cross Switch", CS35L32_CLASSD_CTL, 2, 1, 0),
117	SOC_SINGLE("Gain Manager Switch", CS35L32_AUDIO_LED_MNGR, 3, 1, 0),
118};
119
120static const struct snd_soc_dapm_widget cs35l32_dapm_widgets[] = {
121
122	SND_SOC_DAPM_SUPPLY("BOOST", CS35L32_PWRCTL1, 2, 1, NULL, 0),
123	SND_SOC_DAPM_OUT_DRV("Speaker", CS35L32_PWRCTL1, 7, 1, NULL, 0),
124
125	SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L32_PWRCTL2, 3, 1),
126
127	SND_SOC_DAPM_INPUT("VP"),
128	SND_SOC_DAPM_INPUT("ISENSE"),
129	SND_SOC_DAPM_INPUT("VSENSE"),
130
131	SND_SOC_DAPM_SWITCH("VMON ADC", CS35L32_PWRCTL2, 7, 1, &vmon_ctl),
132	SND_SOC_DAPM_SWITCH("IMON ADC", CS35L32_PWRCTL2, 6, 1, &imon_ctl),
133	SND_SOC_DAPM_SWITCH("VPMON ADC", CS35L32_PWRCTL2, 5, 1, &vpmon_ctl),
134};
135
136static const struct snd_soc_dapm_route cs35l32_audio_map[] = {
137
138	{"Speaker", NULL, "BOOST"},
139
140	{"VMON ADC", NULL, "VSENSE"},
141	{"IMON ADC", NULL, "ISENSE"},
142	{"VPMON ADC", NULL, "VP"},
143
144	{"SDOUT", "Switch", "VMON ADC"},
145	{"SDOUT",  "Switch", "IMON ADC"},
146	{"SDOUT", "Switch", "VPMON ADC"},
147
148	{"Capture", NULL, "SDOUT"},
149};
150
151static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
152{
153	struct snd_soc_component *component = codec_dai->component;
154
155	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
156	case SND_SOC_DAIFMT_CBM_CFM:
157		snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
158				    CS35L32_ADSP_MASTER_MASK,
159				CS35L32_ADSP_MASTER_MASK);
160		break;
161	case SND_SOC_DAIFMT_CBS_CFS:
162		snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
163				    CS35L32_ADSP_MASTER_MASK, 0);
164		break;
165	default:
166		return -EINVAL;
167	}
168
169	return 0;
170}
171
172static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate)
173{
174	struct snd_soc_component *component = dai->component;
175
176	return snd_soc_component_update_bits(component, CS35L32_PWRCTL2,
177					CS35L32_SDOUT_3ST, tristate << 3);
178}
179
180static const struct snd_soc_dai_ops cs35l32_ops = {
181	.set_fmt = cs35l32_set_dai_fmt,
182	.set_tristate = cs35l32_set_tristate,
183};
184
185static struct snd_soc_dai_driver cs35l32_dai[] = {
186	{
187		.name = "cs35l32-monitor",
188		.id = 0,
189		.capture = {
190			.stream_name = "Capture",
191			.channels_min = 2,
192			.channels_max = 2,
193			.rates = CS35L32_RATES,
194			.formats = CS35L32_FORMATS,
195		},
196		.ops = &cs35l32_ops,
197		.symmetric_rate = 1,
198	}
199};
200
201static int cs35l32_component_set_sysclk(struct snd_soc_component *component,
202			      int clk_id, int source, unsigned int freq, int dir)
203{
204	unsigned int val;
205
206	switch (freq) {
207	case 6000000:
208		val = CS35L32_MCLK_RATIO;
209		break;
210	case 12000000:
211		val = CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO;
212		break;
213	case 6144000:
214		val = 0;
215		break;
216	case 12288000:
217		val = CS35L32_MCLK_DIV2_MASK;
218		break;
219	default:
220		return -EINVAL;
221	}
222
223	return snd_soc_component_update_bits(component, CS35L32_CLK_CTL,
224			CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
225}
226
227static const struct snd_soc_component_driver soc_component_dev_cs35l32 = {
228	.set_sysclk		= cs35l32_component_set_sysclk,
229	.controls		= cs35l32_snd_controls,
230	.num_controls		= ARRAY_SIZE(cs35l32_snd_controls),
231	.dapm_widgets		= cs35l32_dapm_widgets,
232	.num_dapm_widgets	= ARRAY_SIZE(cs35l32_dapm_widgets),
233	.dapm_routes		= cs35l32_audio_map,
234	.num_dapm_routes	= ARRAY_SIZE(cs35l32_audio_map),
235	.idle_bias_on		= 1,
236	.use_pmdown_time	= 1,
237	.endianness		= 1,
238};
239
240/* Current and threshold powerup sequence Pg37 in datasheet */
241static const struct reg_sequence cs35l32_monitor_patch[] = {
242
243	{ 0x00, 0x99 },
244	{ 0x48, 0x17 },
245	{ 0x49, 0x56 },
246	{ 0x43, 0x01 },
247	{ 0x3B, 0x62 },
248	{ 0x3C, 0x80 },
249	{ 0x00, 0x00 },
250};
251
252static const struct regmap_config cs35l32_regmap = {
253	.reg_bits = 8,
254	.val_bits = 8,
255
256	.max_register = CS35L32_MAX_REGISTER,
257	.reg_defaults = cs35l32_reg_defaults,
258	.num_reg_defaults = ARRAY_SIZE(cs35l32_reg_defaults),
259	.volatile_reg = cs35l32_volatile_register,
260	.readable_reg = cs35l32_readable_register,
261	.precious_reg = cs35l32_precious_register,
262	.cache_type = REGCACHE_MAPLE,
263
264	.use_single_read = true,
265	.use_single_write = true,
266};
267
268static int cs35l32_handle_of_data(struct i2c_client *i2c_client,
269				    struct cs35l32_platform_data *pdata)
270{
271	struct device_node *np = i2c_client->dev.of_node;
272	unsigned int val;
273
274	if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0)
275		pdata->sdout_share = val;
276
277	if (of_property_read_u32(np, "cirrus,boost-manager", &val))
278		val = -1u;
279
280	switch (val) {
281	case CS35L32_BOOST_MGR_AUTO:
282	case CS35L32_BOOST_MGR_AUTO_AUDIO:
283	case CS35L32_BOOST_MGR_BYPASS:
284	case CS35L32_BOOST_MGR_FIXED:
285		pdata->boost_mng = val;
286		break;
287	case -1u:
288	default:
289		dev_err(&i2c_client->dev,
290			"Wrong cirrus,boost-manager DT value %d\n", val);
291		pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS;
292	}
293
294	if (of_property_read_u32(np, "cirrus,sdout-datacfg", &val))
295		val = -1u;
296	switch (val) {
297	case CS35L32_DATA_CFG_LR_VP:
298	case CS35L32_DATA_CFG_LR_STAT:
299	case CS35L32_DATA_CFG_LR:
300	case CS35L32_DATA_CFG_LR_VPSTAT:
301		pdata->sdout_datacfg = val;
302		break;
303	case -1u:
304	default:
305		dev_err(&i2c_client->dev,
306			"Wrong cirrus,sdout-datacfg DT value %d\n", val);
307		pdata->sdout_datacfg = CS35L32_DATA_CFG_LR;
308	}
309
310	if (of_property_read_u32(np, "cirrus,battery-threshold", &val))
311		val = -1u;
312	switch (val) {
313	case CS35L32_BATT_THRESH_3_1V:
314	case CS35L32_BATT_THRESH_3_2V:
315	case CS35L32_BATT_THRESH_3_3V:
316	case CS35L32_BATT_THRESH_3_4V:
317		pdata->batt_thresh = val;
318		break;
319	case -1u:
320	default:
321		dev_err(&i2c_client->dev,
322			"Wrong cirrus,battery-threshold DT value %d\n", val);
323		pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V;
324	}
325
326	if (of_property_read_u32(np, "cirrus,battery-recovery", &val))
327		val = -1u;
328	switch (val) {
329	case CS35L32_BATT_RECOV_3_1V:
330	case CS35L32_BATT_RECOV_3_2V:
331	case CS35L32_BATT_RECOV_3_3V:
332	case CS35L32_BATT_RECOV_3_4V:
333	case CS35L32_BATT_RECOV_3_5V:
334	case CS35L32_BATT_RECOV_3_6V:
335		pdata->batt_recov = val;
336		break;
337	case -1u:
338	default:
339		dev_err(&i2c_client->dev,
340			"Wrong cirrus,battery-recovery DT value %d\n", val);
341		pdata->batt_recov = CS35L32_BATT_RECOV_3_4V;
342	}
343
344	return 0;
345}
346
347static int cs35l32_i2c_probe(struct i2c_client *i2c_client)
 
348{
349	struct cs35l32_private *cs35l32;
350	struct cs35l32_platform_data *pdata =
351		dev_get_platdata(&i2c_client->dev);
352	int ret, i, devid;
 
353	unsigned int reg;
354
355	cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l32), GFP_KERNEL);
356	if (!cs35l32)
 
 
 
357		return -ENOMEM;
 
358
359	i2c_set_clientdata(i2c_client, cs35l32);
360
361	cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap);
362	if (IS_ERR(cs35l32->regmap)) {
363		ret = PTR_ERR(cs35l32->regmap);
364		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
365		return ret;
366	}
367
368	if (pdata) {
369		cs35l32->pdata = *pdata;
370	} else {
371		pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
372				     GFP_KERNEL);
373		if (!pdata)
 
 
374			return -ENOMEM;
375
376		if (i2c_client->dev.of_node) {
377			ret = cs35l32_handle_of_data(i2c_client,
378						     &cs35l32->pdata);
379			if (ret != 0)
380				return ret;
381		}
382	}
383
384	for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++)
385		cs35l32->supplies[i].supply = cs35l32_supply_names[i];
386
387	ret = devm_regulator_bulk_get(&i2c_client->dev,
388				      ARRAY_SIZE(cs35l32->supplies),
389				      cs35l32->supplies);
390	if (ret != 0) {
391		dev_err(&i2c_client->dev,
392			"Failed to request supplies: %d\n", ret);
393		return ret;
394	}
395
396	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
397				    cs35l32->supplies);
398	if (ret != 0) {
399		dev_err(&i2c_client->dev,
400			"Failed to enable supplies: %d\n", ret);
401		return ret;
402	}
403
404	/* Reset the Device */
405	cs35l32->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
406		"reset", GPIOD_OUT_LOW);
407	if (IS_ERR(cs35l32->reset_gpio)) {
408		ret = PTR_ERR(cs35l32->reset_gpio);
409		goto err_supplies;
410	}
411
412	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
413
414	/* initialize codec */
415	devid = cirrus_read_device_id(cs35l32->regmap, CS35L32_DEVID_AB);
416	if (devid < 0) {
417		ret = devid;
418		dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
419		goto err_disable;
420	}
 
 
421
422	if (devid != CS35L32_CHIP_ID) {
423		ret = -ENODEV;
424		dev_err(&i2c_client->dev,
425			"CS35L32 Device ID (%X). Expected %X\n",
426			devid, CS35L32_CHIP_ID);
427		goto err_disable;
428	}
429
430	ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, &reg);
431	if (ret < 0) {
432		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
433		goto err_disable;
434	}
435
436	ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
437				    ARRAY_SIZE(cs35l32_monitor_patch));
438	if (ret < 0) {
439		dev_err(&i2c_client->dev, "Failed to apply errata patch\n");
440		goto err_disable;
441	}
442
443	dev_info(&i2c_client->dev,
444		 "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF);
445
446	/* Setup VBOOST Management */
447	if (cs35l32->pdata.boost_mng)
448		regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR,
449				   CS35L32_BOOST_MASK,
450				cs35l32->pdata.boost_mng);
451
452	/* Setup ADSP Format Config */
453	if (cs35l32->pdata.sdout_share)
454		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
455				    CS35L32_ADSP_SHARE_MASK,
456				cs35l32->pdata.sdout_share << 3);
457
458	/* Setup ADSP Data Configuration */
459	if (cs35l32->pdata.sdout_datacfg)
460		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
461				   CS35L32_ADSP_DATACFG_MASK,
462				cs35l32->pdata.sdout_datacfg << 4);
463
464	/* Setup Low Battery Recovery  */
465	if (cs35l32->pdata.batt_recov)
466		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
467				   CS35L32_BATT_REC_MASK,
468				cs35l32->pdata.batt_recov << 1);
469
470	/* Setup Low Battery Threshold */
471	if (cs35l32->pdata.batt_thresh)
472		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
473				   CS35L32_BATT_THRESH_MASK,
474				cs35l32->pdata.batt_thresh << 4);
475
476	/* Power down the AMP */
477	regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP,
478			    CS35L32_PDN_AMP);
479
480	/* Clear MCLK Error Bit since we don't have the clock yet */
481	regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);
482
483	ret = devm_snd_soc_register_component(&i2c_client->dev,
484			&soc_component_dev_cs35l32, cs35l32_dai,
485			ARRAY_SIZE(cs35l32_dai));
486	if (ret < 0)
487		goto err_disable;
488
489	return 0;
490
491err_disable:
492	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
493err_supplies:
494	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
495			       cs35l32->supplies);
496	return ret;
497}
498
499static void cs35l32_i2c_remove(struct i2c_client *i2c_client)
500{
501	struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client);
502
 
 
503	/* Hold down reset */
504	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
 
 
505}
506
507#ifdef CONFIG_PM
508static int cs35l32_runtime_suspend(struct device *dev)
509{
510	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
511
512	regcache_cache_only(cs35l32->regmap, true);
513	regcache_mark_dirty(cs35l32->regmap);
514
515	/* Hold down reset */
516	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
517
518	/* remove power */
519	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
520			       cs35l32->supplies);
521
522	return 0;
523}
524
525static int cs35l32_runtime_resume(struct device *dev)
526{
527	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
528	int ret;
529
530	/* Enable power */
531	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
532				    cs35l32->supplies);
533	if (ret != 0) {
534		dev_err(dev, "Failed to enable supplies: %d\n",
535			ret);
536		return ret;
537	}
538
539	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
540
541	regcache_cache_only(cs35l32->regmap, false);
542	regcache_sync(cs35l32->regmap);
543
544	return 0;
545}
546#endif
547
548static const struct dev_pm_ops cs35l32_runtime_pm = {
549	SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume,
550			   NULL)
551};
552
553static const struct of_device_id cs35l32_of_match[] = {
554	{ .compatible = "cirrus,cs35l32", },
555	{},
556};
557MODULE_DEVICE_TABLE(of, cs35l32_of_match);
558
559
560static const struct i2c_device_id cs35l32_id[] = {
561	{"cs35l32"},
562	{}
563};
564
565MODULE_DEVICE_TABLE(i2c, cs35l32_id);
566
567static struct i2c_driver cs35l32_i2c_driver = {
568	.driver = {
569		   .name = "cs35l32",
570		   .pm = &cs35l32_runtime_pm,
571		   .of_match_table = cs35l32_of_match,
572		   },
573	.id_table = cs35l32_id,
574	.probe = cs35l32_i2c_probe,
575	.remove = cs35l32_i2c_remove,
576};
577
578module_i2c_driver(cs35l32_i2c_driver);
579
580MODULE_DESCRIPTION("ASoC CS35L32 driver");
581MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
582MODULE_LICENSE("GPL");
v4.6
 
  1/*
  2 * cs35l32.c -- CS35L32 ALSA SoC audio driver
  3 *
  4 * Copyright 2014 CirrusLogic, Inc.
  5 *
  6 * Author: Brian Austin <brian.austin@cirrus.com>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License version 2 as
 10 * published by the Free Software Foundation.
 11 *
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/moduleparam.h>
 16#include <linux/kernel.h>
 17#include <linux/init.h>
 18#include <linux/delay.h>
 19#include <linux/i2c.h>
 20#include <linux/gpio.h>
 21#include <linux/regmap.h>
 22#include <linux/slab.h>
 23#include <linux/platform_device.h>
 24#include <linux/regulator/consumer.h>
 25#include <linux/gpio/consumer.h>
 26#include <linux/of_device.h>
 27#include <sound/core.h>
 28#include <sound/pcm.h>
 29#include <sound/pcm_params.h>
 30#include <sound/soc.h>
 31#include <sound/soc-dapm.h>
 32#include <sound/initval.h>
 33#include <sound/tlv.h>
 34#include <dt-bindings/sound/cs35l32.h>
 35
 36#include "cs35l32.h"
 
 37
 38#define CS35L32_NUM_SUPPLIES 2
 39static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = {
 40	"VA",
 41	"VP",
 42};
 43
 44struct  cs35l32_private {
 45	struct regmap *regmap;
 46	struct snd_soc_codec *codec;
 47	struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES];
 48	struct cs35l32_platform_data pdata;
 49	struct gpio_desc *reset_gpio;
 50};
 51
 52static const struct reg_default cs35l32_reg_defaults[] = {
 53
 54	{ 0x06, 0x04 }, /* Power Ctl 1 */
 55	{ 0x07, 0xE8 }, /* Power Ctl 2 */
 56	{ 0x08, 0x40 }, /* Clock Ctl */
 57	{ 0x09, 0x20 }, /* Low Battery Threshold */
 58	{ 0x0A, 0x00 }, /* Voltage Monitor [RO] */
 59	{ 0x0B, 0x40 }, /* Conv Peak Curr Protection CTL */
 60	{ 0x0C, 0x07 }, /* IMON Scaling */
 61	{ 0x0D, 0x03 }, /* Audio/LED Pwr Manager */
 62	{ 0x0F, 0x20 }, /* Serial Port Control */
 63	{ 0x10, 0x14 }, /* Class D Amp CTL */
 64	{ 0x11, 0x00 }, /* Protection Release CTL */
 65	{ 0x12, 0xFF }, /* Interrupt Mask 1 */
 66	{ 0x13, 0xFF }, /* Interrupt Mask 2 */
 67	{ 0x14, 0xFF }, /* Interrupt Mask 3 */
 68	{ 0x19, 0x00 }, /* LED Flash Mode Current */
 69	{ 0x1A, 0x00 }, /* LED Movie Mode Current */
 70	{ 0x1B, 0x20 }, /* LED Flash Timer */
 71	{ 0x1C, 0x00 }, /* LED Flash Inhibit Current */
 72};
 73
 74static bool cs35l32_readable_register(struct device *dev, unsigned int reg)
 75{
 76	switch (reg) {
 77	case CS35L32_DEVID_AB ... CS35L32_AUDIO_LED_MNGR:
 78	case CS35L32_ADSP_CTL ... CS35L32_FLASH_INHIBIT:
 79		return true;
 80	default:
 81		return false;
 82	}
 83}
 84
 85static bool cs35l32_volatile_register(struct device *dev, unsigned int reg)
 86{
 87	switch (reg) {
 88	case CS35L32_DEVID_AB ... CS35L32_REV_ID:
 89	case CS35L32_INT_STATUS_1 ... CS35L32_LED_STATUS:
 90		return true;
 91	default:
 92		return false;
 93	}
 94}
 95
 96static bool cs35l32_precious_register(struct device *dev, unsigned int reg)
 97{
 98	switch (reg) {
 99	case CS35L32_INT_STATUS_1 ... CS35L32_LED_STATUS:
100		return true;
101	default:
102		return false;
103	}
104}
105
106static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 300, 0);
107
108static const struct snd_kcontrol_new imon_ctl =
109	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 6, 1, 1);
110
111static const struct snd_kcontrol_new vmon_ctl =
112	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 7, 1, 1);
113
114static const struct snd_kcontrol_new vpmon_ctl =
115	SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 5, 1, 1);
116
117static const struct snd_kcontrol_new cs35l32_snd_controls[] = {
118	SOC_SINGLE_TLV("Speaker Volume", CS35L32_CLASSD_CTL,
119		       3, 0x04, 1, classd_ctl_tlv),
120	SOC_SINGLE("Zero Cross Switch", CS35L32_CLASSD_CTL, 2, 1, 0),
121	SOC_SINGLE("Gain Manager Switch", CS35L32_AUDIO_LED_MNGR, 3, 1, 0),
122};
123
124static const struct snd_soc_dapm_widget cs35l32_dapm_widgets[] = {
125
126	SND_SOC_DAPM_SUPPLY("BOOST", CS35L32_PWRCTL1, 2, 1, NULL, 0),
127	SND_SOC_DAPM_OUT_DRV("Speaker", CS35L32_PWRCTL1, 7, 1, NULL, 0),
128
129	SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L32_PWRCTL2, 3, 1),
130
131	SND_SOC_DAPM_INPUT("VP"),
132	SND_SOC_DAPM_INPUT("ISENSE"),
133	SND_SOC_DAPM_INPUT("VSENSE"),
134
135	SND_SOC_DAPM_SWITCH("VMON ADC", CS35L32_PWRCTL2, 7, 1, &vmon_ctl),
136	SND_SOC_DAPM_SWITCH("IMON ADC", CS35L32_PWRCTL2, 6, 1, &imon_ctl),
137	SND_SOC_DAPM_SWITCH("VPMON ADC", CS35L32_PWRCTL2, 5, 1, &vpmon_ctl),
138};
139
140static const struct snd_soc_dapm_route cs35l32_audio_map[] = {
141
142	{"Speaker", NULL, "BOOST"},
143
144	{"VMON ADC", NULL, "VSENSE"},
145	{"IMON ADC", NULL, "ISENSE"},
146	{"VPMON ADC", NULL, "VP"},
147
148	{"SDOUT", "Switch", "VMON ADC"},
149	{"SDOUT",  "Switch", "IMON ADC"},
150	{"SDOUT", "Switch", "VPMON ADC"},
151
152	{"Capture", NULL, "SDOUT"},
153};
154
155static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
156{
157	struct snd_soc_codec *codec = codec_dai->codec;
158
159	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
160	case SND_SOC_DAIFMT_CBM_CFM:
161		snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
162				    CS35L32_ADSP_MASTER_MASK,
163				CS35L32_ADSP_MASTER_MASK);
164		break;
165	case SND_SOC_DAIFMT_CBS_CFS:
166		snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
167				    CS35L32_ADSP_MASTER_MASK, 0);
168		break;
169	default:
170		return -EINVAL;
171	}
172
173	return 0;
174}
175
176static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate)
177{
178	struct snd_soc_codec *codec = dai->codec;
179
180	return snd_soc_update_bits(codec, CS35L32_PWRCTL2,
181					CS35L32_SDOUT_3ST, tristate << 3);
182}
183
184static const struct snd_soc_dai_ops cs35l32_ops = {
185	.set_fmt = cs35l32_set_dai_fmt,
186	.set_tristate = cs35l32_set_tristate,
187};
188
189static struct snd_soc_dai_driver cs35l32_dai[] = {
190	{
191		.name = "cs35l32-monitor",
192		.id = 0,
193		.capture = {
194			.stream_name = "Capture",
195			.channels_min = 2,
196			.channels_max = 2,
197			.rates = CS35L32_RATES,
198			.formats = CS35L32_FORMATS,
199		},
200		.ops = &cs35l32_ops,
201		.symmetric_rates = 1,
202	}
203};
204
205static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
206			      int clk_id, int source, unsigned int freq, int dir)
207{
208	unsigned int val;
209
210	switch (freq) {
211	case 6000000:
212		val = CS35L32_MCLK_RATIO;
213		break;
214	case 12000000:
215		val = CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO;
216		break;
217	case 6144000:
218		val = 0;
219		break;
220	case 12288000:
221		val = CS35L32_MCLK_DIV2_MASK;
222		break;
223	default:
224		return -EINVAL;
225	}
226
227	return snd_soc_update_bits(codec, CS35L32_CLK_CTL,
228			CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
229}
230
231static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
232	.set_sysclk = cs35l32_codec_set_sysclk,
233
234	.dapm_widgets = cs35l32_dapm_widgets,
235	.num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets),
236	.dapm_routes = cs35l32_audio_map,
237	.num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map),
238
239	.controls = cs35l32_snd_controls,
240	.num_controls = ARRAY_SIZE(cs35l32_snd_controls),
 
241};
242
243/* Current and threshold powerup sequence Pg37 in datasheet */
244static const struct reg_sequence cs35l32_monitor_patch[] = {
245
246	{ 0x00, 0x99 },
247	{ 0x48, 0x17 },
248	{ 0x49, 0x56 },
249	{ 0x43, 0x01 },
250	{ 0x3B, 0x62 },
251	{ 0x3C, 0x80 },
252	{ 0x00, 0x00 },
253};
254
255static const struct regmap_config cs35l32_regmap = {
256	.reg_bits = 8,
257	.val_bits = 8,
258
259	.max_register = CS35L32_MAX_REGISTER,
260	.reg_defaults = cs35l32_reg_defaults,
261	.num_reg_defaults = ARRAY_SIZE(cs35l32_reg_defaults),
262	.volatile_reg = cs35l32_volatile_register,
263	.readable_reg = cs35l32_readable_register,
264	.precious_reg = cs35l32_precious_register,
265	.cache_type = REGCACHE_RBTREE,
 
 
 
266};
267
268static int cs35l32_handle_of_data(struct i2c_client *i2c_client,
269				    struct cs35l32_platform_data *pdata)
270{
271	struct device_node *np = i2c_client->dev.of_node;
272	unsigned int val;
273
274	if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0)
275		pdata->sdout_share = val;
276
277	if (of_property_read_u32(np, "cirrus,boost-manager", &val))
278		val = -1u;
279
280	switch (val) {
281	case CS35L32_BOOST_MGR_AUTO:
282	case CS35L32_BOOST_MGR_AUTO_AUDIO:
283	case CS35L32_BOOST_MGR_BYPASS:
284	case CS35L32_BOOST_MGR_FIXED:
285		pdata->boost_mng = val;
286		break;
287	case -1u:
288	default:
289		dev_err(&i2c_client->dev,
290			"Wrong cirrus,boost-manager DT value %d\n", val);
291		pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS;
292	}
293
294	if (of_property_read_u32(np, "cirrus,sdout-datacfg", &val))
295		val = -1u;
296	switch (val) {
297	case CS35L32_DATA_CFG_LR_VP:
298	case CS35L32_DATA_CFG_LR_STAT:
299	case CS35L32_DATA_CFG_LR:
300	case CS35L32_DATA_CFG_LR_VPSTAT:
301		pdata->sdout_datacfg = val;
302		break;
303	case -1u:
304	default:
305		dev_err(&i2c_client->dev,
306			"Wrong cirrus,sdout-datacfg DT value %d\n", val);
307		pdata->sdout_datacfg = CS35L32_DATA_CFG_LR;
308	}
309
310	if (of_property_read_u32(np, "cirrus,battery-threshold", &val))
311		val = -1u;
312	switch (val) {
313	case CS35L32_BATT_THRESH_3_1V:
314	case CS35L32_BATT_THRESH_3_2V:
315	case CS35L32_BATT_THRESH_3_3V:
316	case CS35L32_BATT_THRESH_3_4V:
317		pdata->batt_thresh = val;
318		break;
319	case -1u:
320	default:
321		dev_err(&i2c_client->dev,
322			"Wrong cirrus,battery-threshold DT value %d\n", val);
323		pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V;
324	}
325
326	if (of_property_read_u32(np, "cirrus,battery-recovery", &val))
327		val = -1u;
328	switch (val) {
329	case CS35L32_BATT_RECOV_3_1V:
330	case CS35L32_BATT_RECOV_3_2V:
331	case CS35L32_BATT_RECOV_3_3V:
332	case CS35L32_BATT_RECOV_3_4V:
333	case CS35L32_BATT_RECOV_3_5V:
334	case CS35L32_BATT_RECOV_3_6V:
335		pdata->batt_recov = val;
336		break;
337	case -1u:
338	default:
339		dev_err(&i2c_client->dev,
340			"Wrong cirrus,battery-recovery DT value %d\n", val);
341		pdata->batt_recov = CS35L32_BATT_RECOV_3_4V;
342	}
343
344	return 0;
345}
346
347static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
348				       const struct i2c_device_id *id)
349{
350	struct cs35l32_private *cs35l32;
351	struct cs35l32_platform_data *pdata =
352		dev_get_platdata(&i2c_client->dev);
353	int ret, i;
354	unsigned int devid = 0;
355	unsigned int reg;
356
357
358	cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private),
359			       GFP_KERNEL);
360	if (!cs35l32) {
361		dev_err(&i2c_client->dev, "could not allocate codec\n");
362		return -ENOMEM;
363	}
364
365	i2c_set_clientdata(i2c_client, cs35l32);
366
367	cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap);
368	if (IS_ERR(cs35l32->regmap)) {
369		ret = PTR_ERR(cs35l32->regmap);
370		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
371		return ret;
372	}
373
374	if (pdata) {
375		cs35l32->pdata = *pdata;
376	} else {
377		pdata = devm_kzalloc(&i2c_client->dev,
378				     sizeof(struct cs35l32_platform_data),
379				GFP_KERNEL);
380		if (!pdata) {
381			dev_err(&i2c_client->dev, "could not allocate pdata\n");
382			return -ENOMEM;
383		}
384		if (i2c_client->dev.of_node) {
385			ret = cs35l32_handle_of_data(i2c_client,
386						     &cs35l32->pdata);
387			if (ret != 0)
388				return ret;
389		}
390	}
391
392	for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++)
393		cs35l32->supplies[i].supply = cs35l32_supply_names[i];
394
395	ret = devm_regulator_bulk_get(&i2c_client->dev,
396				      ARRAY_SIZE(cs35l32->supplies),
397				      cs35l32->supplies);
398	if (ret != 0) {
399		dev_err(&i2c_client->dev,
400			"Failed to request supplies: %d\n", ret);
401		return ret;
402	}
403
404	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
405				    cs35l32->supplies);
406	if (ret != 0) {
407		dev_err(&i2c_client->dev,
408			"Failed to enable supplies: %d\n", ret);
409		return ret;
410	}
411
412	/* Reset the Device */
413	cs35l32->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
414		"reset", GPIOD_OUT_LOW);
415	if (IS_ERR(cs35l32->reset_gpio))
416		return PTR_ERR(cs35l32->reset_gpio);
 
 
417
418	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
419
420	/* initialize codec */
421	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg);
422	devid = (reg & 0xFF) << 12;
423
424	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, &reg);
425	devid |= (reg & 0xFF) << 4;
426
427	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, &reg);
428	devid |= (reg & 0xF0) >> 4;
429
430	if (devid != CS35L32_CHIP_ID) {
431		ret = -ENODEV;
432		dev_err(&i2c_client->dev,
433			"CS35L32 Device ID (%X). Expected %X\n",
434			devid, CS35L32_CHIP_ID);
435		return ret;
436	}
437
438	ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, &reg);
439	if (ret < 0) {
440		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
441		return ret;
442	}
443
444	ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
445				    ARRAY_SIZE(cs35l32_monitor_patch));
446	if (ret < 0) {
447		dev_err(&i2c_client->dev, "Failed to apply errata patch\n");
448		return ret;
449	}
450
451	dev_info(&i2c_client->dev,
452		 "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF);
453
454	/* Setup VBOOST Management */
455	if (cs35l32->pdata.boost_mng)
456		regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR,
457				   CS35L32_BOOST_MASK,
458				cs35l32->pdata.boost_mng);
459
460	/* Setup ADSP Format Config */
461	if (cs35l32->pdata.sdout_share)
462		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
463				    CS35L32_ADSP_SHARE_MASK,
464				cs35l32->pdata.sdout_share << 3);
465
466	/* Setup ADSP Data Configuration */
467	if (cs35l32->pdata.sdout_datacfg)
468		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
469				   CS35L32_ADSP_DATACFG_MASK,
470				cs35l32->pdata.sdout_datacfg << 4);
471
472	/* Setup Low Battery Recovery  */
473	if (cs35l32->pdata.batt_recov)
474		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
475				   CS35L32_BATT_REC_MASK,
476				cs35l32->pdata.batt_recov << 1);
477
478	/* Setup Low Battery Threshold */
479	if (cs35l32->pdata.batt_thresh)
480		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
481				   CS35L32_BATT_THRESH_MASK,
482				cs35l32->pdata.batt_thresh << 4);
483
484	/* Power down the AMP */
485	regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP,
486			    CS35L32_PDN_AMP);
487
488	/* Clear MCLK Error Bit since we don't have the clock yet */
489	ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);
490
491	ret =  snd_soc_register_codec(&i2c_client->dev,
492			&soc_codec_dev_cs35l32, cs35l32_dai,
493			ARRAY_SIZE(cs35l32_dai));
494	if (ret < 0)
495		goto err_disable;
496
497	return 0;
498
499err_disable:
 
 
500	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
501			       cs35l32->supplies);
502	return ret;
503}
504
505static int cs35l32_i2c_remove(struct i2c_client *i2c_client)
506{
507	struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client);
508
509	snd_soc_unregister_codec(&i2c_client->dev);
510
511	/* Hold down reset */
512	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
513
514	return 0;
515}
516
517#ifdef CONFIG_PM
518static int cs35l32_runtime_suspend(struct device *dev)
519{
520	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
521
522	regcache_cache_only(cs35l32->regmap, true);
523	regcache_mark_dirty(cs35l32->regmap);
524
525	/* Hold down reset */
526	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
527
528	/* remove power */
529	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
530			       cs35l32->supplies);
531
532	return 0;
533}
534
535static int cs35l32_runtime_resume(struct device *dev)
536{
537	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
538	int ret;
539
540	/* Enable power */
541	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
542				    cs35l32->supplies);
543	if (ret != 0) {
544		dev_err(dev, "Failed to enable supplies: %d\n",
545			ret);
546		return ret;
547	}
548
549	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
550
551	regcache_cache_only(cs35l32->regmap, false);
552	regcache_sync(cs35l32->regmap);
553
554	return 0;
555}
556#endif
557
558static const struct dev_pm_ops cs35l32_runtime_pm = {
559	SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume,
560			   NULL)
561};
562
563static const struct of_device_id cs35l32_of_match[] = {
564	{ .compatible = "cirrus,cs35l32", },
565	{},
566};
567MODULE_DEVICE_TABLE(of, cs35l32_of_match);
568
569
570static const struct i2c_device_id cs35l32_id[] = {
571	{"cs35l32", 0},
572	{}
573};
574
575MODULE_DEVICE_TABLE(i2c, cs35l32_id);
576
577static struct i2c_driver cs35l32_i2c_driver = {
578	.driver = {
579		   .name = "cs35l32",
580		   .pm = &cs35l32_runtime_pm,
581		   .of_match_table = cs35l32_of_match,
582		   },
583	.id_table = cs35l32_id,
584	.probe = cs35l32_i2c_probe,
585	.remove = cs35l32_i2c_remove,
586};
587
588module_i2c_driver(cs35l32_i2c_driver);
589
590MODULE_DESCRIPTION("ASoC CS35L32 driver");
591MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
592MODULE_LICENSE("GPL");