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