1/* 2 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com> 3 * 4 * Original author: 5 * Ben Collins <bcollins@ubuntu.com> 6 * 7 * Additional work by: 8 * John Brooks <john.brooks@bluecherry.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21#include <linux/kernel.h> 22#include <linux/mempool.h> 23#include <linux/poll.h> 24#include <linux/kthread.h> 25#include <linux/freezer.h> 26#include <linux/module.h> 27#include <linux/slab.h> 28 29#include <sound/core.h> 30#include <sound/initval.h> 31#include <sound/pcm.h> 32#include <sound/control.h> 33 34#include "solo6x10.h" 35#include "solo6x10-tw28.h" 36 37#define G723_FDMA_PAGES 32 38#define G723_PERIOD_BYTES 48 39#define G723_PERIOD_BLOCK 1024 40#define G723_FRAMES_PER_PAGE 48 41 42/* Sets up channels 16-19 for decoding and 0-15 for encoding */ 43#define OUTMODE_MASK 0x300 44 45#define SAMPLERATE 8000 46#define BITRATE 25 47 48/* The solo writes to 1k byte pages, 32 pages, in the dma. Each 1k page 49 * is broken down to 20 * 48 byte regions (one for each channel possible) 50 * with the rest of the page being dummy data. */ 51#define G723_MAX_BUFFER (G723_PERIOD_BYTES * PERIODS_MAX) 52#define G723_INTR_ORDER 4 /* 0 - 4 */ 53#define PERIODS_MIN (1 << G723_INTR_ORDER) 54#define PERIODS_MAX G723_FDMA_PAGES 55 56struct solo_snd_pcm { 57 int on; 58 spinlock_t lock; 59 struct solo_dev *solo_dev; 60 u8 *g723_buf; 61 dma_addr_t g723_dma; 62}; 63 64static void solo_g723_config(struct solo_dev *solo_dev) 65{ 66 int clk_div; 67 68 clk_div = (solo_dev->clock_mhz * 1000000) 69 / (SAMPLERATE * (BITRATE * 2) * 2); 70 71 solo_reg_write(solo_dev, SOLO_AUDIO_SAMPLE, 72 SOLO_AUDIO_BITRATE(BITRATE) 73 | SOLO_AUDIO_CLK_DIV(clk_div)); 74 75 solo_reg_write(solo_dev, SOLO_AUDIO_FDMA_INTR, 76 SOLO_AUDIO_FDMA_INTERVAL(1) 77 | SOLO_AUDIO_INTR_ORDER(G723_INTR_ORDER) 78 | SOLO_AUDIO_FDMA_BASE(SOLO_G723_EXT_ADDR(solo_dev) >> 16)); 79 80 solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 81 SOLO_AUDIO_ENABLE 82 | SOLO_AUDIO_I2S_MODE 83 | SOLO_AUDIO_I2S_MULTI(3) 84 | SOLO_AUDIO_MODE(OUTMODE_MASK)); 85} 86 87void solo_g723_isr(struct solo_dev *solo_dev) 88{ 89 struct snd_pcm_str *pstr = 90 &solo_dev->snd_pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; 91 struct snd_pcm_substream *ss; 92 struct solo_snd_pcm *solo_pcm; 93 94 for (ss = pstr->substream; ss != NULL; ss = ss->next) { 95 if (snd_pcm_substream_chip(ss) == NULL) 96 continue; 97 98 /* This means open() hasn't been called on this one */ 99 if (snd_pcm_substream_chip(ss) == solo_dev) 100 continue; 101 102 /* Haven't triggered a start yet */ 103 solo_pcm = snd_pcm_substream_chip(ss); 104 if (!solo_pcm->on) 105 continue; 106 107 snd_pcm_period_elapsed(ss); 108 } 109} 110 111static int snd_solo_hw_params(struct snd_pcm_substream *ss, 112 struct snd_pcm_hw_params *hw_params) 113{ 114 return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params)); 115} 116 117static int snd_solo_hw_free(struct snd_pcm_substream *ss) 118{ 119 return snd_pcm_lib_free_pages(ss); 120} 121 122static const struct snd_pcm_hardware snd_solo_pcm_hw = { 123 .info = (SNDRV_PCM_INFO_MMAP | 124 SNDRV_PCM_INFO_INTERLEAVED | 125 SNDRV_PCM_INFO_BLOCK_TRANSFER | 126 SNDRV_PCM_INFO_MMAP_VALID), 127 .formats = SNDRV_PCM_FMTBIT_U8, 128 .rates = SNDRV_PCM_RATE_8000, 129 .rate_min = SAMPLERATE, 130 .rate_max = SAMPLERATE, 131 .channels_min = 1, 132 .channels_max = 1, 133 .buffer_bytes_max = G723_MAX_BUFFER, 134 .period_bytes_min = G723_PERIOD_BYTES, 135 .period_bytes_max = G723_PERIOD_BYTES, 136 .periods_min = PERIODS_MIN, 137 .periods_max = PERIODS_MAX, 138}; 139 140static int snd_solo_pcm_open(struct snd_pcm_substream *ss) 141{ 142 struct solo_dev *solo_dev = snd_pcm_substream_chip(ss); 143 struct solo_snd_pcm *solo_pcm; 144 145 solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL); 146 if (solo_pcm == NULL) 147 goto oom; 148 149 solo_pcm->g723_buf = pci_alloc_consistent(solo_dev->pdev, 150 G723_PERIOD_BYTES, 151 &solo_pcm->g723_dma); 152 if (solo_pcm->g723_buf == NULL) 153 goto oom; 154 155 spin_lock_init(&solo_pcm->lock); 156 solo_pcm->solo_dev = solo_dev; 157 ss->runtime->hw = snd_solo_pcm_hw; 158 159 snd_pcm_substream_chip(ss) = solo_pcm; 160 161 return 0; 162 163oom: 164 kfree(solo_pcm); 165 return -ENOMEM; 166} 167 168static int snd_solo_pcm_close(struct snd_pcm_substream *ss) 169{ 170 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); 171 172 snd_pcm_substream_chip(ss) = solo_pcm->solo_dev; 173 pci_free_consistent(solo_pcm->solo_dev->pdev, G723_PERIOD_BYTES, 174 solo_pcm->g723_buf, solo_pcm->g723_dma); 175 kfree(solo_pcm); 176 177 return 0; 178} 179 180static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) 181{ 182 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); 183 struct solo_dev *solo_dev = solo_pcm->solo_dev; 184 int ret = 0; 185 186 spin_lock(&solo_pcm->lock); 187 188 switch (cmd) { 189 case SNDRV_PCM_TRIGGER_START: 190 if (solo_pcm->on == 0) { 191 /* If this is the first user, switch on interrupts */ 192 if (atomic_inc_return(&solo_dev->snd_users) == 1) 193 solo_irq_on(solo_dev, SOLO_IRQ_G723); 194 solo_pcm->on = 1; 195 } 196 break; 197 case SNDRV_PCM_TRIGGER_STOP: 198 if (solo_pcm->on) { 199 /* If this was our last user, switch them off */ 200 if (atomic_dec_return(&solo_dev->snd_users) == 0) 201 solo_irq_off(solo_dev, SOLO_IRQ_G723); 202 solo_pcm->on = 0; 203 } 204 break; 205 default: 206 ret = -EINVAL; 207 } 208 209 spin_unlock(&solo_pcm->lock); 210 211 return ret; 212} 213 214static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss) 215{ 216 return 0; 217} 218 219static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) 220{ 221 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); 222 struct solo_dev *solo_dev = solo_pcm->solo_dev; 223 snd_pcm_uframes_t idx = solo_reg_read(solo_dev, SOLO_AUDIO_STA) & 0x1f; 224 225 return idx * G723_FRAMES_PER_PAGE; 226} 227 228static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, 229 snd_pcm_uframes_t pos, void __user *dst, 230 snd_pcm_uframes_t count) 231{ 232 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); 233 struct solo_dev *solo_dev = solo_pcm->solo_dev; 234 int err, i; 235 236 for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) { 237 int page = (pos / G723_FRAMES_PER_PAGE) + i; 238 239 err = solo_p2m_dma_t(solo_dev, 0, solo_pcm->g723_dma, 240 SOLO_G723_EXT_ADDR(solo_dev) + 241 (page * G723_PERIOD_BLOCK) + 242 (ss->number * G723_PERIOD_BYTES), 243 G723_PERIOD_BYTES, 0, 0); 244 if (err) 245 return err; 246 247 err = copy_to_user(dst + (i * G723_PERIOD_BYTES), 248 solo_pcm->g723_buf, G723_PERIOD_BYTES); 249 250 if (err) 251 return -EFAULT; 252 } 253 254 return 0; 255} 256 257static struct snd_pcm_ops snd_solo_pcm_ops = { 258 .open = snd_solo_pcm_open, 259 .close = snd_solo_pcm_close, 260 .ioctl = snd_pcm_lib_ioctl, 261 .hw_params = snd_solo_hw_params, 262 .hw_free = snd_solo_hw_free, 263 .prepare = snd_solo_pcm_prepare, 264 .trigger = snd_solo_pcm_trigger, 265 .pointer = snd_solo_pcm_pointer, 266 .copy = snd_solo_pcm_copy, 267}; 268 269static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, 270 struct snd_ctl_elem_info *info) 271{ 272 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 273 info->count = 1; 274 info->value.integer.min = 0; 275 info->value.integer.max = 15; 276 info->value.integer.step = 1; 277 278 return 0; 279} 280 281static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, 282 struct snd_ctl_elem_value *value) 283{ 284 struct solo_dev *solo_dev = snd_kcontrol_chip(kcontrol); 285 u8 ch = value->id.numid - 1; 286 287 value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch); 288 289 return 0; 290} 291 292static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, 293 struct snd_ctl_elem_value *value) 294{ 295 struct solo_dev *solo_dev = snd_kcontrol_chip(kcontrol); 296 u8 ch = value->id.numid - 1; 297 u8 old_val; 298 299 old_val = tw28_get_audio_gain(solo_dev, ch); 300 if (old_val == value->value.integer.value[0]) 301 return 0; 302 303 tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]); 304 305 return 1; 306} 307 308static struct snd_kcontrol_new snd_solo_capture_volume = { 309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 310 .name = "Capture Volume", 311 .info = snd_solo_capture_volume_info, 312 .get = snd_solo_capture_volume_get, 313 .put = snd_solo_capture_volume_put, 314}; 315 316static int solo_snd_pcm_init(struct solo_dev *solo_dev) 317{ 318 struct snd_card *card = solo_dev->snd_card; 319 struct snd_pcm *pcm; 320 struct snd_pcm_substream *ss; 321 int ret; 322 int i; 323 324 ret = snd_pcm_new(card, card->driver, 0, 0, solo_dev->nr_chans, 325 &pcm); 326 if (ret < 0) 327 return ret; 328 329 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 330 &snd_solo_pcm_ops); 331 332 snd_pcm_chip(pcm) = solo_dev; 333 pcm->info_flags = 0; 334 strcpy(pcm->name, card->shortname); 335 336 for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 337 ss; ss = ss->next, i++) 338 sprintf(ss->name, "Camera #%d Audio", i); 339 340 ret = snd_pcm_lib_preallocate_pages_for_all(pcm, 341 SNDRV_DMA_TYPE_CONTINUOUS, 342 snd_dma_continuous_data(GFP_KERNEL), 343 G723_MAX_BUFFER, G723_MAX_BUFFER); 344 if (ret < 0) 345 return ret; 346 347 solo_dev->snd_pcm = pcm; 348 349 return 0; 350} 351 352int solo_g723_init(struct solo_dev *solo_dev) 353{ 354 static struct snd_device_ops ops = { NULL }; 355 struct snd_card *card; 356 struct snd_kcontrol_new kctl; 357 char name[32]; 358 int ret; 359 360 atomic_set(&solo_dev->snd_users, 0); 361 362 /* Allows for easier mapping between video and audio */ 363 sprintf(name, "Softlogic%d", solo_dev->vfd->num); 364 365 ret = snd_card_new(&solo_dev->pdev->dev, 366 SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0, 367 &solo_dev->snd_card); 368 if (ret < 0) 369 return ret; 370 371 card = solo_dev->snd_card; 372 373 strcpy(card->driver, SOLO6X10_NAME); 374 strcpy(card->shortname, "SOLO-6x10 Audio"); 375 sprintf(card->longname, "%s on %s IRQ %d", card->shortname, 376 pci_name(solo_dev->pdev), solo_dev->pdev->irq); 377 378 ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, solo_dev, &ops); 379 if (ret < 0) 380 goto snd_error; 381 382 /* Mixer controls */ 383 strcpy(card->mixername, "SOLO-6x10"); 384 kctl = snd_solo_capture_volume; 385 kctl.count = solo_dev->nr_chans; 386 387 ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); 388 if (ret < 0) 389 return ret; 390 391 ret = solo_snd_pcm_init(solo_dev); 392 if (ret < 0) 393 goto snd_error; 394 395 ret = snd_card_register(card); 396 if (ret < 0) 397 goto snd_error; 398 399 solo_g723_config(solo_dev); 400 401 dev_info(&solo_dev->pdev->dev, "Alsa sound card as %s\n", name); 402 403 return 0; 404 405snd_error: 406 snd_card_free(card); 407 return ret; 408} 409 410void solo_g723_exit(struct solo_dev *solo_dev) 411{ 412 if (!solo_dev->snd_card) 413 return; 414 415 solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 0); 416 solo_irq_off(solo_dev, SOLO_IRQ_G723); 417 418 snd_card_free(solo_dev->snd_card); 419 solo_dev->snd_card = NULL; 420} 421