1/* 2 * Fushicai USBTV007 Audio-Video Grabber Driver 3 * 4 * Product web site: 5 * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html 6 * 7 * Copyright (c) 2013 Federico Simoncelli 8 * All rights reserved. 9 * No physical hardware was harmed running Windows during the 10 * reverse-engineering activity 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * Alternatively, this software may be distributed under the terms of the 22 * GNU General Public License ("GPL"). 23 */ 24 25#include <sound/core.h> 26#include <sound/initval.h> 27#include <sound/ac97_codec.h> 28#include <sound/pcm_params.h> 29 30#include "usbtv.h" 31 32static struct snd_pcm_hardware snd_usbtv_digital_hw = { 33 .info = SNDRV_PCM_INFO_BATCH | 34 SNDRV_PCM_INFO_MMAP | 35 SNDRV_PCM_INFO_INTERLEAVED | 36 SNDRV_PCM_INFO_BLOCK_TRANSFER | 37 SNDRV_PCM_INFO_MMAP_VALID, 38 .formats = SNDRV_PCM_FMTBIT_S16_LE, 39 .rates = SNDRV_PCM_RATE_48000, 40 .rate_min = 48000, 41 .rate_max = 48000, 42 .channels_min = 2, 43 .channels_max = 2, 44 .period_bytes_min = 11059, 45 .period_bytes_max = 13516, 46 .periods_min = 2, 47 .periods_max = 98, 48 .buffer_bytes_max = 62720 * 8, /* value in usbaudio.c */ 49}; 50 51static int snd_usbtv_pcm_open(struct snd_pcm_substream *substream) 52{ 53 struct usbtv *chip = snd_pcm_substream_chip(substream); 54 struct snd_pcm_runtime *runtime = substream->runtime; 55 56 chip->snd_substream = substream; 57 runtime->hw = snd_usbtv_digital_hw; 58 59 return 0; 60} 61 62static int snd_usbtv_pcm_close(struct snd_pcm_substream *substream) 63{ 64 struct usbtv *chip = snd_pcm_substream_chip(substream); 65 66 if (atomic_read(&chip->snd_stream)) { 67 atomic_set(&chip->snd_stream, 0); 68 schedule_work(&chip->snd_trigger); 69 } 70 71 return 0; 72} 73 74static int snd_usbtv_hw_params(struct snd_pcm_substream *substream, 75 struct snd_pcm_hw_params *hw_params) 76{ 77 int rv; 78 struct usbtv *chip = snd_pcm_substream_chip(substream); 79 80 rv = snd_pcm_lib_malloc_pages(substream, 81 params_buffer_bytes(hw_params)); 82 83 if (rv < 0) { 84 dev_warn(chip->dev, "pcm audio buffer allocation failure %i\n", 85 rv); 86 return rv; 87 } 88 89 return 0; 90} 91 92static int snd_usbtv_hw_free(struct snd_pcm_substream *substream) 93{ 94 snd_pcm_lib_free_pages(substream); 95 return 0; 96} 97 98static int snd_usbtv_prepare(struct snd_pcm_substream *substream) 99{ 100 struct usbtv *chip = snd_pcm_substream_chip(substream); 101 102 chip->snd_buffer_pos = 0; 103 chip->snd_period_pos = 0; 104 105 return 0; 106} 107 108static void usbtv_audio_urb_received(struct urb *urb) 109{ 110 struct usbtv *chip = urb->context; 111 struct snd_pcm_substream *substream = chip->snd_substream; 112 struct snd_pcm_runtime *runtime = substream->runtime; 113 size_t i, frame_bytes, chunk_length, buffer_pos, period_pos; 114 int period_elapsed; 115 void *urb_current; 116 117 switch (urb->status) { 118 case 0: 119 case -ETIMEDOUT: 120 break; 121 case -ENOENT: 122 case -EPROTO: 123 case -ECONNRESET: 124 case -ESHUTDOWN: 125 return; 126 default: 127 dev_warn(chip->dev, "unknown audio urb status %i\n", 128 urb->status); 129 } 130 131 if (!atomic_read(&chip->snd_stream)) 132 return; 133 134 frame_bytes = runtime->frame_bits >> 3; 135 chunk_length = USBTV_CHUNK / frame_bytes; 136 137 buffer_pos = chip->snd_buffer_pos; 138 period_pos = chip->snd_period_pos; 139 period_elapsed = 0; 140 141 for (i = 0; i < urb->actual_length; i += USBTV_CHUNK_SIZE) { 142 urb_current = urb->transfer_buffer + i + USBTV_AUDIO_HDRSIZE; 143 144 if (buffer_pos + chunk_length >= runtime->buffer_size) { 145 size_t cnt = (runtime->buffer_size - buffer_pos) * 146 frame_bytes; 147 memcpy(runtime->dma_area + buffer_pos * frame_bytes, 148 urb_current, cnt); 149 memcpy(runtime->dma_area, urb_current + cnt, 150 chunk_length * frame_bytes - cnt); 151 } else { 152 memcpy(runtime->dma_area + buffer_pos * frame_bytes, 153 urb_current, chunk_length * frame_bytes); 154 } 155 156 buffer_pos += chunk_length; 157 period_pos += chunk_length; 158 159 if (buffer_pos >= runtime->buffer_size) 160 buffer_pos -= runtime->buffer_size; 161 162 if (period_pos >= runtime->period_size) { 163 period_pos -= runtime->period_size; 164 period_elapsed = 1; 165 } 166 } 167 168 snd_pcm_stream_lock(substream); 169 170 chip->snd_buffer_pos = buffer_pos; 171 chip->snd_period_pos = period_pos; 172 173 snd_pcm_stream_unlock(substream); 174 175 if (period_elapsed) 176 snd_pcm_period_elapsed(substream); 177 178 usb_submit_urb(urb, GFP_ATOMIC); 179} 180 181static int usbtv_audio_start(struct usbtv *chip) 182{ 183 unsigned int pipe; 184 static const u16 setup[][2] = { 185 /* These seem to enable the device. */ 186 { USBTV_BASE + 0x0008, 0x0001 }, 187 { USBTV_BASE + 0x01d0, 0x00ff }, 188 { USBTV_BASE + 0x01d9, 0x0002 }, 189 190 { USBTV_BASE + 0x01da, 0x0013 }, 191 { USBTV_BASE + 0x01db, 0x0012 }, 192 { USBTV_BASE + 0x01e9, 0x0002 }, 193 { USBTV_BASE + 0x01ec, 0x006c }, 194 { USBTV_BASE + 0x0294, 0x0020 }, 195 { USBTV_BASE + 0x0255, 0x00cf }, 196 { USBTV_BASE + 0x0256, 0x0020 }, 197 { USBTV_BASE + 0x01eb, 0x0030 }, 198 { USBTV_BASE + 0x027d, 0x00a6 }, 199 { USBTV_BASE + 0x0280, 0x0011 }, 200 { USBTV_BASE + 0x0281, 0x0040 }, 201 { USBTV_BASE + 0x0282, 0x0011 }, 202 { USBTV_BASE + 0x0283, 0x0040 }, 203 { 0xf891, 0x0010 }, 204 205 /* this sets the input from composite */ 206 { USBTV_BASE + 0x0284, 0x00aa }, 207 }; 208 209 chip->snd_bulk_urb = usb_alloc_urb(0, GFP_KERNEL); 210 if (chip->snd_bulk_urb == NULL) 211 goto err_alloc_urb; 212 213 pipe = usb_rcvbulkpipe(chip->udev, USBTV_AUDIO_ENDP); 214 215 chip->snd_bulk_urb->transfer_buffer = kzalloc( 216 USBTV_AUDIO_URBSIZE, GFP_KERNEL); 217 if (chip->snd_bulk_urb->transfer_buffer == NULL) 218 goto err_transfer_buffer; 219 220 usb_fill_bulk_urb(chip->snd_bulk_urb, chip->udev, pipe, 221 chip->snd_bulk_urb->transfer_buffer, USBTV_AUDIO_URBSIZE, 222 usbtv_audio_urb_received, chip); 223 224 /* starting the stream */ 225 usbtv_set_regs(chip, setup, ARRAY_SIZE(setup)); 226 227 usb_clear_halt(chip->udev, pipe); 228 usb_submit_urb(chip->snd_bulk_urb, GFP_ATOMIC); 229 230 return 0; 231 232err_transfer_buffer: 233 usb_free_urb(chip->snd_bulk_urb); 234 chip->snd_bulk_urb = NULL; 235 236err_alloc_urb: 237 return -ENOMEM; 238} 239 240static int usbtv_audio_stop(struct usbtv *chip) 241{ 242 static const u16 setup[][2] = { 243 /* The original windows driver sometimes sends also: 244 * { USBTV_BASE + 0x00a2, 0x0013 } 245 * but it seems useless and its real effects are untested at 246 * the moment. 247 */ 248 { USBTV_BASE + 0x027d, 0x0000 }, 249 { USBTV_BASE + 0x0280, 0x0010 }, 250 { USBTV_BASE + 0x0282, 0x0010 }, 251 }; 252 253 if (chip->snd_bulk_urb) { 254 usb_kill_urb(chip->snd_bulk_urb); 255 kfree(chip->snd_bulk_urb->transfer_buffer); 256 usb_free_urb(chip->snd_bulk_urb); 257 chip->snd_bulk_urb = NULL; 258 } 259 260 usbtv_set_regs(chip, setup, ARRAY_SIZE(setup)); 261 262 return 0; 263} 264 265void usbtv_audio_suspend(struct usbtv *usbtv) 266{ 267 if (atomic_read(&usbtv->snd_stream) && usbtv->snd_bulk_urb) 268 usb_kill_urb(usbtv->snd_bulk_urb); 269} 270 271void usbtv_audio_resume(struct usbtv *usbtv) 272{ 273 if (atomic_read(&usbtv->snd_stream) && usbtv->snd_bulk_urb) 274 usb_submit_urb(usbtv->snd_bulk_urb, GFP_ATOMIC); 275} 276 277static void snd_usbtv_trigger(struct work_struct *work) 278{ 279 struct usbtv *chip = container_of(work, struct usbtv, snd_trigger); 280 281 if (atomic_read(&chip->snd_stream)) 282 usbtv_audio_start(chip); 283 else 284 usbtv_audio_stop(chip); 285} 286 287static int snd_usbtv_card_trigger(struct snd_pcm_substream *substream, int cmd) 288{ 289 struct usbtv *chip = snd_pcm_substream_chip(substream); 290 291 switch (cmd) { 292 case SNDRV_PCM_TRIGGER_START: 293 case SNDRV_PCM_TRIGGER_RESUME: 294 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 295 atomic_set(&chip->snd_stream, 1); 296 break; 297 case SNDRV_PCM_TRIGGER_STOP: 298 case SNDRV_PCM_TRIGGER_SUSPEND: 299 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 300 atomic_set(&chip->snd_stream, 0); 301 break; 302 default: 303 return -EINVAL; 304 } 305 306 schedule_work(&chip->snd_trigger); 307 308 return 0; 309} 310 311static snd_pcm_uframes_t snd_usbtv_pointer(struct snd_pcm_substream *substream) 312{ 313 struct usbtv *chip = snd_pcm_substream_chip(substream); 314 315 return chip->snd_buffer_pos; 316} 317 318static struct snd_pcm_ops snd_usbtv_pcm_ops = { 319 .open = snd_usbtv_pcm_open, 320 .close = snd_usbtv_pcm_close, 321 .ioctl = snd_pcm_lib_ioctl, 322 .hw_params = snd_usbtv_hw_params, 323 .hw_free = snd_usbtv_hw_free, 324 .prepare = snd_usbtv_prepare, 325 .trigger = snd_usbtv_card_trigger, 326 .pointer = snd_usbtv_pointer, 327}; 328 329int usbtv_audio_init(struct usbtv *usbtv) 330{ 331 int rv; 332 struct snd_card *card; 333 struct snd_pcm *pcm; 334 335 INIT_WORK(&usbtv->snd_trigger, snd_usbtv_trigger); 336 atomic_set(&usbtv->snd_stream, 0); 337 338 rv = snd_card_new(&usbtv->udev->dev, SNDRV_DEFAULT_IDX1, "usbtv", 339 THIS_MODULE, 0, &card); 340 if (rv < 0) 341 return rv; 342 343 strlcpy(card->driver, usbtv->dev->driver->name, sizeof(card->driver)); 344 strlcpy(card->shortname, "usbtv", sizeof(card->shortname)); 345 snprintf(card->longname, sizeof(card->longname), 346 "USBTV Audio at bus %d device %d", usbtv->udev->bus->busnum, 347 usbtv->udev->devnum); 348 349 snd_card_set_dev(card, usbtv->dev); 350 351 usbtv->snd = card; 352 353 rv = snd_pcm_new(card, "USBTV Audio", 0, 0, 1, &pcm); 354 if (rv < 0) 355 goto err; 356 357 strlcpy(pcm->name, "USBTV Audio Input", sizeof(pcm->name)); 358 pcm->info_flags = 0; 359 pcm->private_data = usbtv; 360 361 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usbtv_pcm_ops); 362 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, 363 snd_dma_continuous_data(GFP_KERNEL), USBTV_AUDIO_BUFFER, 364 USBTV_AUDIO_BUFFER); 365 366 rv = snd_card_register(card); 367 if (rv) 368 goto err; 369 370 return 0; 371 372err: 373 usbtv->snd = NULL; 374 snd_card_free(card); 375 376 return rv; 377} 378 379void usbtv_audio_free(struct usbtv *usbtv) 380{ 381 if (usbtv->snd && usbtv->udev) { 382 snd_card_free(usbtv->snd); 383 usbtv->snd = NULL; 384 } 385} 386