1 /* 2 * Renesas R-Car DVC support 3 * 4 * Copyright (C) 2014 Renesas Solutions Corp. 5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 #include "rsnd.h" 12 13 #define RSND_DVC_NAME_SIZE 16 14 15 #define DVC_NAME "dvc" 16 17 struct rsnd_dvc { 18 struct rsnd_mod mod; 19 struct rsnd_kctrl_cfg_m volume; 20 struct rsnd_kctrl_cfg_m mute; 21 struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ 22 struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */ 23 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 24 }; 25 26 #define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id) 27 #define rsnd_dvc_nr(priv) ((priv)->dvc_nr) 28 #define rsnd_dvc_of_node(priv) \ 29 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") 30 31 #define rsnd_mod_to_dvc(_mod) \ 32 container_of((_mod), struct rsnd_dvc, mod) 33 34 #define for_each_rsnd_dvc(pos, priv, i) \ 35 for ((i) = 0; \ 36 ((i) < rsnd_dvc_nr(priv)) && \ 37 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ 38 i++) 39 40 static const char * const dvc_ramp_rate[] = { 41 "128 dB/1 step", /* 00000 */ 42 "64 dB/1 step", /* 00001 */ 43 "32 dB/1 step", /* 00010 */ 44 "16 dB/1 step", /* 00011 */ 45 "8 dB/1 step", /* 00100 */ 46 "4 dB/1 step", /* 00101 */ 47 "2 dB/1 step", /* 00110 */ 48 "1 dB/1 step", /* 00111 */ 49 "0.5 dB/1 step", /* 01000 */ 50 "0.25 dB/1 step", /* 01001 */ 51 "0.125 dB/1 step", /* 01010 */ 52 "0.125 dB/2 steps", /* 01011 */ 53 "0.125 dB/4 steps", /* 01100 */ 54 "0.125 dB/8 steps", /* 01101 */ 55 "0.125 dB/16 steps", /* 01110 */ 56 "0.125 dB/32 steps", /* 01111 */ 57 "0.125 dB/64 steps", /* 10000 */ 58 "0.125 dB/128 steps", /* 10001 */ 59 "0.125 dB/256 steps", /* 10010 */ 60 "0.125 dB/512 steps", /* 10011 */ 61 "0.125 dB/1024 steps", /* 10100 */ 62 "0.125 dB/2048 steps", /* 10101 */ 63 "0.125 dB/4096 steps", /* 10110 */ 64 "0.125 dB/8192 steps", /* 10111 */ 65 }; 66 67 static void rsnd_dvc_activation(struct rsnd_mod *mod) 68 { 69 rsnd_mod_write(mod, DVC_SWRSR, 0); 70 rsnd_mod_write(mod, DVC_SWRSR, 1); 71 } 72 73 static void rsnd_dvc_halt(struct rsnd_mod *mod) 74 { 75 rsnd_mod_write(mod, DVC_DVUIR, 1); 76 rsnd_mod_write(mod, DVC_SWRSR, 0); 77 } 78 79 #define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val) 80 #define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13)) 81 82 static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io, 83 struct rsnd_mod *mod) 84 { 85 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 86 u32 val[RSND_DVC_CHANNELS]; 87 int i; 88 89 /* Enable Ramp */ 90 if (dvc->ren.val) 91 for (i = 0; i < RSND_DVC_CHANNELS; i++) 92 val[i] = dvc->volume.cfg.max; 93 else 94 for (i = 0; i < RSND_DVC_CHANNELS; i++) 95 val[i] = dvc->volume.val[i]; 96 97 /* Enable Digital Volume */ 98 rsnd_mod_write(mod, DVC_VOL0R, val[0]); 99 rsnd_mod_write(mod, DVC_VOL1R, val[1]); 100 rsnd_mod_write(mod, DVC_VOL2R, val[2]); 101 rsnd_mod_write(mod, DVC_VOL3R, val[3]); 102 rsnd_mod_write(mod, DVC_VOL4R, val[4]); 103 rsnd_mod_write(mod, DVC_VOL5R, val[5]); 104 rsnd_mod_write(mod, DVC_VOL6R, val[6]); 105 rsnd_mod_write(mod, DVC_VOL7R, val[7]); 106 } 107 108 static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, 109 struct rsnd_mod *mod) 110 { 111 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 112 u32 adinr = 0; 113 u32 dvucr = 0; 114 u32 vrctr = 0; 115 u32 vrpdr = 0; 116 u32 vrdbr = 0; 117 118 adinr = rsnd_get_adinr_bit(mod, io) | 119 rsnd_get_adinr_chan(mod, io); 120 121 /* Enable Digital Volume, Zero Cross Mute Mode */ 122 dvucr |= 0x101; 123 124 /* Enable Ramp */ 125 if (dvc->ren.val) { 126 dvucr |= 0x10; 127 128 /* 129 * FIXME !! 130 * use scale-downed Digital Volume 131 * as Volume Ramp 132 * 7F FFFF -> 3FF 133 */ 134 vrctr = 0xff; 135 vrpdr = rsnd_dvc_get_vrpdr(dvc); 136 vrdbr = rsnd_dvc_get_vrdbr(dvc); 137 } 138 139 /* Initialize operation */ 140 rsnd_mod_write(mod, DVC_DVUIR, 1); 141 142 /* General Information */ 143 rsnd_mod_write(mod, DVC_ADINR, adinr); 144 rsnd_mod_write(mod, DVC_DVUCR, dvucr); 145 146 /* Volume Ramp Parameter */ 147 rsnd_mod_write(mod, DVC_VRCTR, vrctr); 148 rsnd_mod_write(mod, DVC_VRPDR, vrpdr); 149 rsnd_mod_write(mod, DVC_VRDBR, vrdbr); 150 151 /* Digital Volume Function Parameter */ 152 rsnd_dvc_volume_parameter(io, mod); 153 154 /* cancel operation */ 155 rsnd_mod_write(mod, DVC_DVUIR, 0); 156 } 157 158 static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, 159 struct rsnd_mod *mod) 160 { 161 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 162 u32 zcmcr = 0; 163 u32 vrpdr = 0; 164 u32 vrdbr = 0; 165 int i; 166 167 for (i = 0; i < dvc->mute.cfg.size; i++) 168 zcmcr |= (!!dvc->mute.cfg.val[i]) << i; 169 170 if (dvc->ren.val) { 171 vrpdr = rsnd_dvc_get_vrpdr(dvc); 172 vrdbr = rsnd_dvc_get_vrdbr(dvc); 173 } 174 175 /* Disable DVC Register access */ 176 rsnd_mod_write(mod, DVC_DVUER, 0); 177 178 /* Zero Cross Mute Function */ 179 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr); 180 181 /* Volume Ramp Function */ 182 rsnd_mod_write(mod, DVC_VRPDR, vrpdr); 183 rsnd_mod_write(mod, DVC_VRDBR, vrdbr); 184 /* add DVC_VRWTR here */ 185 186 /* Digital Volume Function Parameter */ 187 rsnd_dvc_volume_parameter(io, mod); 188 189 /* Enable DVC Register access */ 190 rsnd_mod_write(mod, DVC_DVUER, 1); 191 } 192 193 static int rsnd_dvc_probe_(struct rsnd_mod *mod, 194 struct rsnd_dai_stream *io, 195 struct rsnd_priv *priv) 196 { 197 return rsnd_cmd_attach(io, rsnd_mod_id(mod)); 198 } 199 200 static int rsnd_dvc_remove_(struct rsnd_mod *mod, 201 struct rsnd_dai_stream *io, 202 struct rsnd_priv *priv) 203 { 204 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 205 206 rsnd_kctrl_remove(dvc->volume); 207 rsnd_kctrl_remove(dvc->mute); 208 rsnd_kctrl_remove(dvc->ren); 209 rsnd_kctrl_remove(dvc->rup); 210 rsnd_kctrl_remove(dvc->rdown); 211 212 return 0; 213 } 214 215 static int rsnd_dvc_init(struct rsnd_mod *mod, 216 struct rsnd_dai_stream *io, 217 struct rsnd_priv *priv) 218 { 219 rsnd_mod_power_on(mod); 220 221 rsnd_dvc_activation(mod); 222 223 rsnd_dvc_volume_init(io, mod); 224 225 rsnd_dvc_volume_update(io, mod); 226 227 return 0; 228 } 229 230 static int rsnd_dvc_quit(struct rsnd_mod *mod, 231 struct rsnd_dai_stream *io, 232 struct rsnd_priv *priv) 233 { 234 rsnd_dvc_halt(mod); 235 236 rsnd_mod_power_off(mod); 237 238 return 0; 239 } 240 241 static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, 242 struct rsnd_dai_stream *io, 243 struct snd_soc_pcm_runtime *rtd) 244 { 245 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 246 int is_play = rsnd_io_is_play(io); 247 int slots = rsnd_get_slot(io); 248 int ret; 249 250 /* Volume */ 251 ret = rsnd_kctrl_new_m(mod, io, rtd, 252 is_play ? 253 "DVC Out Playback Volume" : "DVC In Capture Volume", 254 rsnd_dvc_volume_update, 255 &dvc->volume, slots, 256 0x00800000 - 1); 257 if (ret < 0) 258 return ret; 259 260 /* Mute */ 261 ret = rsnd_kctrl_new_m(mod, io, rtd, 262 is_play ? 263 "DVC Out Mute Switch" : "DVC In Mute Switch", 264 rsnd_dvc_volume_update, 265 &dvc->mute, slots, 266 1); 267 if (ret < 0) 268 return ret; 269 270 /* Ramp */ 271 ret = rsnd_kctrl_new_s(mod, io, rtd, 272 is_play ? 273 "DVC Out Ramp Switch" : "DVC In Ramp Switch", 274 rsnd_dvc_volume_update, 275 &dvc->ren, 1); 276 if (ret < 0) 277 return ret; 278 279 ret = rsnd_kctrl_new_e(mod, io, rtd, 280 is_play ? 281 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", 282 &dvc->rup, 283 rsnd_dvc_volume_update, 284 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 285 if (ret < 0) 286 return ret; 287 288 ret = rsnd_kctrl_new_e(mod, io, rtd, 289 is_play ? 290 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", 291 &dvc->rdown, 292 rsnd_dvc_volume_update, 293 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 294 295 if (ret < 0) 296 return ret; 297 298 return 0; 299 } 300 301 static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io, 302 struct rsnd_mod *mod) 303 { 304 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 305 306 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv), 307 mod, "tx"); 308 } 309 310 static struct rsnd_mod_ops rsnd_dvc_ops = { 311 .name = DVC_NAME, 312 .dma_req = rsnd_dvc_dma_req, 313 .probe = rsnd_dvc_probe_, 314 .remove = rsnd_dvc_remove_, 315 .init = rsnd_dvc_init, 316 .quit = rsnd_dvc_quit, 317 .pcm_new = rsnd_dvc_pcm_new, 318 }; 319 320 struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) 321 { 322 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) 323 id = 0; 324 325 return rsnd_mod_get(rsnd_dvc_get(priv, id)); 326 } 327 328 int rsnd_dvc_probe(struct rsnd_priv *priv) 329 { 330 struct device_node *node; 331 struct device_node *np; 332 struct device *dev = rsnd_priv_to_dev(priv); 333 struct rsnd_dvc *dvc; 334 struct clk *clk; 335 char name[RSND_DVC_NAME_SIZE]; 336 int i, nr, ret; 337 338 /* This driver doesn't support Gen1 at this point */ 339 if (rsnd_is_gen1(priv)) 340 return 0; 341 342 node = rsnd_dvc_of_node(priv); 343 if (!node) 344 return 0; /* not used is not error */ 345 346 nr = of_get_child_count(node); 347 if (!nr) { 348 ret = -EINVAL; 349 goto rsnd_dvc_probe_done; 350 } 351 352 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); 353 if (!dvc) { 354 ret = -ENOMEM; 355 goto rsnd_dvc_probe_done; 356 } 357 358 priv->dvc_nr = nr; 359 priv->dvc = dvc; 360 361 i = 0; 362 ret = 0; 363 for_each_child_of_node(node, np) { 364 dvc = rsnd_dvc_get(priv, i); 365 366 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d", 367 DVC_NAME, i); 368 369 clk = devm_clk_get(dev, name); 370 if (IS_ERR(clk)) { 371 ret = PTR_ERR(clk); 372 goto rsnd_dvc_probe_done; 373 } 374 375 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, 376 clk, RSND_MOD_DVC, i); 377 if (ret) 378 goto rsnd_dvc_probe_done; 379 380 i++; 381 } 382 383 rsnd_dvc_probe_done: 384 of_node_put(node); 385 386 return ret; 387 } 388 389 void rsnd_dvc_remove(struct rsnd_priv *priv) 390 { 391 struct rsnd_dvc *dvc; 392 int i; 393 394 for_each_rsnd_dvc(dvc, priv, i) { 395 rsnd_mod_quit(rsnd_mod_get(dvc)); 396 } 397 } 398