1 /* 2 * Helper routines for R-Car sound ADG. 3 * 4 * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 #include <linux/sh_clk.h> 11 #include "rsnd.h" 12 13 #define CLKA 0 14 #define CLKB 1 15 #define CLKC 2 16 #define CLKI 3 17 #define CLKMAX 4 18 19 struct rsnd_adg { 20 struct clk *clk[CLKMAX]; 21 22 int rbga_rate_for_441khz_div_6; /* RBGA */ 23 int rbgb_rate_for_48khz_div_6; /* RBGB */ 24 u32 ckr; 25 }; 26 27 #define for_each_rsnd_clk(pos, adg, i) \ 28 for (i = 0, (pos) = adg->clk[i]; \ 29 i < CLKMAX; \ 30 i++, (pos) = adg->clk[i]) 31 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 32 33 static int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 34 struct rsnd_mod *mod, 35 unsigned int src_rate, 36 unsigned int dst_rate) 37 { 38 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 39 struct device *dev = rsnd_priv_to_dev(priv); 40 int idx, sel, div, shift; 41 u32 mask, val; 42 int id = rsnd_mod_id(mod); 43 unsigned int sel_rate [] = { 44 clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */ 45 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ 46 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ 47 0, /* 011: MLBCLK (not used) */ 48 adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */ 49 adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */ 50 }; 51 52 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ 53 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) { 54 for (div = 128, idx = 0; 55 div <= 2048; 56 div *= 2, idx++) { 57 if (src_rate == sel_rate[sel] / div) { 58 val = (idx << 4) | sel; 59 goto find_rate; 60 } 61 } 62 } 63 dev_err(dev, "can't find convert src clk\n"); 64 return -EINVAL; 65 66 find_rate: 67 shift = (id % 4) * 8; 68 mask = 0xFF << shift; 69 val = val << shift; 70 71 dev_dbg(dev, "adg convert src clk = %02x\n", val); 72 73 switch (id / 4) { 74 case 0: 75 rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val); 76 break; 77 case 1: 78 rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val); 79 break; 80 case 2: 81 rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val); 82 break; 83 } 84 85 /* 86 * Gen1 doesn't need dst_rate settings, 87 * since it uses SSI WS pin. 88 * see also rsnd_src_set_route_if_gen1() 89 */ 90 91 return 0; 92 } 93 94 int rsnd_adg_set_convert_clk(struct rsnd_priv *priv, 95 struct rsnd_mod *mod, 96 unsigned int src_rate, 97 unsigned int dst_rate) 98 { 99 if (rsnd_is_gen1(priv)) 100 return rsnd_adg_set_convert_clk_gen1(priv, mod, 101 src_rate, dst_rate); 102 103 return -EINVAL; 104 } 105 106 static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) 107 { 108 int id = rsnd_mod_id(mod); 109 int shift = (id % 4) * 8; 110 u32 mask = 0xFF << shift; 111 112 val = val << shift; 113 114 /* 115 * SSI 8 is not connected to ADG. 116 * it works with SSI 7 117 */ 118 if (id == 8) 119 return; 120 121 switch (id / 4) { 122 case 0: 123 rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val); 124 break; 125 case 1: 126 rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val); 127 break; 128 case 2: 129 rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val); 130 break; 131 } 132 } 133 134 int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) 135 { 136 /* 137 * "mod" = "ssi" here. 138 * we can get "ssi id" from mod 139 */ 140 rsnd_adg_set_ssi_clk(mod, 0); 141 142 return 0; 143 } 144 145 int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) 146 { 147 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 148 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 149 struct device *dev = rsnd_priv_to_dev(priv); 150 struct clk *clk; 151 int i; 152 u32 data; 153 int sel_table[] = { 154 [CLKA] = 0x1, 155 [CLKB] = 0x2, 156 [CLKC] = 0x3, 157 [CLKI] = 0x0, 158 }; 159 160 dev_dbg(dev, "request clock = %d\n", rate); 161 162 /* 163 * find suitable clock from 164 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI. 165 */ 166 data = 0; 167 for_each_rsnd_clk(clk, adg, i) { 168 if (rate == clk_get_rate(clk)) { 169 data = sel_table[i]; 170 goto found_clock; 171 } 172 } 173 174 /* 175 * find 1/6 clock from BRGA/BRGB 176 */ 177 if (rate == adg->rbga_rate_for_441khz_div_6) { 178 data = 0x10; 179 goto found_clock; 180 } 181 182 if (rate == adg->rbgb_rate_for_48khz_div_6) { 183 data = 0x20; 184 goto found_clock; 185 } 186 187 return -EIO; 188 189 found_clock: 190 191 /* see rsnd_adg_ssi_clk_init() */ 192 rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr); 193 rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */ 194 rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */ 195 196 /* 197 * This "mod" = "ssi" here. 198 * we can get "ssi id" from mod 199 */ 200 rsnd_adg_set_ssi_clk(mod, data); 201 202 dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", 203 rsnd_mod_id(mod), i, rate); 204 205 return 0; 206 } 207 208 static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) 209 { 210 struct clk *clk; 211 unsigned long rate; 212 u32 ckr; 213 int i; 214 int brg_table[] = { 215 [CLKA] = 0x0, 216 [CLKB] = 0x1, 217 [CLKC] = 0x4, 218 [CLKI] = 0x2, 219 }; 220 221 /* 222 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC 223 * have 44.1kHz or 48kHz base clocks for now. 224 * 225 * SSI itself can divide parent clock by 1/1 - 1/16 226 * So, BRGA outputs 44.1kHz base parent clock 1/32, 227 * and, BRGB outputs 48.0kHz base parent clock 1/32 here. 228 * see 229 * rsnd_adg_ssi_clk_try_start() 230 */ 231 ckr = 0; 232 adg->rbga_rate_for_441khz_div_6 = 0; 233 adg->rbgb_rate_for_48khz_div_6 = 0; 234 for_each_rsnd_clk(clk, adg, i) { 235 rate = clk_get_rate(clk); 236 237 if (0 == rate) /* not used */ 238 continue; 239 240 /* RBGA */ 241 if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) { 242 adg->rbga_rate_for_441khz_div_6 = rate / 6; 243 ckr |= brg_table[i] << 20; 244 } 245 246 /* RBGB */ 247 if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) { 248 adg->rbgb_rate_for_48khz_div_6 = rate / 6; 249 ckr |= brg_table[i] << 16; 250 } 251 } 252 253 adg->ckr = ckr; 254 } 255 256 int rsnd_adg_probe(struct platform_device *pdev, 257 struct rcar_snd_info *info, 258 struct rsnd_priv *priv) 259 { 260 struct rsnd_adg *adg; 261 struct device *dev = rsnd_priv_to_dev(priv); 262 struct clk *clk; 263 int i; 264 265 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 266 if (!adg) { 267 dev_err(dev, "ADG allocate failed\n"); 268 return -ENOMEM; 269 } 270 271 adg->clk[CLKA] = clk_get(NULL, "audio_clk_a"); 272 adg->clk[CLKB] = clk_get(NULL, "audio_clk_b"); 273 adg->clk[CLKC] = clk_get(NULL, "audio_clk_c"); 274 adg->clk[CLKI] = clk_get(NULL, "audio_clk_internal"); 275 for_each_rsnd_clk(clk, adg, i) { 276 if (IS_ERR(clk)) { 277 dev_err(dev, "Audio clock failed\n"); 278 return -EIO; 279 } 280 } 281 282 rsnd_adg_ssi_clk_init(priv, adg); 283 284 priv->adg = adg; 285 286 dev_dbg(dev, "adg probed\n"); 287 288 return 0; 289 } 290 291 void rsnd_adg_remove(struct platform_device *pdev, 292 struct rsnd_priv *priv) 293 { 294 struct rsnd_adg *adg = priv->adg; 295 struct clk *clk; 296 int i; 297 298 for_each_rsnd_clk(clk, adg, i) 299 clk_put(clk); 300 } 301