@@ -129,8 +129,6 @@ struct sun4i_i2s;
129
129
* @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
130
130
* @reg_offset_txdata: offset of the tx fifo.
131
131
* @sun4i_i2s_regmap: regmap config to use.
132
- * @mclk_offset: Value by which mclkdiv needs to be adjusted.
133
- * @bclk_offset: Value by which bclkdiv needs to be adjusted.
134
132
* @field_clkdiv_mclk_en: regmap field to enable mclk output.
135
133
* @field_fmt_wss: regmap field to set word select size.
136
134
* @field_fmt_sr: regmap field to set sample resolution.
@@ -142,8 +140,6 @@ struct sun4i_i2s_quirks {
142
140
bool has_fmt_set_lrck_period ;
143
141
unsigned int reg_offset_txdata ; /* TX FIFO */
144
142
const struct regmap_config * sun4i_i2s_regmap ;
145
- unsigned int mclk_offset ;
146
- unsigned int bclk_offset ;
147
143
148
144
/* Register fields for i2s */
149
145
struct reg_field field_clkdiv_mclk_en ;
@@ -152,6 +148,11 @@ struct sun4i_i2s_quirks {
152
148
struct reg_field field_fmt_bclk ;
153
149
struct reg_field field_fmt_lrclk ;
154
150
151
+ const struct sun4i_i2s_clk_div * bclk_dividers ;
152
+ unsigned int num_bclk_dividers ;
153
+ const struct sun4i_i2s_clk_div * mclk_dividers ;
154
+ unsigned int num_mclk_dividers ;
155
+
155
156
unsigned long (* get_bclk_parent_rate )(const struct sun4i_i2s * );
156
157
s8 (* get_sr )(const struct sun4i_i2s * , int );
157
158
s8 (* get_wss )(const struct sun4i_i2s * , int );
@@ -208,6 +209,24 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
208
209
/* TODO - extend divide ratio supported by newer SoCs */
209
210
};
210
211
212
+ static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div [] = {
213
+ { .div = 1 , .val = 1 },
214
+ { .div = 2 , .val = 2 },
215
+ { .div = 4 , .val = 3 },
216
+ { .div = 6 , .val = 4 },
217
+ { .div = 8 , .val = 5 },
218
+ { .div = 12 , .val = 6 },
219
+ { .div = 16 , .val = 7 },
220
+ { .div = 24 , .val = 8 },
221
+ { .div = 32 , .val = 9 },
222
+ { .div = 48 , .val = 10 },
223
+ { .div = 64 , .val = 11 },
224
+ { .div = 96 , .val = 12 },
225
+ { .div = 128 , .val = 13 },
226
+ { .div = 176 , .val = 14 },
227
+ { .div = 192 , .val = 15 },
228
+ };
229
+
211
230
static unsigned long sun4i_i2s_get_bclk_parent_rate (const struct sun4i_i2s * i2s )
212
231
{
213
232
return i2s -> mclk_freq ;
@@ -223,11 +242,12 @@ static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
223
242
unsigned int sampling_rate ,
224
243
unsigned int word_size )
225
244
{
245
+ const struct sun4i_i2s_clk_div * dividers = i2s -> variant -> bclk_dividers ;
226
246
int div = parent_rate / sampling_rate / word_size / 2 ;
227
247
int i ;
228
248
229
- for (i = 0 ; i < ARRAY_SIZE ( sun4i_i2s_bclk_div ) ; i ++ ) {
230
- const struct sun4i_i2s_clk_div * bdiv = & sun4i_i2s_bclk_div [i ];
249
+ for (i = 0 ; i < i2s -> variant -> num_bclk_dividers ; i ++ ) {
250
+ const struct sun4i_i2s_clk_div * bdiv = & dividers [i ];
231
251
232
252
if (bdiv -> div == div )
233
253
return bdiv -> val ;
@@ -240,11 +260,12 @@ static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
240
260
unsigned long parent_rate ,
241
261
unsigned long mclk_rate )
242
262
{
263
+ const struct sun4i_i2s_clk_div * dividers = i2s -> variant -> mclk_dividers ;
243
264
int div = parent_rate / mclk_rate ;
244
265
int i ;
245
266
246
- for (i = 0 ; i < ARRAY_SIZE ( sun4i_i2s_mclk_div ) ; i ++ ) {
247
- const struct sun4i_i2s_clk_div * mdiv = & sun4i_i2s_mclk_div [i ];
267
+ for (i = 0 ; i < i2s -> variant -> num_mclk_dividers ; i ++ ) {
268
+ const struct sun4i_i2s_clk_div * mdiv = & dividers [i ];
248
269
249
270
if (mdiv -> div == div )
250
271
return mdiv -> val ;
@@ -326,10 +347,6 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
326
347
return - EINVAL ;
327
348
}
328
349
329
- /* Adjust the clock division values if needed */
330
- bclk_div += i2s -> variant -> bclk_offset ;
331
- mclk_div += i2s -> variant -> mclk_offset ;
332
-
333
350
regmap_write (i2s -> regmap , SUN4I_I2S_CLK_DIV_REG ,
334
351
SUN4I_I2S_CLK_DIV_BCLK (bclk_div ) |
335
352
SUN4I_I2S_CLK_DIV_MCLK (mclk_div ));
@@ -969,6 +986,10 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
969
986
.field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 5 ),
970
987
.field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 6 , 6 ),
971
988
.field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
989
+ .bclk_dividers = sun4i_i2s_bclk_div ,
990
+ .num_bclk_dividers = ARRAY_SIZE (sun4i_i2s_bclk_div ),
991
+ .mclk_dividers = sun4i_i2s_mclk_div ,
992
+ .num_mclk_dividers = ARRAY_SIZE (sun4i_i2s_mclk_div ),
972
993
.get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate ,
973
994
.get_sr = sun4i_i2s_get_sr ,
974
995
.get_wss = sun4i_i2s_get_wss ,
@@ -985,6 +1006,10 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
985
1006
.field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 5 ),
986
1007
.field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 6 , 6 ),
987
1008
.field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
1009
+ .bclk_dividers = sun4i_i2s_bclk_div ,
1010
+ .num_bclk_dividers = ARRAY_SIZE (sun4i_i2s_bclk_div ),
1011
+ .mclk_dividers = sun4i_i2s_mclk_div ,
1012
+ .num_mclk_dividers = ARRAY_SIZE (sun4i_i2s_mclk_div ),
988
1013
.get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate ,
989
1014
.get_sr = sun4i_i2s_get_sr ,
990
1015
.get_wss = sun4i_i2s_get_wss ,
@@ -1001,6 +1026,10 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1001
1026
.field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 5 ),
1002
1027
.field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 6 , 6 ),
1003
1028
.field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
1029
+ .bclk_dividers = sun8i_i2s_clk_div ,
1030
+ .num_bclk_dividers = ARRAY_SIZE (sun8i_i2s_clk_div ),
1031
+ .mclk_dividers = sun8i_i2s_clk_div ,
1032
+ .num_mclk_dividers = ARRAY_SIZE (sun8i_i2s_clk_div ),
1004
1033
.get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate ,
1005
1034
.get_sr = sun8i_i2s_get_sr_wss ,
1006
1035
.get_wss = sun8i_i2s_get_sr_wss ,
@@ -1012,14 +1041,16 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1012
1041
.has_reset = true,
1013
1042
.reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
1014
1043
.sun4i_i2s_regmap = & sun8i_i2s_regmap_config ,
1015
- .mclk_offset = 1 ,
1016
- .bclk_offset = 2 ,
1017
1044
.has_fmt_set_lrck_period = true,
1018
1045
.field_clkdiv_mclk_en = REG_FIELD (SUN4I_I2S_CLK_DIV_REG , 8 , 8 ),
1019
1046
.field_fmt_wss = REG_FIELD (SUN4I_I2S_FMT0_REG , 0 , 2 ),
1020
1047
.field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 6 ),
1021
1048
.field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
1022
1049
.field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 19 , 19 ),
1050
+ .bclk_dividers = sun8i_i2s_clk_div ,
1051
+ .num_bclk_dividers = ARRAY_SIZE (sun8i_i2s_clk_div ),
1052
+ .mclk_dividers = sun8i_i2s_clk_div ,
1053
+ .num_mclk_dividers = ARRAY_SIZE (sun8i_i2s_clk_div ),
1023
1054
.get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate ,
1024
1055
.get_sr = sun8i_i2s_get_sr_wss ,
1025
1056
.get_wss = sun8i_i2s_get_sr_wss ,
@@ -1036,6 +1067,10 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1036
1067
.field_fmt_sr = REG_FIELD (SUN4I_I2S_FMT0_REG , 4 , 5 ),
1037
1068
.field_fmt_bclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 6 , 6 ),
1038
1069
.field_fmt_lrclk = REG_FIELD (SUN4I_I2S_FMT0_REG , 7 , 7 ),
1070
+ .bclk_dividers = sun4i_i2s_bclk_div ,
1071
+ .num_bclk_dividers = ARRAY_SIZE (sun4i_i2s_bclk_div ),
1072
+ .mclk_dividers = sun4i_i2s_mclk_div ,
1073
+ .num_mclk_dividers = ARRAY_SIZE (sun4i_i2s_mclk_div ),
1039
1074
.get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate ,
1040
1075
.get_sr = sun4i_i2s_get_sr ,
1041
1076
.get_wss = sun4i_i2s_get_wss ,
0 commit comments