diff options
| -rw-r--r-- | drivers/media/usb/au0828/au0828-cards.c | 4 | ||||
| -rw-r--r-- | drivers/media/usb/au0828/au0828-core.c | 52 | ||||
| -rw-r--r-- | drivers/media/usb/au0828/au0828-input.c | 4 | ||||
| -rw-r--r-- | drivers/media/usb/au0828/au0828-video.c | 63 | ||||
| -rw-r--r-- | drivers/media/usb/au0828/au0828.h | 9 | ||||
| -rw-r--r-- | sound/usb/Kconfig | 4 | ||||
| -rw-r--r-- | sound/usb/Makefile | 2 | ||||
| -rw-r--r-- | sound/usb/card.c | 14 | ||||
| -rw-r--r-- | sound/usb/card.h | 3 | ||||
| -rw-r--r-- | sound/usb/media.c | 318 | ||||
| -rw-r--r-- | sound/usb/media.h | 72 | ||||
| -rw-r--r-- | sound/usb/mixer.h | 3 | ||||
| -rw-r--r-- | sound/usb/pcm.c | 28 | ||||
| -rw-r--r-- | sound/usb/quirks-table.h | 1 | ||||
| -rw-r--r-- | sound/usb/stream.c | 2 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 6 |
16 files changed, 78 insertions, 507 deletions
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c index ca861aea68a5..6b469e8c4c6e 100644 --- a/drivers/media/usb/au0828/au0828-cards.c +++ b/drivers/media/usb/au0828/au0828-cards.c | |||
| @@ -228,10 +228,6 @@ void au0828_card_analog_fe_setup(struct au0828_dev *dev) | |||
| 228 | "au8522", 0x8e >> 1, NULL); | 228 | "au8522", 0x8e >> 1, NULL); |
| 229 | if (sd == NULL) | 229 | if (sd == NULL) |
| 230 | pr_err("analog subdev registration failed\n"); | 230 | pr_err("analog subdev registration failed\n"); |
| 231 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
| 232 | if (sd) | ||
| 233 | dev->decoder = &sd->entity; | ||
| 234 | #endif | ||
| 235 | } | 231 | } |
| 236 | 232 | ||
| 237 | /* Setup tuners */ | 233 | /* Setup tuners */ |
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 5dc82e8c8670..cc22b32776ad 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c | |||
| @@ -137,8 +137,14 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) | |||
| 137 | #ifdef CONFIG_MEDIA_CONTROLLER | 137 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 138 | if (dev->media_dev && | 138 | if (dev->media_dev && |
| 139 | media_devnode_is_registered(&dev->media_dev->devnode)) { | 139 | media_devnode_is_registered(&dev->media_dev->devnode)) { |
| 140 | /* clear enable_source, disable_source */ | ||
| 141 | dev->media_dev->source_priv = NULL; | ||
| 142 | dev->media_dev->enable_source = NULL; | ||
| 143 | dev->media_dev->disable_source = NULL; | ||
| 144 | |||
| 140 | media_device_unregister(dev->media_dev); | 145 | media_device_unregister(dev->media_dev); |
| 141 | media_device_cleanup(dev->media_dev); | 146 | media_device_cleanup(dev->media_dev); |
| 147 | kfree(dev->media_dev); | ||
| 142 | dev->media_dev = NULL; | 148 | dev->media_dev = NULL; |
| 143 | } | 149 | } |
| 144 | #endif | 150 | #endif |
| @@ -166,7 +172,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface) | |||
| 166 | Set the status so poll routines can check and avoid | 172 | Set the status so poll routines can check and avoid |
| 167 | access after disconnect. | 173 | access after disconnect. |
| 168 | */ | 174 | */ |
| 169 | dev->dev_state = DEV_DISCONNECTED; | 175 | set_bit(DEV_DISCONNECTED, &dev->dev_state); |
| 170 | 176 | ||
| 171 | au0828_rc_unregister(dev); | 177 | au0828_rc_unregister(dev); |
| 172 | /* Digital TV */ | 178 | /* Digital TV */ |
| @@ -192,7 +198,7 @@ static int au0828_media_device_init(struct au0828_dev *dev, | |||
| 192 | #ifdef CONFIG_MEDIA_CONTROLLER | 198 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 193 | struct media_device *mdev; | 199 | struct media_device *mdev; |
| 194 | 200 | ||
| 195 | mdev = media_device_get_devres(&udev->dev); | 201 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); |
| 196 | if (!mdev) | 202 | if (!mdev) |
| 197 | return -ENOMEM; | 203 | return -ENOMEM; |
| 198 | 204 | ||
| @@ -456,7 +462,8 @@ static int au0828_media_device_register(struct au0828_dev *dev, | |||
| 456 | { | 462 | { |
| 457 | #ifdef CONFIG_MEDIA_CONTROLLER | 463 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 458 | int ret; | 464 | int ret; |
| 459 | struct media_entity *entity, *demod = NULL, *tuner = NULL; | 465 | struct media_entity *entity, *demod = NULL; |
| 466 | struct media_link *link; | ||
| 460 | 467 | ||
| 461 | if (!dev->media_dev) | 468 | if (!dev->media_dev) |
| 462 | return 0; | 469 | return 0; |
| @@ -482,26 +489,37 @@ static int au0828_media_device_register(struct au0828_dev *dev, | |||
| 482 | } | 489 | } |
| 483 | 490 | ||
| 484 | /* | 491 | /* |
| 485 | * Find tuner and demod to disable the link between | 492 | * Find tuner, decoder and demod. |
| 486 | * the two to avoid disable step when tuner is requested | 493 | * |
| 487 | * by video or audio. Note that this step can't be done | 494 | * The tuner and decoder should be cached, as they'll be used by |
| 488 | * until dvb graph is created during dvb register. | 495 | * au0828_enable_source. |
| 496 | * | ||
| 497 | * It also needs to disable the link between tuner and | ||
| 498 | * decoder/demod, to avoid disable step when tuner is requested | ||
| 499 | * by video or audio. Note that this step can't be done until dvb | ||
| 500 | * graph is created during dvb register. | ||
| 489 | */ | 501 | */ |
| 490 | media_device_for_each_entity(entity, dev->media_dev) { | 502 | media_device_for_each_entity(entity, dev->media_dev) { |
| 491 | if (entity->function == MEDIA_ENT_F_DTV_DEMOD) | 503 | switch (entity->function) { |
| 504 | case MEDIA_ENT_F_TUNER: | ||
| 505 | dev->tuner = entity; | ||
| 506 | break; | ||
| 507 | case MEDIA_ENT_F_ATV_DECODER: | ||
| 508 | dev->decoder = entity; | ||
| 509 | break; | ||
| 510 | case MEDIA_ENT_F_DTV_DEMOD: | ||
| 492 | demod = entity; | 511 | demod = entity; |
| 493 | else if (entity->function == MEDIA_ENT_F_TUNER) | 512 | break; |
| 494 | tuner = entity; | 513 | } |
| 495 | } | 514 | } |
| 496 | /* Disable link between tuner and demod */ | ||
| 497 | if (tuner && demod) { | ||
| 498 | struct media_link *link; | ||
| 499 | 515 | ||
| 500 | list_for_each_entry(link, &demod->links, list) { | 516 | /* Disable link between tuner->demod and/or tuner->decoder */ |
| 501 | if (link->sink->entity == demod && | 517 | if (dev->tuner) { |
| 502 | link->source->entity == tuner) { | 518 | list_for_each_entry(link, &dev->tuner->links, list) { |
| 519 | if (demod && link->sink->entity == demod) | ||
| 520 | media_entity_setup_link(link, 0); | ||
| 521 | if (dev->decoder && link->sink->entity == dev->decoder) | ||
| 503 | media_entity_setup_link(link, 0); | 522 | media_entity_setup_link(link, 0); |
| 504 | } | ||
| 505 | } | 523 | } |
| 506 | } | 524 | } |
| 507 | 525 | ||
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index b0f067971979..3d6687f0407d 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c | |||
| @@ -130,7 +130,7 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) | |||
| 130 | bool first = true; | 130 | bool first = true; |
| 131 | 131 | ||
| 132 | /* do nothing if device is disconnected */ | 132 | /* do nothing if device is disconnected */ |
| 133 | if (ir->dev->dev_state == DEV_DISCONNECTED) | 133 | if (test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) |
| 134 | return 0; | 134 | return 0; |
| 135 | 135 | ||
| 136 | /* Check IR int */ | 136 | /* Check IR int */ |
| @@ -260,7 +260,7 @@ static void au0828_rc_stop(struct rc_dev *rc) | |||
| 260 | cancel_delayed_work_sync(&ir->work); | 260 | cancel_delayed_work_sync(&ir->work); |
| 261 | 261 | ||
| 262 | /* do nothing if device is disconnected */ | 262 | /* do nothing if device is disconnected */ |
| 263 | if (ir->dev->dev_state != DEV_DISCONNECTED) { | 263 | if (!test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) { |
| 264 | /* Disable IR */ | 264 | /* Disable IR */ |
| 265 | au8522_rc_clear(ir, 0xe0, 1 << 4); | 265 | au8522_rc_clear(ir, 0xe0, 1 << 4); |
| 266 | } | 266 | } |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 13f6dab9ccc2..32d7db96479c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
| @@ -106,14 +106,13 @@ static inline void print_err_status(struct au0828_dev *dev, | |||
| 106 | 106 | ||
| 107 | static int check_dev(struct au0828_dev *dev) | 107 | static int check_dev(struct au0828_dev *dev) |
| 108 | { | 108 | { |
| 109 | if (dev->dev_state & DEV_DISCONNECTED) { | 109 | if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) { |
| 110 | pr_info("v4l2 ioctl: device not present\n"); | 110 | pr_info("v4l2 ioctl: device not present\n"); |
| 111 | return -ENODEV; | 111 | return -ENODEV; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | if (dev->dev_state & DEV_MISCONFIGURED) { | 114 | if (test_bit(DEV_MISCONFIGURED, &dev->dev_state)) { |
| 115 | pr_info("v4l2 ioctl: device is misconfigured; " | 115 | pr_info("v4l2 ioctl: device is misconfigured; close and open it again\n"); |
| 116 | "close and open it again\n"); | ||
| 117 | return -EIO; | 116 | return -EIO; |
| 118 | } | 117 | } |
| 119 | return 0; | 118 | return 0; |
| @@ -521,8 +520,8 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) | |||
| 521 | if (!dev) | 520 | if (!dev) |
| 522 | return 0; | 521 | return 0; |
| 523 | 522 | ||
| 524 | if ((dev->dev_state & DEV_DISCONNECTED) || | 523 | if (test_bit(DEV_DISCONNECTED, &dev->dev_state) || |
| 525 | (dev->dev_state & DEV_MISCONFIGURED)) | 524 | test_bit(DEV_MISCONFIGURED, &dev->dev_state)) |
| 526 | return 0; | 525 | return 0; |
| 527 | 526 | ||
| 528 | if (urb->status < 0) { | 527 | if (urb->status < 0) { |
| @@ -824,10 +823,10 @@ static int au0828_stream_interrupt(struct au0828_dev *dev) | |||
| 824 | int ret = 0; | 823 | int ret = 0; |
| 825 | 824 | ||
| 826 | dev->stream_state = STREAM_INTERRUPT; | 825 | dev->stream_state = STREAM_INTERRUPT; |
| 827 | if (dev->dev_state == DEV_DISCONNECTED) | 826 | if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) |
| 828 | return -ENODEV; | 827 | return -ENODEV; |
| 829 | else if (ret) { | 828 | else if (ret) { |
| 830 | dev->dev_state = DEV_MISCONFIGURED; | 829 | set_bit(DEV_MISCONFIGURED, &dev->dev_state); |
| 831 | dprintk(1, "%s device is misconfigured!\n", __func__); | 830 | dprintk(1, "%s device is misconfigured!\n", __func__); |
| 832 | return ret; | 831 | return ret; |
| 833 | } | 832 | } |
| @@ -1026,7 +1025,7 @@ static int au0828_v4l2_open(struct file *filp) | |||
| 1026 | int ret; | 1025 | int ret; |
| 1027 | 1026 | ||
| 1028 | dprintk(1, | 1027 | dprintk(1, |
| 1029 | "%s called std_set %d dev_state %d stream users %d users %d\n", | 1028 | "%s called std_set %d dev_state %ld stream users %d users %d\n", |
| 1030 | __func__, dev->std_set_in_tuner_core, dev->dev_state, | 1029 | __func__, dev->std_set_in_tuner_core, dev->dev_state, |
| 1031 | dev->streaming_users, dev->users); | 1030 | dev->streaming_users, dev->users); |
| 1032 | 1031 | ||
| @@ -1045,7 +1044,7 @@ static int au0828_v4l2_open(struct file *filp) | |||
| 1045 | au0828_analog_stream_enable(dev); | 1044 | au0828_analog_stream_enable(dev); |
| 1046 | au0828_analog_stream_reset(dev); | 1045 | au0828_analog_stream_reset(dev); |
| 1047 | dev->stream_state = STREAM_OFF; | 1046 | dev->stream_state = STREAM_OFF; |
| 1048 | dev->dev_state |= DEV_INITIALIZED; | 1047 | set_bit(DEV_INITIALIZED, &dev->dev_state); |
| 1049 | } | 1048 | } |
| 1050 | dev->users++; | 1049 | dev->users++; |
| 1051 | mutex_unlock(&dev->lock); | 1050 | mutex_unlock(&dev->lock); |
| @@ -1059,7 +1058,7 @@ static int au0828_v4l2_close(struct file *filp) | |||
| 1059 | struct video_device *vdev = video_devdata(filp); | 1058 | struct video_device *vdev = video_devdata(filp); |
| 1060 | 1059 | ||
| 1061 | dprintk(1, | 1060 | dprintk(1, |
| 1062 | "%s called std_set %d dev_state %d stream users %d users %d\n", | 1061 | "%s called std_set %d dev_state %ld stream users %d users %d\n", |
| 1063 | __func__, dev->std_set_in_tuner_core, dev->dev_state, | 1062 | __func__, dev->std_set_in_tuner_core, dev->dev_state, |
| 1064 | dev->streaming_users, dev->users); | 1063 | dev->streaming_users, dev->users); |
| 1065 | 1064 | ||
| @@ -1075,7 +1074,7 @@ static int au0828_v4l2_close(struct file *filp) | |||
| 1075 | del_timer_sync(&dev->vbi_timeout); | 1074 | del_timer_sync(&dev->vbi_timeout); |
| 1076 | } | 1075 | } |
| 1077 | 1076 | ||
| 1078 | if (dev->dev_state == DEV_DISCONNECTED) | 1077 | if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) |
| 1079 | goto end; | 1078 | goto end; |
| 1080 | 1079 | ||
| 1081 | if (dev->users == 1) { | 1080 | if (dev->users == 1) { |
| @@ -1135,7 +1134,7 @@ static void au0828_init_tuner(struct au0828_dev *dev) | |||
| 1135 | .type = V4L2_TUNER_ANALOG_TV, | 1134 | .type = V4L2_TUNER_ANALOG_TV, |
| 1136 | }; | 1135 | }; |
| 1137 | 1136 | ||
| 1138 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1137 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1139 | dev->std_set_in_tuner_core, dev->dev_state); | 1138 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1140 | 1139 | ||
| 1141 | if (dev->std_set_in_tuner_core) | 1140 | if (dev->std_set_in_tuner_core) |
| @@ -1207,7 +1206,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 1207 | struct video_device *vdev = video_devdata(file); | 1206 | struct video_device *vdev = video_devdata(file); |
| 1208 | struct au0828_dev *dev = video_drvdata(file); | 1207 | struct au0828_dev *dev = video_drvdata(file); |
| 1209 | 1208 | ||
| 1210 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1209 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1211 | dev->std_set_in_tuner_core, dev->dev_state); | 1210 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1212 | 1211 | ||
| 1213 | strlcpy(cap->driver, "au0828", sizeof(cap->driver)); | 1212 | strlcpy(cap->driver, "au0828", sizeof(cap->driver)); |
| @@ -1250,7 +1249,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 1250 | { | 1249 | { |
| 1251 | struct au0828_dev *dev = video_drvdata(file); | 1250 | struct au0828_dev *dev = video_drvdata(file); |
| 1252 | 1251 | ||
| 1253 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1252 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1254 | dev->std_set_in_tuner_core, dev->dev_state); | 1253 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1255 | 1254 | ||
| 1256 | f->fmt.pix.width = dev->width; | 1255 | f->fmt.pix.width = dev->width; |
| @@ -1269,7 +1268,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1269 | { | 1268 | { |
| 1270 | struct au0828_dev *dev = video_drvdata(file); | 1269 | struct au0828_dev *dev = video_drvdata(file); |
| 1271 | 1270 | ||
| 1272 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1271 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1273 | dev->std_set_in_tuner_core, dev->dev_state); | 1272 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1274 | 1273 | ||
| 1275 | return au0828_set_format(dev, VIDIOC_TRY_FMT, f); | 1274 | return au0828_set_format(dev, VIDIOC_TRY_FMT, f); |
| @@ -1281,7 +1280,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 1281 | struct au0828_dev *dev = video_drvdata(file); | 1280 | struct au0828_dev *dev = video_drvdata(file); |
| 1282 | int rc; | 1281 | int rc; |
| 1283 | 1282 | ||
| 1284 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1283 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1285 | dev->std_set_in_tuner_core, dev->dev_state); | 1284 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1286 | 1285 | ||
| 1287 | rc = check_dev(dev); | 1286 | rc = check_dev(dev); |
| @@ -1303,7 +1302,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1303 | { | 1302 | { |
| 1304 | struct au0828_dev *dev = video_drvdata(file); | 1303 | struct au0828_dev *dev = video_drvdata(file); |
| 1305 | 1304 | ||
| 1306 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1305 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1307 | dev->std_set_in_tuner_core, dev->dev_state); | 1306 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1308 | 1307 | ||
| 1309 | if (norm == dev->std) | 1308 | if (norm == dev->std) |
| @@ -1335,7 +1334,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
| 1335 | { | 1334 | { |
| 1336 | struct au0828_dev *dev = video_drvdata(file); | 1335 | struct au0828_dev *dev = video_drvdata(file); |
| 1337 | 1336 | ||
| 1338 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1337 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1339 | dev->std_set_in_tuner_core, dev->dev_state); | 1338 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1340 | 1339 | ||
| 1341 | *norm = dev->std; | 1340 | *norm = dev->std; |
| @@ -1357,7 +1356,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
| 1357 | [AU0828_VMUX_DVB] = "DVB", | 1356 | [AU0828_VMUX_DVB] = "DVB", |
| 1358 | }; | 1357 | }; |
| 1359 | 1358 | ||
| 1360 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1359 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1361 | dev->std_set_in_tuner_core, dev->dev_state); | 1360 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1362 | 1361 | ||
| 1363 | tmp = input->index; | 1362 | tmp = input->index; |
| @@ -1387,7 +1386,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | |||
| 1387 | { | 1386 | { |
| 1388 | struct au0828_dev *dev = video_drvdata(file); | 1387 | struct au0828_dev *dev = video_drvdata(file); |
| 1389 | 1388 | ||
| 1390 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1389 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1391 | dev->std_set_in_tuner_core, dev->dev_state); | 1390 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1392 | 1391 | ||
| 1393 | *i = dev->ctrl_input; | 1392 | *i = dev->ctrl_input; |
| @@ -1398,7 +1397,7 @@ static void au0828_s_input(struct au0828_dev *dev, int index) | |||
| 1398 | { | 1397 | { |
| 1399 | int i; | 1398 | int i; |
| 1400 | 1399 | ||
| 1401 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1400 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1402 | dev->std_set_in_tuner_core, dev->dev_state); | 1401 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1403 | 1402 | ||
| 1404 | switch (AUVI_INPUT(index).type) { | 1403 | switch (AUVI_INPUT(index).type) { |
| @@ -1496,7 +1495,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
| 1496 | { | 1495 | { |
| 1497 | struct au0828_dev *dev = video_drvdata(file); | 1496 | struct au0828_dev *dev = video_drvdata(file); |
| 1498 | 1497 | ||
| 1499 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1498 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1500 | dev->std_set_in_tuner_core, dev->dev_state); | 1499 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1501 | 1500 | ||
| 1502 | a->index = dev->ctrl_ainput; | 1501 | a->index = dev->ctrl_ainput; |
| @@ -1516,7 +1515,7 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio | |||
| 1516 | if (a->index != dev->ctrl_ainput) | 1515 | if (a->index != dev->ctrl_ainput) |
| 1517 | return -EINVAL; | 1516 | return -EINVAL; |
| 1518 | 1517 | ||
| 1519 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1518 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1520 | dev->std_set_in_tuner_core, dev->dev_state); | 1519 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1521 | return 0; | 1520 | return 0; |
| 1522 | } | 1521 | } |
| @@ -1534,7 +1533,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
| 1534 | if (ret) | 1533 | if (ret) |
| 1535 | return ret; | 1534 | return ret; |
| 1536 | 1535 | ||
| 1537 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1536 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1538 | dev->std_set_in_tuner_core, dev->dev_state); | 1537 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1539 | 1538 | ||
| 1540 | strcpy(t->name, "Auvitek tuner"); | 1539 | strcpy(t->name, "Auvitek tuner"); |
| @@ -1554,7 +1553,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
| 1554 | if (t->index != 0) | 1553 | if (t->index != 0) |
| 1555 | return -EINVAL; | 1554 | return -EINVAL; |
| 1556 | 1555 | ||
| 1557 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1556 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1558 | dev->std_set_in_tuner_core, dev->dev_state); | 1557 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1559 | 1558 | ||
| 1560 | au0828_init_tuner(dev); | 1559 | au0828_init_tuner(dev); |
| @@ -1576,7 +1575,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
| 1576 | 1575 | ||
| 1577 | if (freq->tuner != 0) | 1576 | if (freq->tuner != 0) |
| 1578 | return -EINVAL; | 1577 | return -EINVAL; |
| 1579 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1578 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1580 | dev->std_set_in_tuner_core, dev->dev_state); | 1579 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1581 | freq->frequency = dev->ctrl_freq; | 1580 | freq->frequency = dev->ctrl_freq; |
| 1582 | return 0; | 1581 | return 0; |
| @@ -1591,7 +1590,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
| 1591 | if (freq->tuner != 0) | 1590 | if (freq->tuner != 0) |
| 1592 | return -EINVAL; | 1591 | return -EINVAL; |
| 1593 | 1592 | ||
| 1594 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1593 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1595 | dev->std_set_in_tuner_core, dev->dev_state); | 1594 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1596 | 1595 | ||
| 1597 | au0828_init_tuner(dev); | 1596 | au0828_init_tuner(dev); |
| @@ -1617,7 +1616,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
| 1617 | { | 1616 | { |
| 1618 | struct au0828_dev *dev = video_drvdata(file); | 1617 | struct au0828_dev *dev = video_drvdata(file); |
| 1619 | 1618 | ||
| 1620 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1619 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1621 | dev->std_set_in_tuner_core, dev->dev_state); | 1620 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1622 | 1621 | ||
| 1623 | format->fmt.vbi.samples_per_line = dev->vbi_width; | 1622 | format->fmt.vbi.samples_per_line = dev->vbi_width; |
| @@ -1643,7 +1642,7 @@ static int vidioc_cropcap(struct file *file, void *priv, | |||
| 1643 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1642 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1644 | return -EINVAL; | 1643 | return -EINVAL; |
| 1645 | 1644 | ||
| 1646 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1645 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1647 | dev->std_set_in_tuner_core, dev->dev_state); | 1646 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1648 | 1647 | ||
| 1649 | cc->bounds.left = 0; | 1648 | cc->bounds.left = 0; |
| @@ -1665,7 +1664,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 1665 | { | 1664 | { |
| 1666 | struct au0828_dev *dev = video_drvdata(file); | 1665 | struct au0828_dev *dev = video_drvdata(file); |
| 1667 | 1666 | ||
| 1668 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1667 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1669 | dev->std_set_in_tuner_core, dev->dev_state); | 1668 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1670 | 1669 | ||
| 1671 | reg->val = au0828_read(dev, reg->reg); | 1670 | reg->val = au0828_read(dev, reg->reg); |
| @@ -1678,7 +1677,7 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
| 1678 | { | 1677 | { |
| 1679 | struct au0828_dev *dev = video_drvdata(file); | 1678 | struct au0828_dev *dev = video_drvdata(file); |
| 1680 | 1679 | ||
| 1681 | dprintk(1, "%s called std_set %d dev_state %d\n", __func__, | 1680 | dprintk(1, "%s called std_set %d dev_state %ld\n", __func__, |
| 1682 | dev->std_set_in_tuner_core, dev->dev_state); | 1681 | dev->std_set_in_tuner_core, dev->dev_state); |
| 1683 | 1682 | ||
| 1684 | return au0828_writereg(dev, reg->reg, reg->val); | 1683 | return au0828_writereg(dev, reg->reg, reg->val); |
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index ff7f8510fb77..87f32846f1c0 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 23 | 23 | ||
| 24 | #include <linux/bitops.h> | ||
| 24 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
| 25 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
| 26 | #include <linux/i2c-algo-bit.h> | 27 | #include <linux/i2c-algo-bit.h> |
| @@ -121,9 +122,9 @@ enum au0828_stream_state { | |||
| 121 | 122 | ||
| 122 | /* device state */ | 123 | /* device state */ |
| 123 | enum au0828_dev_state { | 124 | enum au0828_dev_state { |
| 124 | DEV_INITIALIZED = 0x01, | 125 | DEV_INITIALIZED = 0, |
| 125 | DEV_DISCONNECTED = 0x02, | 126 | DEV_DISCONNECTED = 1, |
| 126 | DEV_MISCONFIGURED = 0x04 | 127 | DEV_MISCONFIGURED = 2 |
| 127 | }; | 128 | }; |
| 128 | 129 | ||
| 129 | struct au0828_dev; | 130 | struct au0828_dev; |
| @@ -247,7 +248,7 @@ struct au0828_dev { | |||
| 247 | int input_type; | 248 | int input_type; |
| 248 | int std_set_in_tuner_core; | 249 | int std_set_in_tuner_core; |
| 249 | unsigned int ctrl_input; | 250 | unsigned int ctrl_input; |
| 250 | enum au0828_dev_state dev_state; | 251 | long unsigned int dev_state; /* defined at enum au0828_dev_state */; |
| 251 | enum au0828_stream_state stream_state; | 252 | enum au0828_stream_state stream_state; |
| 252 | wait_queue_head_t open; | 253 | wait_queue_head_t open; |
| 253 | 254 | ||
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index d14bf411515b..a452ad7cec40 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
| @@ -15,7 +15,6 @@ config SND_USB_AUDIO | |||
| 15 | select SND_RAWMIDI | 15 | select SND_RAWMIDI |
| 16 | select SND_PCM | 16 | select SND_PCM |
| 17 | select BITREVERSE | 17 | select BITREVERSE |
| 18 | select SND_USB_AUDIO_USE_MEDIA_CONTROLLER if MEDIA_CONTROLLER && (MEDIA_SUPPORT=y || MEDIA_SUPPORT=SND_USB_AUDIO) | ||
| 19 | help | 18 | help |
| 20 | Say Y here to include support for USB audio and USB MIDI | 19 | Say Y here to include support for USB audio and USB MIDI |
| 21 | devices. | 20 | devices. |
| @@ -23,9 +22,6 @@ config SND_USB_AUDIO | |||
| 23 | To compile this driver as a module, choose M here: the module | 22 | To compile this driver as a module, choose M here: the module |
| 24 | will be called snd-usb-audio. | 23 | will be called snd-usb-audio. |
| 25 | 24 | ||
| 26 | config SND_USB_AUDIO_USE_MEDIA_CONTROLLER | ||
| 27 | bool | ||
| 28 | |||
| 29 | config SND_USB_UA101 | 25 | config SND_USB_UA101 |
| 30 | tristate "Edirol UA-101/UA-1000 driver" | 26 | tristate "Edirol UA-101/UA-1000 driver" |
| 31 | select SND_PCM | 27 | select SND_PCM |
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 8dca3c407f5a..2d2d122b069f 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
| @@ -15,8 +15,6 @@ snd-usb-audio-objs := card.o \ | |||
| 15 | quirks.o \ | 15 | quirks.o \ |
| 16 | stream.o | 16 | stream.o |
| 17 | 17 | ||
| 18 | snd-usb-audio-$(CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER) += media.o | ||
| 19 | |||
| 20 | snd-usbmidi-lib-objs := midi.o | 18 | snd-usbmidi-lib-objs := midi.o |
| 21 | 19 | ||
| 22 | # Toplevel Module Dependency | 20 | # Toplevel Module Dependency |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 63244bbba8c7..3fc63583a537 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -66,7 +66,6 @@ | |||
| 66 | #include "format.h" | 66 | #include "format.h" |
| 67 | #include "power.h" | 67 | #include "power.h" |
| 68 | #include "stream.h" | 68 | #include "stream.h" |
| 69 | #include "media.h" | ||
| 70 | 69 | ||
| 71 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 70 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
| 72 | MODULE_DESCRIPTION("USB Audio"); | 71 | MODULE_DESCRIPTION("USB Audio"); |
| @@ -612,11 +611,6 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
| 612 | if (err < 0) | 611 | if (err < 0) |
| 613 | goto __error; | 612 | goto __error; |
| 614 | 613 | ||
| 615 | if (quirk->media_device) { | ||
| 616 | /* don't want to fail when media_snd_device_create() fails */ | ||
| 617 | media_snd_device_create(chip, intf); | ||
| 618 | } | ||
| 619 | |||
| 620 | usb_chip[chip->index] = chip; | 614 | usb_chip[chip->index] = chip; |
| 621 | chip->num_interfaces++; | 615 | chip->num_interfaces++; |
| 622 | usb_set_intfdata(intf, chip); | 616 | usb_set_intfdata(intf, chip); |
| @@ -673,14 +667,6 @@ static void usb_audio_disconnect(struct usb_interface *intf) | |||
| 673 | list_for_each(p, &chip->midi_list) { | 667 | list_for_each(p, &chip->midi_list) { |
| 674 | snd_usbmidi_disconnect(p); | 668 | snd_usbmidi_disconnect(p); |
| 675 | } | 669 | } |
| 676 | /* | ||
| 677 | * Nice to check quirk && quirk->media_device | ||
| 678 | * need some special handlings. Doesn't look like | ||
| 679 | * we have access to quirk here | ||
| 680 | * Acceses mixer_list | ||
| 681 | */ | ||
| 682 | media_snd_device_delete(chip); | ||
| 683 | |||
| 684 | /* release mixer resources */ | 670 | /* release mixer resources */ |
| 685 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 671 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
| 686 | snd_usb_mixer_disconnect(mixer); | 672 | snd_usb_mixer_disconnect(mixer); |
diff --git a/sound/usb/card.h b/sound/usb/card.h index 34a0898e2238..71778ca4b26a 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
| @@ -105,8 +105,6 @@ struct snd_usb_endpoint { | |||
| 105 | struct list_head list; | 105 | struct list_head list; |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | struct media_ctl; | ||
| 109 | |||
| 110 | struct snd_usb_substream { | 108 | struct snd_usb_substream { |
| 111 | struct snd_usb_stream *stream; | 109 | struct snd_usb_stream *stream; |
| 112 | struct usb_device *dev; | 110 | struct usb_device *dev; |
| @@ -158,7 +156,6 @@ struct snd_usb_substream { | |||
| 158 | } dsd_dop; | 156 | } dsd_dop; |
| 159 | 157 | ||
| 160 | bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ | 158 | bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ |
| 161 | struct media_ctl *media_ctl; | ||
| 162 | }; | 159 | }; |
| 163 | 160 | ||
| 164 | struct snd_usb_stream { | 161 | struct snd_usb_stream { |
diff --git a/sound/usb/media.c b/sound/usb/media.c deleted file mode 100644 index 93a50d01490c..000000000000 --- a/sound/usb/media.c +++ /dev/null | |||
| @@ -1,318 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * media.c - Media Controller specific ALSA driver code | ||
| 3 | * | ||
| 4 | * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com> | ||
| 5 | * Copyright (c) 2016 Samsung Electronics Co., Ltd. | ||
| 6 | * | ||
| 7 | * This file is released under the GPLv2. | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This file adds Media Controller support to ALSA driver | ||
| 12 | * to use the Media Controller API to share tuner with DVB | ||
| 13 | * and V4L2 drivers that control media device. Media device | ||
| 14 | * is created based on existing quirks framework. Using this | ||
| 15 | * approach, the media controller API usage can be added for | ||
| 16 | * a specific device. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/list.h> | ||
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/usb.h> | ||
| 24 | |||
| 25 | #include <sound/pcm.h> | ||
| 26 | #include <sound/core.h> | ||
| 27 | |||
| 28 | #include "usbaudio.h" | ||
| 29 | #include "card.h" | ||
| 30 | #include "mixer.h" | ||
| 31 | #include "media.h" | ||
| 32 | |||
| 33 | static int media_snd_enable_source(struct media_ctl *mctl) | ||
| 34 | { | ||
| 35 | if (mctl && mctl->media_dev->enable_source) | ||
| 36 | return mctl->media_dev->enable_source(&mctl->media_entity, | ||
| 37 | &mctl->media_pipe); | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | static void media_snd_disable_source(struct media_ctl *mctl) | ||
| 42 | { | ||
| 43 | if (mctl && mctl->media_dev->disable_source) | ||
| 44 | mctl->media_dev->disable_source(&mctl->media_entity); | ||
| 45 | } | ||
| 46 | |||
| 47 | int media_snd_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, | ||
| 48 | int stream) | ||
| 49 | { | ||
| 50 | struct media_device *mdev; | ||
| 51 | struct media_ctl *mctl; | ||
| 52 | struct device *pcm_dev = &pcm->streams[stream].dev; | ||
| 53 | u32 intf_type; | ||
| 54 | int ret = 0; | ||
| 55 | u16 mixer_pad; | ||
| 56 | struct media_entity *entity; | ||
| 57 | |||
| 58 | mdev = subs->stream->chip->media_dev; | ||
| 59 | if (!mdev) | ||
| 60 | return -ENODEV; | ||
| 61 | |||
| 62 | if (subs->media_ctl) | ||
| 63 | return 0; | ||
| 64 | |||
| 65 | /* allocate media_ctl */ | ||
| 66 | mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); | ||
| 67 | if (!mctl) | ||
| 68 | return -ENOMEM; | ||
| 69 | |||
| 70 | mctl->media_dev = mdev; | ||
| 71 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 72 | intf_type = MEDIA_INTF_T_ALSA_PCM_PLAYBACK; | ||
| 73 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_PLAYBACK; | ||
| 74 | mctl->media_pad.flags = MEDIA_PAD_FL_SOURCE; | ||
| 75 | mixer_pad = 1; | ||
| 76 | } else { | ||
| 77 | intf_type = MEDIA_INTF_T_ALSA_PCM_CAPTURE; | ||
| 78 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_CAPTURE; | ||
| 79 | mctl->media_pad.flags = MEDIA_PAD_FL_SINK; | ||
| 80 | mixer_pad = 2; | ||
| 81 | } | ||
| 82 | mctl->media_entity.name = pcm->name; | ||
| 83 | media_entity_pads_init(&mctl->media_entity, 1, &mctl->media_pad); | ||
| 84 | ret = media_device_register_entity(mctl->media_dev, | ||
| 85 | &mctl->media_entity); | ||
| 86 | if (ret) | ||
| 87 | goto free_mctl; | ||
| 88 | |||
| 89 | mctl->intf_devnode = media_devnode_create(mdev, intf_type, 0, | ||
| 90 | MAJOR(pcm_dev->devt), | ||
| 91 | MINOR(pcm_dev->devt)); | ||
| 92 | if (!mctl->intf_devnode) { | ||
| 93 | ret = -ENOMEM; | ||
| 94 | goto unregister_entity; | ||
| 95 | } | ||
| 96 | mctl->intf_link = media_create_intf_link(&mctl->media_entity, | ||
| 97 | &mctl->intf_devnode->intf, | ||
| 98 | MEDIA_LNK_FL_ENABLED); | ||
| 99 | if (!mctl->intf_link) { | ||
| 100 | ret = -ENOMEM; | ||
| 101 | goto devnode_remove; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* create link between mixer and audio */ | ||
| 105 | media_device_for_each_entity(entity, mdev) { | ||
| 106 | switch (entity->function) { | ||
| 107 | case MEDIA_ENT_F_AUDIO_MIXER: | ||
| 108 | ret = media_create_pad_link(entity, mixer_pad, | ||
| 109 | &mctl->media_entity, 0, | ||
| 110 | MEDIA_LNK_FL_ENABLED); | ||
| 111 | if (ret) | ||
| 112 | goto remove_intf_link; | ||
| 113 | break; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | subs->media_ctl = mctl; | ||
| 118 | return 0; | ||
| 119 | |||
| 120 | remove_intf_link: | ||
| 121 | media_remove_intf_link(mctl->intf_link); | ||
| 122 | devnode_remove: | ||
| 123 | media_devnode_remove(mctl->intf_devnode); | ||
| 124 | unregister_entity: | ||
| 125 | media_device_unregister_entity(&mctl->media_entity); | ||
| 126 | free_mctl: | ||
| 127 | kfree(mctl); | ||
| 128 | return ret; | ||
| 129 | } | ||
| 130 | |||
| 131 | void media_snd_stream_delete(struct snd_usb_substream *subs) | ||
| 132 | { | ||
| 133 | struct media_ctl *mctl = subs->media_ctl; | ||
| 134 | |||
| 135 | if (mctl && mctl->media_dev) { | ||
| 136 | struct media_device *mdev; | ||
| 137 | |||
| 138 | mdev = subs->stream->chip->media_dev; | ||
| 139 | if (mdev && media_devnode_is_registered(&mdev->devnode)) { | ||
| 140 | media_devnode_remove(mctl->intf_devnode); | ||
| 141 | media_device_unregister_entity(&mctl->media_entity); | ||
| 142 | media_entity_cleanup(&mctl->media_entity); | ||
| 143 | } | ||
| 144 | kfree(mctl); | ||
| 145 | subs->media_ctl = NULL; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | int media_snd_start_pipeline(struct snd_usb_substream *subs) | ||
| 150 | { | ||
| 151 | struct media_ctl *mctl = subs->media_ctl; | ||
| 152 | |||
| 153 | if (mctl) | ||
| 154 | return media_snd_enable_source(mctl); | ||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | void media_snd_stop_pipeline(struct snd_usb_substream *subs) | ||
| 159 | { | ||
| 160 | struct media_ctl *mctl = subs->media_ctl; | ||
| 161 | |||
| 162 | if (mctl) | ||
| 163 | media_snd_disable_source(mctl); | ||
| 164 | } | ||
| 165 | |||
| 166 | int media_snd_mixer_init(struct snd_usb_audio *chip) | ||
| 167 | { | ||
| 168 | struct device *ctl_dev = &chip->card->ctl_dev; | ||
| 169 | struct media_intf_devnode *ctl_intf; | ||
| 170 | struct usb_mixer_interface *mixer; | ||
| 171 | struct media_device *mdev = chip->media_dev; | ||
| 172 | struct media_mixer_ctl *mctl; | ||
| 173 | u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL; | ||
| 174 | int ret; | ||
| 175 | |||
| 176 | if (!mdev) | ||
| 177 | return -ENODEV; | ||
| 178 | |||
| 179 | ctl_intf = chip->ctl_intf_media_devnode; | ||
| 180 | if (!ctl_intf) { | ||
| 181 | ctl_intf = media_devnode_create(mdev, intf_type, 0, | ||
| 182 | MAJOR(ctl_dev->devt), | ||
| 183 | MINOR(ctl_dev->devt)); | ||
| 184 | if (!ctl_intf) | ||
| 185 | return -ENOMEM; | ||
| 186 | chip->ctl_intf_media_devnode = ctl_intf; | ||
| 187 | } | ||
| 188 | |||
| 189 | list_for_each_entry(mixer, &chip->mixer_list, list) { | ||
| 190 | |||
| 191 | if (mixer->media_mixer_ctl) | ||
| 192 | continue; | ||
| 193 | |||
| 194 | /* allocate media_mixer_ctl */ | ||
| 195 | mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); | ||
| 196 | if (!mctl) | ||
| 197 | return -ENOMEM; | ||
| 198 | |||
| 199 | mctl->media_dev = mdev; | ||
| 200 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_MIXER; | ||
| 201 | mctl->media_entity.name = chip->card->mixername; | ||
| 202 | mctl->media_pad[0].flags = MEDIA_PAD_FL_SINK; | ||
| 203 | mctl->media_pad[1].flags = MEDIA_PAD_FL_SOURCE; | ||
| 204 | mctl->media_pad[2].flags = MEDIA_PAD_FL_SOURCE; | ||
| 205 | media_entity_pads_init(&mctl->media_entity, MEDIA_MIXER_PAD_MAX, | ||
| 206 | mctl->media_pad); | ||
| 207 | ret = media_device_register_entity(mctl->media_dev, | ||
| 208 | &mctl->media_entity); | ||
| 209 | if (ret) { | ||
| 210 | kfree(mctl); | ||
| 211 | return ret; | ||
| 212 | } | ||
| 213 | |||
| 214 | mctl->intf_link = media_create_intf_link(&mctl->media_entity, | ||
| 215 | &ctl_intf->intf, | ||
| 216 | MEDIA_LNK_FL_ENABLED); | ||
| 217 | if (!mctl->intf_link) { | ||
| 218 | media_device_unregister_entity(&mctl->media_entity); | ||
| 219 | media_entity_cleanup(&mctl->media_entity); | ||
| 220 | kfree(mctl); | ||
| 221 | return -ENOMEM; | ||
| 222 | } | ||
| 223 | mctl->intf_devnode = ctl_intf; | ||
| 224 | mixer->media_mixer_ctl = mctl; | ||
| 225 | } | ||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | |||
| 229 | static void media_snd_mixer_delete(struct snd_usb_audio *chip) | ||
| 230 | { | ||
| 231 | struct usb_mixer_interface *mixer; | ||
| 232 | struct media_device *mdev = chip->media_dev; | ||
| 233 | |||
| 234 | if (!mdev) | ||
| 235 | return; | ||
| 236 | |||
| 237 | list_for_each_entry(mixer, &chip->mixer_list, list) { | ||
| 238 | struct media_mixer_ctl *mctl; | ||
| 239 | |||
| 240 | mctl = mixer->media_mixer_ctl; | ||
| 241 | if (!mixer->media_mixer_ctl) | ||
| 242 | continue; | ||
| 243 | |||
| 244 | if (media_devnode_is_registered(&mdev->devnode)) { | ||
| 245 | media_device_unregister_entity(&mctl->media_entity); | ||
| 246 | media_entity_cleanup(&mctl->media_entity); | ||
| 247 | } | ||
| 248 | kfree(mctl); | ||
| 249 | mixer->media_mixer_ctl = NULL; | ||
| 250 | } | ||
| 251 | if (media_devnode_is_registered(&mdev->devnode)) | ||
| 252 | media_devnode_remove(chip->ctl_intf_media_devnode); | ||
| 253 | chip->ctl_intf_media_devnode = NULL; | ||
| 254 | } | ||
| 255 | |||
| 256 | int media_snd_device_create(struct snd_usb_audio *chip, | ||
| 257 | struct usb_interface *iface) | ||
| 258 | { | ||
| 259 | struct media_device *mdev; | ||
| 260 | struct usb_device *usbdev = interface_to_usbdev(iface); | ||
| 261 | int ret; | ||
| 262 | |||
| 263 | mdev = media_device_get_devres(&usbdev->dev); | ||
| 264 | if (!mdev) | ||
| 265 | return -ENOMEM; | ||
| 266 | if (!mdev->dev) { | ||
| 267 | /* register media device */ | ||
| 268 | mdev->dev = &usbdev->dev; | ||
| 269 | if (usbdev->product) | ||
| 270 | strlcpy(mdev->model, usbdev->product, | ||
| 271 | sizeof(mdev->model)); | ||
| 272 | if (usbdev->serial) | ||
| 273 | strlcpy(mdev->serial, usbdev->serial, | ||
| 274 | sizeof(mdev->serial)); | ||
| 275 | strcpy(mdev->bus_info, usbdev->devpath); | ||
| 276 | mdev->hw_revision = le16_to_cpu(usbdev->descriptor.bcdDevice); | ||
| 277 | media_device_init(mdev); | ||
| 278 | } | ||
| 279 | if (!media_devnode_is_registered(&mdev->devnode)) { | ||
| 280 | ret = media_device_register(mdev); | ||
| 281 | if (ret) { | ||
| 282 | dev_err(&usbdev->dev, | ||
| 283 | "Couldn't register media device. Error: %d\n", | ||
| 284 | ret); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | /* save media device - avoid lookups */ | ||
| 290 | chip->media_dev = mdev; | ||
| 291 | |||
| 292 | /* Create media entities for mixer and control dev */ | ||
| 293 | ret = media_snd_mixer_init(chip); | ||
| 294 | if (ret) { | ||
| 295 | dev_err(&usbdev->dev, | ||
| 296 | "Couldn't create media mixer entities. Error: %d\n", | ||
| 297 | ret); | ||
| 298 | |||
| 299 | /* clear saved media_dev */ | ||
| 300 | chip->media_dev = NULL; | ||
| 301 | |||
| 302 | return ret; | ||
| 303 | } | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | void media_snd_device_delete(struct snd_usb_audio *chip) | ||
| 308 | { | ||
| 309 | struct media_device *mdev = chip->media_dev; | ||
| 310 | |||
| 311 | media_snd_mixer_delete(chip); | ||
| 312 | |||
| 313 | if (mdev) { | ||
| 314 | if (media_devnode_is_registered(&mdev->devnode)) | ||
| 315 | media_device_unregister(mdev); | ||
| 316 | chip->media_dev = NULL; | ||
| 317 | } | ||
| 318 | } | ||
diff --git a/sound/usb/media.h b/sound/usb/media.h deleted file mode 100644 index 1dcdcdc5f7aa..000000000000 --- a/sound/usb/media.h +++ /dev/null | |||
| @@ -1,72 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * media.h - Media Controller specific ALSA driver code | ||
| 3 | * | ||
| 4 | * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com> | ||
| 5 | * Copyright (c) 2016 Samsung Electronics Co., Ltd. | ||
| 6 | * | ||
| 7 | * This file is released under the GPLv2. | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This file adds Media Controller support to ALSA driver | ||
| 12 | * to use the Media Controller API to share tuner with DVB | ||
| 13 | * and V4L2 drivers that control media device. Media device | ||
| 14 | * is created based on existing quirks framework. Using this | ||
| 15 | * approach, the media controller API usage can be added for | ||
| 16 | * a specific device. | ||
| 17 | */ | ||
| 18 | #ifndef __MEDIA_H | ||
| 19 | |||
| 20 | #ifdef CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER | ||
| 21 | |||
| 22 | #include <media/media-device.h> | ||
| 23 | #include <media/media-entity.h> | ||
| 24 | #include <sound/asound.h> | ||
| 25 | |||
| 26 | struct media_ctl { | ||
| 27 | struct media_device *media_dev; | ||
| 28 | struct media_entity media_entity; | ||
| 29 | struct media_intf_devnode *intf_devnode; | ||
| 30 | struct media_link *intf_link; | ||
| 31 | struct media_pad media_pad; | ||
| 32 | struct media_pipeline media_pipe; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * One source pad each for SNDRV_PCM_STREAM_CAPTURE and | ||
| 37 | * SNDRV_PCM_STREAM_PLAYBACK. One for sink pad to link | ||
| 38 | * to AUDIO Source | ||
| 39 | */ | ||
| 40 | #define MEDIA_MIXER_PAD_MAX (SNDRV_PCM_STREAM_LAST + 2) | ||
| 41 | |||
| 42 | struct media_mixer_ctl { | ||
| 43 | struct media_device *media_dev; | ||
| 44 | struct media_entity media_entity; | ||
| 45 | struct media_intf_devnode *intf_devnode; | ||
| 46 | struct media_link *intf_link; | ||
| 47 | struct media_pad media_pad[MEDIA_MIXER_PAD_MAX]; | ||
| 48 | struct media_pipeline media_pipe; | ||
| 49 | }; | ||
| 50 | |||
| 51 | int media_snd_device_create(struct snd_usb_audio *chip, | ||
| 52 | struct usb_interface *iface); | ||
| 53 | void media_snd_device_delete(struct snd_usb_audio *chip); | ||
| 54 | int media_snd_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, | ||
| 55 | int stream); | ||
| 56 | void media_snd_stream_delete(struct snd_usb_substream *subs); | ||
| 57 | int media_snd_start_pipeline(struct snd_usb_substream *subs); | ||
| 58 | void media_snd_stop_pipeline(struct snd_usb_substream *subs); | ||
| 59 | #else | ||
| 60 | static inline int media_snd_device_create(struct snd_usb_audio *chip, | ||
| 61 | struct usb_interface *iface) | ||
| 62 | { return 0; } | ||
| 63 | static inline void media_snd_device_delete(struct snd_usb_audio *chip) { } | ||
| 64 | static inline int media_snd_stream_init(struct snd_usb_substream *subs, | ||
| 65 | struct snd_pcm *pcm, int stream) | ||
| 66 | { return 0; } | ||
| 67 | static inline void media_snd_stream_delete(struct snd_usb_substream *subs) { } | ||
| 68 | static inline int media_snd_start_pipeline(struct snd_usb_substream *subs) | ||
| 69 | { return 0; } | ||
| 70 | static inline void media_snd_stop_pipeline(struct snd_usb_substream *subs) { } | ||
| 71 | #endif | ||
| 72 | #endif /* __MEDIA_H */ | ||
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index f3789446ab9c..3417ef347e40 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
| @@ -3,8 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #include <sound/info.h> | 4 | #include <sound/info.h> |
| 5 | 5 | ||
| 6 | struct media_mixer_ctl; | ||
| 7 | |||
| 8 | struct usb_mixer_interface { | 6 | struct usb_mixer_interface { |
| 9 | struct snd_usb_audio *chip; | 7 | struct snd_usb_audio *chip; |
| 10 | struct usb_host_interface *hostif; | 8 | struct usb_host_interface *hostif; |
| @@ -24,7 +22,6 @@ struct usb_mixer_interface { | |||
| 24 | struct urb *rc_urb; | 22 | struct urb *rc_urb; |
| 25 | struct usb_ctrlrequest *rc_setup_packet; | 23 | struct usb_ctrlrequest *rc_setup_packet; |
| 26 | u8 rc_buffer[6]; | 24 | u8 rc_buffer[6]; |
| 27 | struct media_mixer_ctl *media_mixer_ctl; | ||
| 28 | }; | 25 | }; |
| 29 | 26 | ||
| 30 | #define MAX_CHANNELS 16 /* max logical channels */ | 27 | #define MAX_CHANNELS 16 /* max logical channels */ |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 0e4e0640c504..44d178ee9177 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include "pcm.h" | 35 | #include "pcm.h" |
| 36 | #include "clock.h" | 36 | #include "clock.h" |
| 37 | #include "power.h" | 37 | #include "power.h" |
| 38 | #include "media.h" | ||
| 39 | 38 | ||
| 40 | #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 | 39 | #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 |
| 41 | #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 | 40 | #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 |
| @@ -718,14 +717,10 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 718 | struct audioformat *fmt; | 717 | struct audioformat *fmt; |
| 719 | int ret; | 718 | int ret; |
| 720 | 719 | ||
| 721 | ret = media_snd_start_pipeline(subs); | ||
| 722 | if (ret) | ||
| 723 | return ret; | ||
| 724 | |||
| 725 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 720 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
| 726 | params_buffer_bytes(hw_params)); | 721 | params_buffer_bytes(hw_params)); |
| 727 | if (ret < 0) | 722 | if (ret < 0) |
| 728 | goto err_ret; | 723 | return ret; |
| 729 | 724 | ||
| 730 | subs->pcm_format = params_format(hw_params); | 725 | subs->pcm_format = params_format(hw_params); |
| 731 | subs->period_bytes = params_period_bytes(hw_params); | 726 | subs->period_bytes = params_period_bytes(hw_params); |
| @@ -739,27 +734,22 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 739 | dev_dbg(&subs->dev->dev, | 734 | dev_dbg(&subs->dev->dev, |
| 740 | "cannot set format: format = %#x, rate = %d, channels = %d\n", | 735 | "cannot set format: format = %#x, rate = %d, channels = %d\n", |
| 741 | subs->pcm_format, subs->cur_rate, subs->channels); | 736 | subs->pcm_format, subs->cur_rate, subs->channels); |
| 742 | ret = -EINVAL; | 737 | return -EINVAL; |
| 743 | goto err_ret; | ||
| 744 | } | 738 | } |
| 745 | 739 | ||
| 746 | ret = snd_usb_lock_shutdown(subs->stream->chip); | 740 | ret = snd_usb_lock_shutdown(subs->stream->chip); |
| 747 | if (ret < 0) | 741 | if (ret < 0) |
| 748 | goto err_ret; | 742 | return ret; |
| 749 | ret = set_format(subs, fmt); | 743 | ret = set_format(subs, fmt); |
| 750 | snd_usb_unlock_shutdown(subs->stream->chip); | 744 | snd_usb_unlock_shutdown(subs->stream->chip); |
| 751 | if (ret < 0) | 745 | if (ret < 0) |
| 752 | goto err_ret; | 746 | return ret; |
| 753 | 747 | ||
| 754 | subs->interface = fmt->iface; | 748 | subs->interface = fmt->iface; |
| 755 | subs->altset_idx = fmt->altset_idx; | 749 | subs->altset_idx = fmt->altset_idx; |
| 756 | subs->need_setup_ep = true; | 750 | subs->need_setup_ep = true; |
| 757 | 751 | ||
| 758 | return 0; | 752 | return 0; |
| 759 | |||
| 760 | err_ret: | ||
| 761 | media_snd_stop_pipeline(subs); | ||
| 762 | return ret; | ||
| 763 | } | 753 | } |
| 764 | 754 | ||
| 765 | /* | 755 | /* |
| @@ -771,7 +761,6 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) | |||
| 771 | { | 761 | { |
| 772 | struct snd_usb_substream *subs = substream->runtime->private_data; | 762 | struct snd_usb_substream *subs = substream->runtime->private_data; |
| 773 | 763 | ||
| 774 | media_snd_stop_pipeline(subs); | ||
| 775 | subs->cur_audiofmt = NULL; | 764 | subs->cur_audiofmt = NULL; |
| 776 | subs->cur_rate = 0; | 765 | subs->cur_rate = 0; |
| 777 | subs->period_bytes = 0; | 766 | subs->period_bytes = 0; |
| @@ -1232,7 +1221,6 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
| 1232 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 1221 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
| 1233 | struct snd_pcm_runtime *runtime = substream->runtime; | 1222 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1234 | struct snd_usb_substream *subs = &as->substream[direction]; | 1223 | struct snd_usb_substream *subs = &as->substream[direction]; |
| 1235 | int ret; | ||
| 1236 | 1224 | ||
| 1237 | subs->interface = -1; | 1225 | subs->interface = -1; |
| 1238 | subs->altset_idx = 0; | 1226 | subs->altset_idx = 0; |
| @@ -1246,12 +1234,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
| 1246 | subs->dsd_dop.channel = 0; | 1234 | subs->dsd_dop.channel = 0; |
| 1247 | subs->dsd_dop.marker = 1; | 1235 | subs->dsd_dop.marker = 1; |
| 1248 | 1236 | ||
| 1249 | ret = setup_hw_info(runtime, subs); | 1237 | return setup_hw_info(runtime, subs); |
| 1250 | if (ret == 0) | ||
| 1251 | ret = media_snd_stream_init(subs, as->pcm, direction); | ||
| 1252 | if (ret) | ||
| 1253 | snd_usb_autosuspend(subs->stream->chip); | ||
| 1254 | return ret; | ||
| 1255 | } | 1238 | } |
| 1256 | 1239 | ||
| 1257 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | 1240 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) |
| @@ -1260,7 +1243,6 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | |||
| 1260 | struct snd_usb_substream *subs = &as->substream[direction]; | 1243 | struct snd_usb_substream *subs = &as->substream[direction]; |
| 1261 | 1244 | ||
| 1262 | stop_endpoints(subs, true); | 1245 | stop_endpoints(subs, true); |
| 1263 | media_snd_stop_pipeline(subs); | ||
| 1264 | 1246 | ||
| 1265 | if (subs->interface >= 0 && | 1247 | if (subs->interface >= 0 && |
| 1266 | !snd_usb_lock_shutdown(subs->stream->chip)) { | 1248 | !snd_usb_lock_shutdown(subs->stream->chip)) { |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 9d087b19c70c..c60a776e815d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -2886,7 +2886,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 2886 | .product_name = pname, \ | 2886 | .product_name = pname, \ |
| 2887 | .ifnum = QUIRK_ANY_INTERFACE, \ | 2887 | .ifnum = QUIRK_ANY_INTERFACE, \ |
| 2888 | .type = QUIRK_AUDIO_ALIGN_TRANSFER, \ | 2888 | .type = QUIRK_AUDIO_ALIGN_TRANSFER, \ |
| 2889 | .media_device = 1, \ | ||
| 2890 | } \ | 2889 | } \ |
| 2891 | } | 2890 | } |
| 2892 | 2891 | ||
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 6fe7f210bd4e..8e9548bc1f1a 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
| @@ -36,7 +36,6 @@ | |||
| 36 | #include "format.h" | 36 | #include "format.h" |
| 37 | #include "clock.h" | 37 | #include "clock.h" |
| 38 | #include "stream.h" | 38 | #include "stream.h" |
| 39 | #include "media.h" | ||
| 40 | 39 | ||
| 41 | /* | 40 | /* |
| 42 | * free a substream | 41 | * free a substream |
| @@ -53,7 +52,6 @@ static void free_substream(struct snd_usb_substream *subs) | |||
| 53 | kfree(fp); | 52 | kfree(fp); |
| 54 | } | 53 | } |
| 55 | kfree(subs->rate_list.list); | 54 | kfree(subs->rate_list.list); |
| 56 | media_snd_stream_delete(subs); | ||
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | 57 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index a161c7c1b126..b665d85555cb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -30,9 +30,6 @@ | |||
| 30 | * | 30 | * |
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | struct media_device; | ||
| 34 | struct media_intf_devnode; | ||
| 35 | |||
| 36 | struct snd_usb_audio { | 33 | struct snd_usb_audio { |
| 37 | int index; | 34 | int index; |
| 38 | struct usb_device *dev; | 35 | struct usb_device *dev; |
| @@ -63,8 +60,6 @@ struct snd_usb_audio { | |||
| 63 | bool autoclock; /* from the 'autoclock' module param */ | 60 | bool autoclock; /* from the 'autoclock' module param */ |
| 64 | 61 | ||
| 65 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | 62 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ |
| 66 | struct media_device *media_dev; | ||
| 67 | struct media_intf_devnode *ctl_intf_media_devnode; | ||
| 68 | }; | 63 | }; |
| 69 | 64 | ||
| 70 | #define usb_audio_err(chip, fmt, args...) \ | 65 | #define usb_audio_err(chip, fmt, args...) \ |
| @@ -115,7 +110,6 @@ struct snd_usb_audio_quirk { | |||
| 115 | const char *product_name; | 110 | const char *product_name; |
| 116 | int16_t ifnum; | 111 | int16_t ifnum; |
| 117 | uint16_t type; | 112 | uint16_t type; |
| 118 | bool media_device; | ||
| 119 | const void *data; | 113 | const void *data; |
| 120 | }; | 114 | }; |
| 121 | 115 | ||
