xref: /linux/sound/soc/codecs/cs35l45-tables.c (revision 0d463d016000d68d7e982720b5e4380b2d83409a)
1*0d463d01SJames Schulman // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*0d463d01SJames Schulman //
3*0d463d01SJames Schulman // cs35l45-tables.c -- CS35L45 ALSA SoC audio driver
4*0d463d01SJames Schulman //
5*0d463d01SJames Schulman // Copyright 2019-2022 Cirrus Logic, Inc.
6*0d463d01SJames Schulman //
7*0d463d01SJames Schulman // Author: James Schulman <james.schulman@cirrus.com>
8*0d463d01SJames Schulman 
9*0d463d01SJames Schulman #include <linux/module.h>
10*0d463d01SJames Schulman #include <linux/regmap.h>
11*0d463d01SJames Schulman 
12*0d463d01SJames Schulman #include "cs35l45.h"
13*0d463d01SJames Schulman 
14*0d463d01SJames Schulman static const struct reg_sequence cs35l45_patch[] = {
15*0d463d01SJames Schulman 	{ 0x00000040,			0x00000055 },
16*0d463d01SJames Schulman 	{ 0x00000040,			0x000000AA },
17*0d463d01SJames Schulman 	{ 0x00000044,			0x00000055 },
18*0d463d01SJames Schulman 	{ 0x00000044,			0x000000AA },
19*0d463d01SJames Schulman 	{ 0x00006480,			0x0830500A },
20*0d463d01SJames Schulman 	{ 0x00007C60,			0x1000850B },
21*0d463d01SJames Schulman 	{ CS35L45_BOOST_OV_CFG,		0x007000D0 },
22*0d463d01SJames Schulman 	{ CS35L45_LDPM_CONFIG,		0x0001B636 },
23*0d463d01SJames Schulman 	{ 0x00002C08,			0x00000009 },
24*0d463d01SJames Schulman 	{ 0x00006850,			0x0A30FFC4 },
25*0d463d01SJames Schulman 	{ 0x00003820,			0x00040100 },
26*0d463d01SJames Schulman 	{ 0x00003824,			0x00000000 },
27*0d463d01SJames Schulman 	{ 0x00007CFC,			0x62870004 },
28*0d463d01SJames Schulman 	{ 0x00007C60,			0x1001850B },
29*0d463d01SJames Schulman 	{ 0x00000040,			0x00000000 },
30*0d463d01SJames Schulman 	{ 0x00000044,			0x00000000 },
31*0d463d01SJames Schulman 	{ CS35L45_BOOST_CCM_CFG,	0xF0000003 },
32*0d463d01SJames Schulman 	{ CS35L45_BOOST_DCM_CFG,	0x08710220 },
33*0d463d01SJames Schulman 	{ CS35L45_ERROR_RELEASE,	0x00200000 },
34*0d463d01SJames Schulman };
35*0d463d01SJames Schulman 
36*0d463d01SJames Schulman int cs35l45_apply_patch(struct cs35l45_private *cs35l45)
37*0d463d01SJames Schulman {
38*0d463d01SJames Schulman 	return regmap_register_patch(cs35l45->regmap, cs35l45_patch,
39*0d463d01SJames Schulman 				     ARRAY_SIZE(cs35l45_patch));
40*0d463d01SJames Schulman }
41*0d463d01SJames Schulman EXPORT_SYMBOL_GPL(cs35l45_apply_patch);
42*0d463d01SJames Schulman 
43*0d463d01SJames Schulman static const struct reg_default cs35l45_defaults[] = {
44*0d463d01SJames Schulman 	{ CS35L45_BLOCK_ENABLES,		0x00003323 },
45*0d463d01SJames Schulman 	{ CS35L45_BLOCK_ENABLES2,		0x00000010 },
46*0d463d01SJames Schulman 	{ CS35L45_REFCLK_INPUT,			0x00000510 },
47*0d463d01SJames Schulman 	{ CS35L45_GLOBAL_SAMPLE_RATE,		0x00000003 },
48*0d463d01SJames Schulman 	{ CS35L45_ASP_ENABLES1,			0x00000000 },
49*0d463d01SJames Schulman 	{ CS35L45_ASP_CONTROL1,			0x00000028 },
50*0d463d01SJames Schulman 	{ CS35L45_ASP_CONTROL2,			0x18180200 },
51*0d463d01SJames Schulman 	{ CS35L45_ASP_CONTROL3,			0x00000002 },
52*0d463d01SJames Schulman 	{ CS35L45_ASP_FRAME_CONTROL1,		0x03020100 },
53*0d463d01SJames Schulman 	{ CS35L45_ASP_FRAME_CONTROL2,		0x00000004 },
54*0d463d01SJames Schulman 	{ CS35L45_ASP_FRAME_CONTROL5,		0x00000100 },
55*0d463d01SJames Schulman 	{ CS35L45_ASP_DATA_CONTROL1,		0x00000018 },
56*0d463d01SJames Schulman 	{ CS35L45_ASP_DATA_CONTROL5,		0x00000018 },
57*0d463d01SJames Schulman 	{ CS35L45_DACPCM1_INPUT,		0x00000008 },
58*0d463d01SJames Schulman 	{ CS35L45_ASPTX1_INPUT,			0x00000018 },
59*0d463d01SJames Schulman 	{ CS35L45_ASPTX2_INPUT,			0x00000019 },
60*0d463d01SJames Schulman 	{ CS35L45_ASPTX3_INPUT,			0x00000020 },
61*0d463d01SJames Schulman 	{ CS35L45_ASPTX4_INPUT,			0x00000028 },
62*0d463d01SJames Schulman 	{ CS35L45_ASPTX5_INPUT,			0x00000048 },
63*0d463d01SJames Schulman 	{ CS35L45_AMP_PCM_CONTROL,		0x00100000 },
64*0d463d01SJames Schulman };
65*0d463d01SJames Schulman 
66*0d463d01SJames Schulman static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
67*0d463d01SJames Schulman {
68*0d463d01SJames Schulman 	switch (reg) {
69*0d463d01SJames Schulman 	case CS35L45_DEVID ... CS35L45_OTPID:
70*0d463d01SJames Schulman 	case CS35L45_SFT_RESET:
71*0d463d01SJames Schulman 	case CS35L45_GLOBAL_ENABLES:
72*0d463d01SJames Schulman 	case CS35L45_BLOCK_ENABLES:
73*0d463d01SJames Schulman 	case CS35L45_BLOCK_ENABLES2:
74*0d463d01SJames Schulman 	case CS35L45_ERROR_RELEASE:
75*0d463d01SJames Schulman 	case CS35L45_REFCLK_INPUT:
76*0d463d01SJames Schulman 	case CS35L45_GLOBAL_SAMPLE_RATE:
77*0d463d01SJames Schulman 	case CS35L45_ASP_ENABLES1:
78*0d463d01SJames Schulman 	case CS35L45_ASP_CONTROL1:
79*0d463d01SJames Schulman 	case CS35L45_ASP_CONTROL2:
80*0d463d01SJames Schulman 	case CS35L45_ASP_CONTROL3:
81*0d463d01SJames Schulman 	case CS35L45_ASP_FRAME_CONTROL1:
82*0d463d01SJames Schulman 	case CS35L45_ASP_FRAME_CONTROL2:
83*0d463d01SJames Schulman 	case CS35L45_ASP_FRAME_CONTROL5:
84*0d463d01SJames Schulman 	case CS35L45_ASP_DATA_CONTROL1:
85*0d463d01SJames Schulman 	case CS35L45_ASP_DATA_CONTROL5:
86*0d463d01SJames Schulman 	case CS35L45_DACPCM1_INPUT:
87*0d463d01SJames Schulman 	case CS35L45_ASPTX1_INPUT:
88*0d463d01SJames Schulman 	case CS35L45_ASPTX2_INPUT:
89*0d463d01SJames Schulman 	case CS35L45_ASPTX3_INPUT:
90*0d463d01SJames Schulman 	case CS35L45_ASPTX4_INPUT:
91*0d463d01SJames Schulman 	case CS35L45_ASPTX5_INPUT:
92*0d463d01SJames Schulman 	case CS35L45_AMP_PCM_CONTROL:
93*0d463d01SJames Schulman 	case CS35L45_AMP_PCM_HPF_TST:
94*0d463d01SJames Schulman 	case CS35L45_IRQ1_EINT_4:
95*0d463d01SJames Schulman 		return true;
96*0d463d01SJames Schulman 	default:
97*0d463d01SJames Schulman 		return false;
98*0d463d01SJames Schulman 	}
99*0d463d01SJames Schulman }
100*0d463d01SJames Schulman 
101*0d463d01SJames Schulman static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg)
102*0d463d01SJames Schulman {
103*0d463d01SJames Schulman 	switch (reg) {
104*0d463d01SJames Schulman 	case CS35L45_DEVID ... CS35L45_OTPID:
105*0d463d01SJames Schulman 	case CS35L45_SFT_RESET:
106*0d463d01SJames Schulman 	case CS35L45_GLOBAL_ENABLES:
107*0d463d01SJames Schulman 	case CS35L45_ERROR_RELEASE:
108*0d463d01SJames Schulman 	case CS35L45_AMP_PCM_HPF_TST:	/* not cachable */
109*0d463d01SJames Schulman 	case CS35L45_IRQ1_EINT_4:
110*0d463d01SJames Schulman 		return true;
111*0d463d01SJames Schulman 	default:
112*0d463d01SJames Schulman 		return false;
113*0d463d01SJames Schulman 	}
114*0d463d01SJames Schulman }
115*0d463d01SJames Schulman 
116*0d463d01SJames Schulman const struct regmap_config cs35l45_i2c_regmap = {
117*0d463d01SJames Schulman 	.reg_bits = 32,
118*0d463d01SJames Schulman 	.val_bits = 32,
119*0d463d01SJames Schulman 	.reg_stride = 4,
120*0d463d01SJames Schulman 	.reg_format_endian = REGMAP_ENDIAN_BIG,
121*0d463d01SJames Schulman 	.val_format_endian = REGMAP_ENDIAN_BIG,
122*0d463d01SJames Schulman 	.max_register = CS35L45_LASTREG,
123*0d463d01SJames Schulman 	.reg_defaults = cs35l45_defaults,
124*0d463d01SJames Schulman 	.num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),
125*0d463d01SJames Schulman 	.volatile_reg = cs35l45_volatile_reg,
126*0d463d01SJames Schulman 	.readable_reg = cs35l45_readable_reg,
127*0d463d01SJames Schulman 	.cache_type = REGCACHE_RBTREE,
128*0d463d01SJames Schulman };
129*0d463d01SJames Schulman EXPORT_SYMBOL_GPL(cs35l45_i2c_regmap);
130*0d463d01SJames Schulman 
131*0d463d01SJames Schulman const struct regmap_config cs35l45_spi_regmap = {
132*0d463d01SJames Schulman 	.reg_bits = 32,
133*0d463d01SJames Schulman 	.val_bits = 32,
134*0d463d01SJames Schulman 	.pad_bits = 16,
135*0d463d01SJames Schulman 	.reg_stride = 4,
136*0d463d01SJames Schulman 	.reg_format_endian = REGMAP_ENDIAN_BIG,
137*0d463d01SJames Schulman 	.val_format_endian = REGMAP_ENDIAN_BIG,
138*0d463d01SJames Schulman 	.max_register = CS35L45_LASTREG,
139*0d463d01SJames Schulman 	.reg_defaults = cs35l45_defaults,
140*0d463d01SJames Schulman 	.num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),
141*0d463d01SJames Schulman 	.volatile_reg = cs35l45_volatile_reg,
142*0d463d01SJames Schulman 	.readable_reg = cs35l45_readable_reg,
143*0d463d01SJames Schulman 	.cache_type = REGCACHE_RBTREE,
144*0d463d01SJames Schulman };
145*0d463d01SJames Schulman EXPORT_SYMBOL_GPL(cs35l45_spi_regmap);
146*0d463d01SJames Schulman 
147*0d463d01SJames Schulman static const struct {
148*0d463d01SJames Schulman 	u8 cfg_id;
149*0d463d01SJames Schulman 	u32 freq;
150*0d463d01SJames Schulman } cs35l45_pll_refclk_freq[] = {
151*0d463d01SJames Schulman 	{ 0x0C,   128000 },
152*0d463d01SJames Schulman 	{ 0x0F,   256000 },
153*0d463d01SJames Schulman 	{ 0x11,   384000 },
154*0d463d01SJames Schulman 	{ 0x12,   512000 },
155*0d463d01SJames Schulman 	{ 0x15,   768000 },
156*0d463d01SJames Schulman 	{ 0x17,  1024000 },
157*0d463d01SJames Schulman 	{ 0x19,  1411200 },
158*0d463d01SJames Schulman 	{ 0x1B,  1536000 },
159*0d463d01SJames Schulman 	{ 0x1C,  2116800 },
160*0d463d01SJames Schulman 	{ 0x1D,  2048000 },
161*0d463d01SJames Schulman 	{ 0x1E,  2304000 },
162*0d463d01SJames Schulman 	{ 0x1F,  2822400 },
163*0d463d01SJames Schulman 	{ 0x21,  3072000 },
164*0d463d01SJames Schulman 	{ 0x23,  4233600 },
165*0d463d01SJames Schulman 	{ 0x24,  4096000 },
166*0d463d01SJames Schulman 	{ 0x25,  4608000 },
167*0d463d01SJames Schulman 	{ 0x26,  5644800 },
168*0d463d01SJames Schulman 	{ 0x27,  6000000 },
169*0d463d01SJames Schulman 	{ 0x28,  6144000 },
170*0d463d01SJames Schulman 	{ 0x29,  6350400 },
171*0d463d01SJames Schulman 	{ 0x2A,  6912000 },
172*0d463d01SJames Schulman 	{ 0x2D,  7526400 },
173*0d463d01SJames Schulman 	{ 0x2E,  8467200 },
174*0d463d01SJames Schulman 	{ 0x2F,  8192000 },
175*0d463d01SJames Schulman 	{ 0x30,  9216000 },
176*0d463d01SJames Schulman 	{ 0x31, 11289600 },
177*0d463d01SJames Schulman 	{ 0x33, 12288000 },
178*0d463d01SJames Schulman 	{ 0x37, 16934400 },
179*0d463d01SJames Schulman 	{ 0x38, 18432000 },
180*0d463d01SJames Schulman 	{ 0x39, 22579200 },
181*0d463d01SJames Schulman 	{ 0x3B, 24576000 },
182*0d463d01SJames Schulman };
183*0d463d01SJames Schulman 
184*0d463d01SJames Schulman unsigned int cs35l45_get_clk_freq_id(unsigned int freq)
185*0d463d01SJames Schulman {
186*0d463d01SJames Schulman 	int i;
187*0d463d01SJames Schulman 
188*0d463d01SJames Schulman 	if (freq == 0)
189*0d463d01SJames Schulman 		return -EINVAL;
190*0d463d01SJames Schulman 
191*0d463d01SJames Schulman 	for (i = 0; i < ARRAY_SIZE(cs35l45_pll_refclk_freq); ++i) {
192*0d463d01SJames Schulman 		if (cs35l45_pll_refclk_freq[i].freq == freq)
193*0d463d01SJames Schulman 			return cs35l45_pll_refclk_freq[i].cfg_id;
194*0d463d01SJames Schulman 	}
195*0d463d01SJames Schulman 
196*0d463d01SJames Schulman 	return -EINVAL;
197*0d463d01SJames Schulman }
198*0d463d01SJames Schulman EXPORT_SYMBOL_GPL(cs35l45_get_clk_freq_id);
199*0d463d01SJames Schulman 
200*0d463d01SJames Schulman MODULE_DESCRIPTION("ASoC CS35L45 driver tables");
201*0d463d01SJames Schulman MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>");
202*0d463d01SJames Schulman MODULE_LICENSE("Dual BSD/GPL");
203