0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk-provider.h>
0011 #include <linux/clkdev.h>
0012 #include <linux/regmap.h>
0013 #include <linux/device.h>
0014
0015 #include "tlv320aic32x4.h"
0016
0017 #define to_clk_aic32x4(_hw) container_of(_hw, struct clk_aic32x4, hw)
0018 struct clk_aic32x4 {
0019 struct clk_hw hw;
0020 struct device *dev;
0021 struct regmap *regmap;
0022 unsigned int reg;
0023 };
0024
0025
0026
0027
0028
0029
0030
0031
0032 struct clk_aic32x4_pll_muldiv {
0033 u8 p;
0034 u16 r;
0035 u8 j;
0036 u16 d;
0037 };
0038
0039 struct aic32x4_clkdesc {
0040 const char *name;
0041 const char * const *parent_names;
0042 unsigned int num_parents;
0043 const struct clk_ops *ops;
0044 unsigned int reg;
0045 };
0046
0047 static int clk_aic32x4_pll_prepare(struct clk_hw *hw)
0048 {
0049 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0050
0051 return regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0052 AIC32X4_PLLEN, AIC32X4_PLLEN);
0053 }
0054
0055 static void clk_aic32x4_pll_unprepare(struct clk_hw *hw)
0056 {
0057 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0058
0059 regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0060 AIC32X4_PLLEN, 0);
0061 }
0062
0063 static int clk_aic32x4_pll_is_prepared(struct clk_hw *hw)
0064 {
0065 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0066
0067 unsigned int val;
0068 int ret;
0069
0070 ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0071 if (ret < 0)
0072 return ret;
0073
0074 return !!(val & AIC32X4_PLLEN);
0075 }
0076
0077 static int clk_aic32x4_pll_get_muldiv(struct clk_aic32x4 *pll,
0078 struct clk_aic32x4_pll_muldiv *settings)
0079 {
0080
0081 unsigned int val;
0082 int ret;
0083
0084 ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0085 if (ret < 0)
0086 return ret;
0087 settings->r = val & AIC32X4_PLL_R_MASK;
0088 settings->p = (val & AIC32X4_PLL_P_MASK) >> AIC32X4_PLL_P_SHIFT;
0089
0090 ret = regmap_read(pll->regmap, AIC32X4_PLLJ, &val);
0091 if (ret < 0)
0092 return ret;
0093 settings->j = val;
0094
0095 ret = regmap_read(pll->regmap, AIC32X4_PLLDMSB, &val);
0096 if (ret < 0)
0097 return ret;
0098 settings->d = val << 8;
0099
0100 ret = regmap_read(pll->regmap, AIC32X4_PLLDLSB, &val);
0101 if (ret < 0)
0102 return ret;
0103 settings->d |= val;
0104
0105 return 0;
0106 }
0107
0108 static int clk_aic32x4_pll_set_muldiv(struct clk_aic32x4 *pll,
0109 struct clk_aic32x4_pll_muldiv *settings)
0110 {
0111 int ret;
0112
0113
0114 ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0115 AIC32X4_PLL_R_MASK, settings->r);
0116 if (ret < 0)
0117 return ret;
0118
0119 ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0120 AIC32X4_PLL_P_MASK,
0121 settings->p << AIC32X4_PLL_P_SHIFT);
0122 if (ret < 0)
0123 return ret;
0124
0125 ret = regmap_write(pll->regmap, AIC32X4_PLLJ, settings->j);
0126 if (ret < 0)
0127 return ret;
0128
0129 ret = regmap_write(pll->regmap, AIC32X4_PLLDMSB, (settings->d >> 8));
0130 if (ret < 0)
0131 return ret;
0132 ret = regmap_write(pll->regmap, AIC32X4_PLLDLSB, (settings->d & 0xff));
0133 if (ret < 0)
0134 return ret;
0135
0136 return 0;
0137 }
0138
0139 static unsigned long clk_aic32x4_pll_calc_rate(
0140 struct clk_aic32x4_pll_muldiv *settings,
0141 unsigned long parent_rate)
0142 {
0143 u64 rate;
0144
0145
0146
0147
0148 rate = (u64) parent_rate * settings->r *
0149 ((settings->j * 10000) + settings->d);
0150
0151 return (unsigned long) DIV_ROUND_UP_ULL(rate, settings->p * 10000);
0152 }
0153
0154 static int clk_aic32x4_pll_calc_muldiv(struct clk_aic32x4_pll_muldiv *settings,
0155 unsigned long rate, unsigned long parent_rate)
0156 {
0157 u64 multiplier;
0158
0159 settings->p = parent_rate / AIC32X4_MAX_PLL_CLKIN + 1;
0160 if (settings->p > 8)
0161 return -1;
0162
0163
0164
0165
0166
0167
0168 multiplier = (u64) rate * settings->p * 10000;
0169 do_div(multiplier, parent_rate);
0170
0171
0172
0173
0174
0175 settings->r = ((u32) multiplier / 640000) + 1;
0176 if (settings->r > 4)
0177 return -1;
0178 do_div(multiplier, settings->r);
0179
0180
0181
0182
0183 if (multiplier < 10000)
0184 return -1;
0185
0186
0187 settings->j = (u32) multiplier / 10000;
0188 settings->d = (u32) multiplier % 10000;
0189
0190 return 0;
0191 }
0192
0193 static unsigned long clk_aic32x4_pll_recalc_rate(struct clk_hw *hw,
0194 unsigned long parent_rate)
0195 {
0196 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0197 struct clk_aic32x4_pll_muldiv settings;
0198 int ret;
0199
0200 ret = clk_aic32x4_pll_get_muldiv(pll, &settings);
0201 if (ret < 0)
0202 return 0;
0203
0204 return clk_aic32x4_pll_calc_rate(&settings, parent_rate);
0205 }
0206
0207 static long clk_aic32x4_pll_round_rate(struct clk_hw *hw,
0208 unsigned long rate,
0209 unsigned long *parent_rate)
0210 {
0211 struct clk_aic32x4_pll_muldiv settings;
0212 int ret;
0213
0214 ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate);
0215 if (ret < 0)
0216 return 0;
0217
0218 return clk_aic32x4_pll_calc_rate(&settings, *parent_rate);
0219 }
0220
0221 static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
0222 unsigned long rate,
0223 unsigned long parent_rate)
0224 {
0225 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0226 struct clk_aic32x4_pll_muldiv settings;
0227 int ret;
0228
0229 ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, parent_rate);
0230 if (ret < 0)
0231 return -EINVAL;
0232
0233 ret = clk_aic32x4_pll_set_muldiv(pll, &settings);
0234 if (ret)
0235 return ret;
0236
0237
0238 msleep(10);
0239
0240 return 0;
0241 }
0242
0243 static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index)
0244 {
0245 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0246
0247 return regmap_update_bits(pll->regmap,
0248 AIC32X4_CLKMUX,
0249 AIC32X4_PLL_CLKIN_MASK,
0250 index << AIC32X4_PLL_CLKIN_SHIFT);
0251 }
0252
0253 static u8 clk_aic32x4_pll_get_parent(struct clk_hw *hw)
0254 {
0255 struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0256 unsigned int val;
0257
0258 regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0259
0260 return (val & AIC32X4_PLL_CLKIN_MASK) >> AIC32X4_PLL_CLKIN_SHIFT;
0261 }
0262
0263
0264 static const struct clk_ops aic32x4_pll_ops = {
0265 .prepare = clk_aic32x4_pll_prepare,
0266 .unprepare = clk_aic32x4_pll_unprepare,
0267 .is_prepared = clk_aic32x4_pll_is_prepared,
0268 .recalc_rate = clk_aic32x4_pll_recalc_rate,
0269 .round_rate = clk_aic32x4_pll_round_rate,
0270 .set_rate = clk_aic32x4_pll_set_rate,
0271 .set_parent = clk_aic32x4_pll_set_parent,
0272 .get_parent = clk_aic32x4_pll_get_parent,
0273 };
0274
0275 static int clk_aic32x4_codec_clkin_set_parent(struct clk_hw *hw, u8 index)
0276 {
0277 struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0278
0279 return regmap_update_bits(mux->regmap,
0280 AIC32X4_CLKMUX,
0281 AIC32X4_CODEC_CLKIN_MASK, index << AIC32X4_CODEC_CLKIN_SHIFT);
0282 }
0283
0284 static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw)
0285 {
0286 struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0287 unsigned int val;
0288
0289 regmap_read(mux->regmap, AIC32X4_CLKMUX, &val);
0290
0291 return (val & AIC32X4_CODEC_CLKIN_MASK) >> AIC32X4_CODEC_CLKIN_SHIFT;
0292 }
0293
0294 static const struct clk_ops aic32x4_codec_clkin_ops = {
0295 .set_parent = clk_aic32x4_codec_clkin_set_parent,
0296 .get_parent = clk_aic32x4_codec_clkin_get_parent,
0297 };
0298
0299 static int clk_aic32x4_div_prepare(struct clk_hw *hw)
0300 {
0301 struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0302
0303 return regmap_update_bits(div->regmap, div->reg,
0304 AIC32X4_DIVEN, AIC32X4_DIVEN);
0305 }
0306
0307 static void clk_aic32x4_div_unprepare(struct clk_hw *hw)
0308 {
0309 struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0310
0311 regmap_update_bits(div->regmap, div->reg,
0312 AIC32X4_DIVEN, 0);
0313 }
0314
0315 static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate,
0316 unsigned long parent_rate)
0317 {
0318 struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0319 u8 divisor;
0320
0321 divisor = DIV_ROUND_UP(parent_rate, rate);
0322 if (divisor > 128)
0323 return -EINVAL;
0324
0325 return regmap_update_bits(div->regmap, div->reg,
0326 AIC32X4_DIV_MASK, divisor);
0327 }
0328
0329 static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate,
0330 unsigned long *parent_rate)
0331 {
0332 unsigned long divisor;
0333
0334 divisor = DIV_ROUND_UP(*parent_rate, rate);
0335 if (divisor > 128)
0336 return -EINVAL;
0337
0338 return DIV_ROUND_UP(*parent_rate, divisor);
0339 }
0340
0341 static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
0342 unsigned long parent_rate)
0343 {
0344 struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0345
0346 unsigned int val;
0347
0348 regmap_read(div->regmap, div->reg, &val);
0349
0350 return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK);
0351 }
0352
0353 static const struct clk_ops aic32x4_div_ops = {
0354 .prepare = clk_aic32x4_div_prepare,
0355 .unprepare = clk_aic32x4_div_unprepare,
0356 .set_rate = clk_aic32x4_div_set_rate,
0357 .round_rate = clk_aic32x4_div_round_rate,
0358 .recalc_rate = clk_aic32x4_div_recalc_rate,
0359 };
0360
0361 static int clk_aic32x4_bdiv_set_parent(struct clk_hw *hw, u8 index)
0362 {
0363 struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0364
0365 return regmap_update_bits(mux->regmap, AIC32X4_IFACE3,
0366 AIC32X4_BDIVCLK_MASK, index);
0367 }
0368
0369 static u8 clk_aic32x4_bdiv_get_parent(struct clk_hw *hw)
0370 {
0371 struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0372 unsigned int val;
0373
0374 regmap_read(mux->regmap, AIC32X4_IFACE3, &val);
0375
0376 return val & AIC32X4_BDIVCLK_MASK;
0377 }
0378
0379 static const struct clk_ops aic32x4_bdiv_ops = {
0380 .prepare = clk_aic32x4_div_prepare,
0381 .unprepare = clk_aic32x4_div_unprepare,
0382 .set_parent = clk_aic32x4_bdiv_set_parent,
0383 .get_parent = clk_aic32x4_bdiv_get_parent,
0384 .set_rate = clk_aic32x4_div_set_rate,
0385 .round_rate = clk_aic32x4_div_round_rate,
0386 .recalc_rate = clk_aic32x4_div_recalc_rate,
0387 };
0388
0389 static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = {
0390 {
0391 .name = "pll",
0392 .parent_names =
0393 (const char* []) { "mclk", "bclk", "gpio", "din" },
0394 .num_parents = 4,
0395 .ops = &aic32x4_pll_ops,
0396 .reg = 0,
0397 },
0398 {
0399 .name = "codec_clkin",
0400 .parent_names =
0401 (const char *[]) { "mclk", "bclk", "gpio", "pll" },
0402 .num_parents = 4,
0403 .ops = &aic32x4_codec_clkin_ops,
0404 .reg = 0,
0405 },
0406 {
0407 .name = "ndac",
0408 .parent_names = (const char * []) { "codec_clkin" },
0409 .num_parents = 1,
0410 .ops = &aic32x4_div_ops,
0411 .reg = AIC32X4_NDAC,
0412 },
0413 {
0414 .name = "mdac",
0415 .parent_names = (const char * []) { "ndac" },
0416 .num_parents = 1,
0417 .ops = &aic32x4_div_ops,
0418 .reg = AIC32X4_MDAC,
0419 },
0420 {
0421 .name = "nadc",
0422 .parent_names = (const char * []) { "codec_clkin" },
0423 .num_parents = 1,
0424 .ops = &aic32x4_div_ops,
0425 .reg = AIC32X4_NADC,
0426 },
0427 {
0428 .name = "madc",
0429 .parent_names = (const char * []) { "nadc" },
0430 .num_parents = 1,
0431 .ops = &aic32x4_div_ops,
0432 .reg = AIC32X4_MADC,
0433 },
0434 {
0435 .name = "bdiv",
0436 .parent_names =
0437 (const char *[]) { "ndac", "mdac", "nadc", "madc" },
0438 .num_parents = 4,
0439 .ops = &aic32x4_bdiv_ops,
0440 .reg = AIC32X4_BCLKN,
0441 },
0442 };
0443
0444 static struct clk *aic32x4_register_clk(struct device *dev,
0445 struct aic32x4_clkdesc *desc)
0446 {
0447 struct clk_init_data init;
0448 struct clk_aic32x4 *priv;
0449 const char *devname = dev_name(dev);
0450
0451 init.ops = desc->ops;
0452 init.name = desc->name;
0453 init.parent_names = desc->parent_names;
0454 init.num_parents = desc->num_parents;
0455 init.flags = 0;
0456
0457 priv = devm_kzalloc(dev, sizeof(struct clk_aic32x4), GFP_KERNEL);
0458 if (priv == NULL)
0459 return (struct clk *) -ENOMEM;
0460
0461 priv->dev = dev;
0462 priv->hw.init = &init;
0463 priv->regmap = dev_get_regmap(dev, NULL);
0464 priv->reg = desc->reg;
0465
0466 clk_hw_register_clkdev(&priv->hw, desc->name, devname);
0467 return devm_clk_register(dev, &priv->hw);
0468 }
0469
0470 int aic32x4_register_clocks(struct device *dev, const char *mclk_name)
0471 {
0472 int i;
0473
0474
0475
0476
0477
0478
0479
0480 aic32x4_clkdesc_array[0].parent_names =
0481 (const char* []) { mclk_name, "bclk", "gpio", "din" };
0482 aic32x4_clkdesc_array[1].parent_names =
0483 (const char *[]) { mclk_name, "bclk", "gpio", "pll" };
0484
0485 for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i)
0486 aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]);
0487
0488 return 0;
0489 }
0490 EXPORT_SYMBOL_GPL(aic32x4_register_clocks);