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