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.17
 
  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_component *component;
 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_component *component = codec_dai->component;
158
159	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
160	case SND_SOC_DAIFMT_CBM_CFM:
161		snd_soc_component_update_bits(component, 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_component_update_bits(component, 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_component *component = dai->component;
179
180	return snd_soc_component_update_bits(component, 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_component_set_sysclk(struct snd_soc_component *component,
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_component_update_bits(component, CS35L32_CLK_CTL,
228			CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
229}
230
231static const struct snd_soc_component_driver soc_component_dev_cs35l32 = {
232	.set_sysclk		= cs35l32_component_set_sysclk,
233	.controls		= cs35l32_snd_controls,
234	.num_controls		= ARRAY_SIZE(cs35l32_snd_controls),
235	.dapm_widgets		= cs35l32_dapm_widgets,
236	.num_dapm_widgets	= ARRAY_SIZE(cs35l32_dapm_widgets),
237	.dapm_routes		= cs35l32_audio_map,
238	.num_dapm_routes	= ARRAY_SIZE(cs35l32_audio_map),
239	.idle_bias_on		= 1,
240	.use_pmdown_time	= 1,
241	.endianness		= 1,
242	.non_legacy_dai_naming	= 1,
243};
244
245/* Current and threshold powerup sequence Pg37 in datasheet */
246static const struct reg_sequence cs35l32_monitor_patch[] = {
247
248	{ 0x00, 0x99 },
249	{ 0x48, 0x17 },
250	{ 0x49, 0x56 },
251	{ 0x43, 0x01 },
252	{ 0x3B, 0x62 },
253	{ 0x3C, 0x80 },
254	{ 0x00, 0x00 },
255};
256
257static const struct regmap_config cs35l32_regmap = {
258	.reg_bits = 8,
259	.val_bits = 8,
260
261	.max_register = CS35L32_MAX_REGISTER,
262	.reg_defaults = cs35l32_reg_defaults,
263	.num_reg_defaults = ARRAY_SIZE(cs35l32_reg_defaults),
264	.volatile_reg = cs35l32_volatile_register,
265	.readable_reg = cs35l32_readable_register,
266	.precious_reg = cs35l32_precious_register,
267	.cache_type = REGCACHE_RBTREE,
 
 
 
268};
269
270static int cs35l32_handle_of_data(struct i2c_client *i2c_client,
271				    struct cs35l32_platform_data *pdata)
272{
273	struct device_node *np = i2c_client->dev.of_node;
274	unsigned int val;
275
276	if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0)
277		pdata->sdout_share = val;
278
279	if (of_property_read_u32(np, "cirrus,boost-manager", &val))
280		val = -1u;
281
282	switch (val) {
283	case CS35L32_BOOST_MGR_AUTO:
284	case CS35L32_BOOST_MGR_AUTO_AUDIO:
285	case CS35L32_BOOST_MGR_BYPASS:
286	case CS35L32_BOOST_MGR_FIXED:
287		pdata->boost_mng = val;
288		break;
289	case -1u:
290	default:
291		dev_err(&i2c_client->dev,
292			"Wrong cirrus,boost-manager DT value %d\n", val);
293		pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS;
294	}
295
296	if (of_property_read_u32(np, "cirrus,sdout-datacfg", &val))
297		val = -1u;
298	switch (val) {
299	case CS35L32_DATA_CFG_LR_VP:
300	case CS35L32_DATA_CFG_LR_STAT:
301	case CS35L32_DATA_CFG_LR:
302	case CS35L32_DATA_CFG_LR_VPSTAT:
303		pdata->sdout_datacfg = val;
304		break;
305	case -1u:
306	default:
307		dev_err(&i2c_client->dev,
308			"Wrong cirrus,sdout-datacfg DT value %d\n", val);
309		pdata->sdout_datacfg = CS35L32_DATA_CFG_LR;
310	}
311
312	if (of_property_read_u32(np, "cirrus,battery-threshold", &val))
313		val = -1u;
314	switch (val) {
315	case CS35L32_BATT_THRESH_3_1V:
316	case CS35L32_BATT_THRESH_3_2V:
317	case CS35L32_BATT_THRESH_3_3V:
318	case CS35L32_BATT_THRESH_3_4V:
319		pdata->batt_thresh = val;
320		break;
321	case -1u:
322	default:
323		dev_err(&i2c_client->dev,
324			"Wrong cirrus,battery-threshold DT value %d\n", val);
325		pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V;
326	}
327
328	if (of_property_read_u32(np, "cirrus,battery-recovery", &val))
329		val = -1u;
330	switch (val) {
331	case CS35L32_BATT_RECOV_3_1V:
332	case CS35L32_BATT_RECOV_3_2V:
333	case CS35L32_BATT_RECOV_3_3V:
334	case CS35L32_BATT_RECOV_3_4V:
335	case CS35L32_BATT_RECOV_3_5V:
336	case CS35L32_BATT_RECOV_3_6V:
337		pdata->batt_recov = val;
338		break;
339	case -1u:
340	default:
341		dev_err(&i2c_client->dev,
342			"Wrong cirrus,battery-recovery DT value %d\n", val);
343		pdata->batt_recov = CS35L32_BATT_RECOV_3_4V;
344	}
345
346	return 0;
347}
348
349static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
350				       const struct i2c_device_id *id)
351{
352	struct cs35l32_private *cs35l32;
353	struct cs35l32_platform_data *pdata =
354		dev_get_platdata(&i2c_client->dev);
355	int ret, i;
356	unsigned int devid = 0;
357	unsigned int reg;
358
359	cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l32), GFP_KERNEL);
360	if (!cs35l32)
361		return -ENOMEM;
362
363	i2c_set_clientdata(i2c_client, cs35l32);
364
365	cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap);
366	if (IS_ERR(cs35l32->regmap)) {
367		ret = PTR_ERR(cs35l32->regmap);
368		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
369		return ret;
370	}
371
372	if (pdata) {
373		cs35l32->pdata = *pdata;
374	} else {
375		pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
376				     GFP_KERNEL);
377		if (!pdata)
378			return -ENOMEM;
379
380		if (i2c_client->dev.of_node) {
381			ret = cs35l32_handle_of_data(i2c_client,
382						     &cs35l32->pdata);
383			if (ret != 0)
384				return ret;
385		}
386	}
387
388	for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++)
389		cs35l32->supplies[i].supply = cs35l32_supply_names[i];
390
391	ret = devm_regulator_bulk_get(&i2c_client->dev,
392				      ARRAY_SIZE(cs35l32->supplies),
393				      cs35l32->supplies);
394	if (ret != 0) {
395		dev_err(&i2c_client->dev,
396			"Failed to request supplies: %d\n", ret);
397		return ret;
398	}
399
400	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
401				    cs35l32->supplies);
402	if (ret != 0) {
403		dev_err(&i2c_client->dev,
404			"Failed to enable supplies: %d\n", ret);
405		return ret;
406	}
407
408	/* Reset the Device */
409	cs35l32->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
410		"reset", GPIOD_OUT_LOW);
411	if (IS_ERR(cs35l32->reset_gpio))
412		return PTR_ERR(cs35l32->reset_gpio);
 
 
413
414	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
415
416	/* initialize codec */
417	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg);
418	devid = (reg & 0xFF) << 12;
419
420	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, &reg);
421	devid |= (reg & 0xFF) << 4;
422
423	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, &reg);
424	devid |= (reg & 0xF0) >> 4;
425
426	if (devid != CS35L32_CHIP_ID) {
427		ret = -ENODEV;
428		dev_err(&i2c_client->dev,
429			"CS35L32 Device ID (%X). Expected %X\n",
430			devid, CS35L32_CHIP_ID);
431		return ret;
432	}
433
434	ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, &reg);
435	if (ret < 0) {
436		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
437		return ret;
438	}
439
440	ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
441				    ARRAY_SIZE(cs35l32_monitor_patch));
442	if (ret < 0) {
443		dev_err(&i2c_client->dev, "Failed to apply errata patch\n");
444		return ret;
445	}
446
447	dev_info(&i2c_client->dev,
448		 "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF);
449
450	/* Setup VBOOST Management */
451	if (cs35l32->pdata.boost_mng)
452		regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR,
453				   CS35L32_BOOST_MASK,
454				cs35l32->pdata.boost_mng);
455
456	/* Setup ADSP Format Config */
457	if (cs35l32->pdata.sdout_share)
458		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
459				    CS35L32_ADSP_SHARE_MASK,
460				cs35l32->pdata.sdout_share << 3);
461
462	/* Setup ADSP Data Configuration */
463	if (cs35l32->pdata.sdout_datacfg)
464		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
465				   CS35L32_ADSP_DATACFG_MASK,
466				cs35l32->pdata.sdout_datacfg << 4);
467
468	/* Setup Low Battery Recovery  */
469	if (cs35l32->pdata.batt_recov)
470		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
471				   CS35L32_BATT_REC_MASK,
472				cs35l32->pdata.batt_recov << 1);
473
474	/* Setup Low Battery Threshold */
475	if (cs35l32->pdata.batt_thresh)
476		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
477				   CS35L32_BATT_THRESH_MASK,
478				cs35l32->pdata.batt_thresh << 4);
479
480	/* Power down the AMP */
481	regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP,
482			    CS35L32_PDN_AMP);
483
484	/* Clear MCLK Error Bit since we don't have the clock yet */
485	ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);
486
487	ret = devm_snd_soc_register_component(&i2c_client->dev,
488			&soc_component_dev_cs35l32, cs35l32_dai,
489			ARRAY_SIZE(cs35l32_dai));
490	if (ret < 0)
491		goto err_disable;
492
493	return 0;
494
495err_disable:
 
 
496	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
497			       cs35l32->supplies);
498	return ret;
499}
500
501static int cs35l32_i2c_remove(struct i2c_client *i2c_client)
502{
503	struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client);
504
505	/* Hold down reset */
506	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
507
508	return 0;
509}
510
511#ifdef CONFIG_PM
512static int cs35l32_runtime_suspend(struct device *dev)
513{
514	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
515
516	regcache_cache_only(cs35l32->regmap, true);
517	regcache_mark_dirty(cs35l32->regmap);
518
519	/* Hold down reset */
520	gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
521
522	/* remove power */
523	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
524			       cs35l32->supplies);
525
526	return 0;
527}
528
529static int cs35l32_runtime_resume(struct device *dev)
530{
531	struct cs35l32_private *cs35l32 = dev_get_drvdata(dev);
532	int ret;
533
534	/* Enable power */
535	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
536				    cs35l32->supplies);
537	if (ret != 0) {
538		dev_err(dev, "Failed to enable supplies: %d\n",
539			ret);
540		return ret;
541	}
542
543	gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
544
545	regcache_cache_only(cs35l32->regmap, false);
546	regcache_sync(cs35l32->regmap);
547
548	return 0;
549}
550#endif
551
552static const struct dev_pm_ops cs35l32_runtime_pm = {
553	SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume,
554			   NULL)
555};
556
557static const struct of_device_id cs35l32_of_match[] = {
558	{ .compatible = "cirrus,cs35l32", },
559	{},
560};
561MODULE_DEVICE_TABLE(of, cs35l32_of_match);
562
563
564static const struct i2c_device_id cs35l32_id[] = {
565	{"cs35l32", 0},
566	{}
567};
568
569MODULE_DEVICE_TABLE(i2c, cs35l32_id);
570
571static struct i2c_driver cs35l32_i2c_driver = {
572	.driver = {
573		   .name = "cs35l32",
574		   .pm = &cs35l32_runtime_pm,
575		   .of_match_table = cs35l32_of_match,
576		   },
577	.id_table = cs35l32_id,
578	.probe = cs35l32_i2c_probe,
579	.remove = cs35l32_i2c_remove,
580};
581
582module_i2c_driver(cs35l32_i2c_driver);
583
584MODULE_DESCRIPTION("ASoC CS35L32 driver");
585MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
586MODULE_LICENSE("GPL");