diff options
Diffstat (limited to 'drivers/media')
246 files changed, 3446 insertions, 1218 deletions
diff --git a/drivers/media/cec/i2c/ch7322.c b/drivers/media/cec/i2c/ch7322.c index 34fad7123704..439c15bc9e44 100644 --- a/drivers/media/cec/i2c/ch7322.c +++ b/drivers/media/cec/i2c/ch7322.c @@ -591,7 +591,7 @@ static struct i2c_driver ch7322_i2c_driver = { .name = "ch7322", .of_match_table = of_match_ptr(ch7322_of_match), }, - .probe_new = ch7322_probe, + .probe = ch7322_probe, .remove = ch7322_remove, }; diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c index bcb957883044..27c53eed8fe3 100644 --- a/drivers/media/common/saa7146/saa7146_core.c +++ b/drivers/media/common/saa7146/saa7146_core.c @@ -133,8 +133,8 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) ****************************************************************************/ /* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c - make sure virt has been allocated with vmalloc_32(), otherwise the BUG() - may be triggered on highmem machines */ + make sure virt has been allocated with vmalloc_32(), otherwise return NULL + on highmem machines */ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) { struct scatterlist *sglist; @@ -150,7 +150,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) if (NULL == pg) goto err; if (WARN_ON(PageHighMem(pg))) - return NULL; + goto err; sg_set_page(&sglist[i], pg, PAGE_SIZE, 0); } return sglist; diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index a4b05e366ccc..305bb21d843c 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -61,21 +61,21 @@ static const char * const dnames[] = { #define DVB_MAX_IDS 4 static const u8 minor_type[] = { - [DVB_DEVICE_VIDEO] = 0, - [DVB_DEVICE_AUDIO] = 1, - [DVB_DEVICE_SEC] = 2, - [DVB_DEVICE_FRONTEND] = 3, - [DVB_DEVICE_DEMUX] = 4, - [DVB_DEVICE_DVR] = 5, - [DVB_DEVICE_CA] = 6, - [DVB_DEVICE_NET] = 7, - [DVB_DEVICE_OSD] = 8, + [DVB_DEVICE_VIDEO] = 0, + [DVB_DEVICE_AUDIO] = 1, + [DVB_DEVICE_SEC] = 2, + [DVB_DEVICE_FRONTEND] = 3, + [DVB_DEVICE_DEMUX] = 4, + [DVB_DEVICE_DVR] = 5, + [DVB_DEVICE_CA] = 6, + [DVB_DEVICE_NET] = 7, + [DVB_DEVICE_OSD] = 8, }; #define nums2minor(num, type, id) \ - (((num) << 6) | ((id) << 4) | minor_type[type]) + (((num) << 6) | ((id) << 4) | minor_type[type]) -#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) +#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS * 64) #endif static struct class *dvb_class; @@ -112,9 +112,7 @@ fail: return -ENODEV; } - -static const struct file_operations dvb_device_fops = -{ +static const struct file_operations dvb_device_fops = { .owner = THIS_MODULE, .open = dvb_device_open, .llseek = noop_llseek, @@ -147,7 +145,6 @@ int dvb_generic_open(struct inode *inode, struct file *file) } EXPORT_SYMBOL(dvb_generic_open); - int dvb_generic_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; @@ -155,11 +152,10 @@ int dvb_generic_release(struct inode *inode, struct file *file) if (!dvbdev) return -ENODEV; - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) dvbdev->readers++; - } else { + else dvbdev->writers++; - } dvbdev->users++; @@ -169,7 +165,6 @@ int dvb_generic_release(struct inode *inode, struct file *file) } EXPORT_SYMBOL(dvb_generic_release); - long dvb_generic_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -185,13 +180,13 @@ long dvb_generic_ioctl(struct file *file, } EXPORT_SYMBOL(dvb_generic_ioctl); - -static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) +static int dvbdev_get_free_id(struct dvb_adapter *adap, int type) { u32 id = 0; while (id < DVB_MAX_IDS) { struct dvb_device *dev; + list_for_each_entry(dev, &adap->device_list, list_head) if (dev->type == type && dev->id == id) goto skip; @@ -245,7 +240,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev) #if defined(CONFIG_MEDIA_CONTROLLER_DVB) static int dvb_create_tsout_entity(struct dvb_device *dvbdev, - const char *name, int npads) + const char *name, int npads) { int i; @@ -387,7 +382,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, static int dvb_register_media_device(struct dvb_device *dvbdev, int type, int minor, - unsigned demux_sink_pads) + unsigned int demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) struct media_link *link; @@ -462,7 +457,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_lock(&dvbdev_register_lock); - if ((id = dvbdev_get_free_id (adap, type)) < 0) { + id = dvbdev_get_free_id(adap, type); + if (id < 0) { mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; pr_err("%s: couldn't find free device id\n", __func__); @@ -470,7 +466,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, } *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL); - if (!dvbdev){ + if (!dvbdev) { mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } @@ -482,14 +478,13 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, */ list_for_each_entry(node, &dvbdevfops_list, list_head) { if (node->fops->owner == adap->module && - node->type == type && - node->template == template) { + node->type == type && node->template == template) { dvbdevfops = node->fops; break; } } - if (dvbdevfops == NULL) { + if (!dvbdevfops) { dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); if (!dvbdevfops) { kfree(dvbdev); @@ -497,7 +492,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; } - new_node = kzalloc(sizeof(struct dvbdevfops_node), GFP_KERNEL); + new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); if (!new_node) { kfree(dvbdevfops); kfree(dvbdev); @@ -508,7 +503,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, new_node->fops = dvbdevfops; new_node->type = type; new_node->template = template; - list_add_tail (&new_node->list_head, &dvbdevfops_list); + list_add_tail(&new_node->list_head, &dvbdevfops_list); } memcpy(dvbdev, template, sizeof(struct dvb_device)); @@ -518,21 +513,21 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->adapter = adap; dvbdev->priv = priv; dvbdev->fops = dvbdevfops; - init_waitqueue_head (&dvbdev->wait_queue); + init_waitqueue_head(&dvbdev->wait_queue); dvbdevfops->owner = adap->module; - list_add_tail (&dvbdev->list_head, &adap->device_list); + list_add_tail(&dvbdev->list_head, &adap->device_list); down_write(&minor_rwsem); #ifdef CONFIG_DVB_DYNAMIC_MINORS for (minor = 0; minor < MAX_DVB_MINORS; minor++) - if (dvb_minors[minor] == NULL) + if (!dvb_minors[minor]) break; if (minor == MAX_DVB_MINORS) { if (new_node) { - list_del (&new_node->list_head); + list_del(&new_node->list_head); kfree(dvbdevfops); kfree(new_node); } - list_del (&dvbdev->list_head); + list_del(&dvbdev->list_head); kfree(dvbdev); up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); @@ -547,14 +542,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); if (ret) { pr_err("%s: dvb_register_media_device failed to create the mediagraph\n", - __func__); + __func__); if (new_node) { - list_del (&new_node->list_head); + list_del(&new_node->list_head); kfree(dvbdevfops); kfree(new_node); } dvb_media_device_free(dvbdev); - list_del (&dvbdev->list_head); + list_del(&dvbdev->list_head); kfree(dvbdev); mutex_unlock(&dvbdev_register_lock); return ret; @@ -567,12 +562,12 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); if (new_node) { - list_del (&new_node->list_head); + list_del(&new_node->list_head); kfree(dvbdevfops); kfree(new_node); } dvb_media_device_free(dvbdev); - list_del (&dvbdev->list_head); + list_del(&dvbdev->list_head); kfree(dvbdev); mutex_unlock(&dvbdev_register_lock); return PTR_ERR(clsdev); @@ -586,7 +581,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, } EXPORT_SYMBOL(dvb_register_device); - void dvb_remove_device(struct dvb_device *dvbdev) { if (!dvbdev) @@ -601,19 +595,17 @@ void dvb_remove_device(struct dvb_device *dvbdev) device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); - list_del (&dvbdev->list_head); + list_del(&dvbdev->list_head); } EXPORT_SYMBOL(dvb_remove_device); - static void dvb_free_device(struct kref *ref) { struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref); - kfree (dvbdev); + kfree(dvbdev); } - struct dvb_device *dvb_device_get(struct dvb_device *dvbdev) { kref_get(&dvbdev->ref); @@ -621,14 +613,12 @@ struct dvb_device *dvb_device_get(struct dvb_device *dvbdev) } EXPORT_SYMBOL(dvb_device_get); - void dvb_device_put(struct dvb_device *dvbdev) { if (dvbdev) kref_put(&dvbdev->ref, dvb_free_device); } - void dvb_unregister_device(struct dvb_device *dvbdev) { dvb_remove_device(dvbdev); @@ -636,7 +626,6 @@ void dvb_unregister_device(struct dvb_device *dvbdev) } EXPORT_SYMBOL(dvb_unregister_device); - #ifdef CONFIG_MEDIA_CONTROLLER_DVB static int dvb_create_io_intf_links(struct dvb_adapter *adap, @@ -669,9 +658,9 @@ int dvb_create_media_graph(struct dvb_adapter *adap, struct media_entity *demux = NULL, *ca = NULL; struct media_link *link; struct media_interface *intf; - unsigned demux_pad = 0; - unsigned dvr_pad = 0; - unsigned ntuner = 0, ndemod = 0; + unsigned int demux_pad = 0; + unsigned int dvr_pad = 0; + unsigned int ntuner = 0, ndemod = 0; int ret, pad_source, pad_sink; static const char *connector_name = "Television"; @@ -741,7 +730,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, MEDIA_LNK_FL_ENABLED, false); } else { - pad_sink = media_get_pad_index(tuner, true, + pad_sink = media_get_pad_index(tuner, MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_sink < 0) return -EINVAL; @@ -759,7 +748,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, if (ntuner && ndemod) { /* NOTE: first found tuner source pad presumed correct */ - pad_source = media_get_pad_index(tuner, false, + pad_source = media_get_pad_index(tuner, MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_ANALOG); if (pad_source < 0) return -EINVAL; @@ -795,18 +784,18 @@ int dvb_create_media_graph(struct dvb_adapter *adap, media_device_for_each_entity(entity, mdev) { if (entity->function == MEDIA_ENT_F_IO_DTV) { if (!strncmp(entity->name, DVR_TSOUT, - strlen(DVR_TSOUT))) { + strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux, - ++dvr_pad, - entity, 0, 0); + ++dvr_pad, + entity, 0, 0); if (ret) return ret; } if (!strncmp(entity->name, DEMUX_TSOUT, - strlen(DEMUX_TSOUT))) { + strlen(DEMUX_TSOUT))) { ret = media_create_pad_link(demux, - ++demux_pad, - entity, 0, 0); + ++demux_pad, + entity, 0, 0); if (ret) return ret; } @@ -864,8 +853,10 @@ EXPORT_SYMBOL_GPL(dvb_create_media_graph); static int dvbdev_check_free_adapter_num(int num) { struct list_head *entry; + list_for_each(entry, &dvb_adapter_list) { struct dvb_adapter *adap; + adap = list_entry(entry, struct dvb_adapter, list_head); if (adap->num == num) return 0; @@ -873,7 +864,7 @@ static int dvbdev_check_free_adapter_num(int num) return 1; } -static int dvbdev_get_free_adapter_num (void) +static int dvbdev_get_free_adapter_num(void) { int num = 0; @@ -886,7 +877,6 @@ static int dvbdev_get_free_adapter_num (void) return -ENFILE; } - int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device, short *adapter_nums) @@ -913,8 +903,8 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, return -ENFILE; } - memset (adap, 0, sizeof(struct dvb_adapter)); - INIT_LIST_HEAD (&adap->device_list); + memset(adap, 0, sizeof(struct dvb_adapter)); + INIT_LIST_HEAD(&adap->device_list); pr_info("DVB: registering new adapter (%s)\n", name); @@ -924,13 +914,13 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, adap->device = device; adap->mfe_shared = 0; adap->mfe_dvbdev = NULL; - mutex_init (&adap->mfe_lock); + mutex_init(&adap->mfe_lock); #ifdef CONFIG_MEDIA_CONTROLLER_DVB mutex_init(&adap->mdev_lock); #endif - list_add_tail (&adap->list_head, &dvb_adapter_list); + list_add_tail(&adap->list_head, &dvb_adapter_list); mutex_unlock(&dvbdev_register_lock); @@ -938,25 +928,26 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, } EXPORT_SYMBOL(dvb_register_adapter); - int dvb_unregister_adapter(struct dvb_adapter *adap) { mutex_lock(&dvbdev_register_lock); - list_del (&adap->list_head); + list_del(&adap->list_head); mutex_unlock(&dvbdev_register_lock); return 0; } EXPORT_SYMBOL(dvb_unregister_adapter); -/* if the miracle happens and "generic_usercopy()" is included into - the kernel, then this can vanish. please don't make the mistake and - define this as video_usercopy(). this will introduce a dependency - to the v4l "videodev.o" module, which is unnecessary for some - cards (ie. the budget dvb-cards don't need the v4l module...) */ +/* + * if the miracle happens and "generic_usercopy()" is included into + * the kernel, then this can vanish. please don't make the mistake and + * define this as video_usercopy(). this will introduce a dependency + * to the v4l "videodev.o" module, which is unnecessary for some + * cards (ie. the budget dvb-cards don't need the v4l module...) + */ int dvb_usercopy(struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct file *file, - unsigned int cmd, void *arg)) + unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, + unsigned int cmd, void *arg)) { char sbuf[128]; void *mbuf = NULL; @@ -970,7 +961,7 @@ int dvb_usercopy(struct file *file, * For this command, the pointer is actually an integer * argument. */ - parg = (void *) arg; + parg = (void *)arg; break; case _IOC_READ: /* some v4l ioctls are marked wrong ... */ case _IOC_WRITE: @@ -980,7 +971,7 @@ int dvb_usercopy(struct file *file, } else { /* too big to allocate from stack */ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); - if (NULL == mbuf) + if (!mbuf) return -ENOMEM; parg = mbuf; } @@ -992,15 +983,15 @@ int dvb_usercopy(struct file *file, } /* call driver */ - if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) + err = func(file, cmd, parg); + if (err == -ENOIOCTLCMD) err = -ENOTTY; if (err < 0) goto out; /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { + switch (_IOC_DIR(cmd)) { case _IOC_READ: case (_IOC_WRITE | _IOC_READ): if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) @@ -1080,19 +1071,20 @@ static char *dvb_devnode(const struct device *dev, umode_t *mode) dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); } - static int __init init_dvbdev(void) { int retval; dev_t dev = MKDEV(DVB_MAJOR, 0); - if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { + retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB"); + if (retval != 0) { pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR); return retval; } cdev_init(&dvb_device_cdev, &dvb_device_fops); - if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { + retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS); + if (retval != 0) { pr_err("dvb-core: unable register character device\n"); goto error; } @@ -1112,7 +1104,6 @@ error: return retval; } - static void __exit exit_dvbdev(void) { struct dvbdevfops_node *node, *next; @@ -1122,7 +1113,7 @@ static void __exit exit_dvbdev(void) unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) { - list_del (&node->list_head); + list_del(&node->list_head); kfree(node->fops); kfree(node); } diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c index cca7cbdd4c7c..f39887c04978 100644 --- a/drivers/media/dvb-frontends/a8293.c +++ b/drivers/media/dvb-frontends/a8293.c @@ -266,7 +266,7 @@ static struct i2c_driver a8293_driver = { .name = "a8293", .suppress_bind_attrs = true, }, - .probe_new = a8293_probe, + .probe = a8293_probe, .remove = a8293_remove, .id_table = a8293_id_table, }; diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 206758a73ae2..a829c89792a4 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -1563,7 +1563,7 @@ static struct i2c_driver af9013_driver = { .name = "af9013", .suppress_bind_attrs = true, }, - .probe_new = af9013_probe, + .probe = af9013_probe, .remove = af9013_remove, .id_table = af9013_id_table, }; diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index a30773f62006..49b7b04a7899 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -1183,7 +1183,7 @@ static struct i2c_driver af9033_driver = { .name = "af9033", .suppress_bind_attrs = true, }, - .probe_new = af9033_probe, + .probe = af9033_probe, .remove = af9033_remove, .id_table = af9033_id_table, }; diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 0f748cf46089..acc27376c246 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -776,7 +776,7 @@ static struct i2c_driver au8522_driver = { .driver = { .name = "au8522", }, - .probe_new = au8522_probe, + .probe = au8522_probe, .remove = au8522_remove, .id_table = au8522_id, }; diff --git a/drivers/media/dvb-frontends/cxd2099.c b/drivers/media/dvb-frontends/cxd2099.c index c0967ad95220..3f3b85743666 100644 --- a/drivers/media/dvb-frontends/cxd2099.c +++ b/drivers/media/dvb-frontends/cxd2099.c @@ -681,7 +681,7 @@ static struct i2c_driver cxd2099_driver = { .driver = { .name = "cxd2099", }, - .probe_new = cxd2099_probe, + .probe = cxd2099_probe, .remove = cxd2099_remove, .id_table = cxd2099_id, }; diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 47aa40967171..d7ee294c6833 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c @@ -733,7 +733,7 @@ static struct i2c_driver cxd2820r_driver = { .name = "cxd2820r", .suppress_bind_attrs = true, }, - .probe_new = cxd2820r_probe, + .probe = cxd2820r_probe, .remove = cxd2820r_remove, .id_table = cxd2820r_id_table, }; diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index e35e00db7dbb..90cb41eacf98 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -942,7 +942,7 @@ static struct i2c_driver dvb_pll_driver = { .driver = { .name = "dvb_pll", }, - .probe_new = dvb_pll_probe, + .probe = dvb_pll_probe, .remove = dvb_pll_remove, .id_table = dvb_pll_id, }; diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index e4bbf6a51a2b..68c1a3e0e2ba 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c @@ -1110,7 +1110,7 @@ static struct i2c_driver helene_driver = { .driver = { .name = "helene", }, - .probe_new = helene_probe, + .probe = helene_probe, .id_table = helene_id, }; module_i2c_driver(helene_driver); diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 6bf723b5ffad..70258884126b 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -2249,7 +2249,7 @@ static struct i2c_driver lgdt3306a_driver = { .name = "lgdt3306a", .suppress_bind_attrs = true, }, - .probe_new = lgdt3306a_probe, + .probe = lgdt3306a_probe, .remove = lgdt3306a_remove, .id_table = lgdt3306a_id_table, }; diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c index 1d6932d8e497..83565209c3b1 100644 --- a/drivers/media/dvb-frontends/lgdt330x.c +++ b/drivers/media/dvb-frontends/lgdt330x.c @@ -993,7 +993,7 @@ static struct i2c_driver lgdt330x_driver = { .name = "lgdt330x", .suppress_bind_attrs = true, }, - .probe_new = lgdt330x_probe, + .probe = lgdt330x_probe, .remove = lgdt330x_remove, .id_table = lgdt330x_id_table, }; diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index f26508b217ee..cf49ac56a37e 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1941,7 +1941,7 @@ static struct i2c_driver m88ds3103_driver = { .name = "m88ds3103", .suppress_bind_attrs = true, }, - .probe_new = m88ds3103_probe, + .probe = m88ds3103_probe, .remove = m88ds3103_remove, .id_table = m88ds3103_id_table, }; diff --git a/drivers/media/dvb-frontends/mn88443x.c b/drivers/media/dvb-frontends/mn88443x.c index 0782f8377eb2..2ce5692bc22c 100644 --- a/drivers/media/dvb-frontends/mn88443x.c +++ b/drivers/media/dvb-frontends/mn88443x.c @@ -800,7 +800,7 @@ static struct i2c_driver mn88443x_driver = { .name = "mn88443x", .of_match_table = mn88443x_of_match, }, - .probe_new = mn88443x_probe, + .probe = mn88443x_probe, .remove = mn88443x_remove, .id_table = mn88443x_i2c_id, }; diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index 4a71f1c6371a..73d1e52de569 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -718,7 +718,7 @@ static struct i2c_driver mn88472_driver = { .name = "mn88472", .suppress_bind_attrs = true, }, - .probe_new = mn88472_probe, + .probe = mn88472_probe, .remove = mn88472_remove, .id_table = mn88472_id_table, }; diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index 205b14ae584e..eb50591c0e7a 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -753,7 +753,7 @@ static struct i2c_driver mn88473_driver = { .name = "mn88473", .suppress_bind_attrs = true, }, - .probe_new = mn88473_probe, + .probe = mn88473_probe, .remove = mn88473_remove, .id_table = mn88473_id_table, }; diff --git a/drivers/media/dvb-frontends/mxl692.c b/drivers/media/dvb-frontends/mxl692.c index 9858e11943a0..2a31bde2630f 100644 --- a/drivers/media/dvb-frontends/mxl692.c +++ b/drivers/media/dvb-frontends/mxl692.c @@ -1355,7 +1355,7 @@ static struct i2c_driver mxl692_driver = { .driver = { .name = "mxl692", }, - .probe_new = mxl692_probe, + .probe = mxl692_probe, .remove = mxl692_remove, .id_table = mxl692_id_table, }; diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index db3254950147..35c969fd2cb5 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -886,7 +886,7 @@ static struct i2c_driver rtl2830_driver = { .name = "rtl2830", .suppress_bind_attrs = true, }, - .probe_new = rtl2830_probe, + .probe = rtl2830_probe, .remove = rtl2830_remove, .id_table = rtl2830_id_table, }; diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 900d4db8b922..601cf45c3935 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -1135,7 +1135,7 @@ static struct i2c_driver rtl2832_driver = { .name = "rtl2832", .suppress_bind_attrs = true, }, - .probe_new = rtl2832_probe, + .probe = rtl2832_probe, .remove = rtl2832_remove, .id_table = rtl2832_id_table, }; diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index cc07e965c34c..72810efd1a96 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -1292,7 +1292,7 @@ static struct i2c_driver si2165_driver = { .driver = { .name = "si2165", }, - .probe_new = si2165_probe, + .probe = si2165_probe, .remove = si2165_remove, .id_table = si2165_id_table, }; diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 2a0e108c5eb0..dae1f2153e8b 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -798,7 +798,7 @@ static struct i2c_driver si2168_driver = { .name = "si2168", .suppress_bind_attrs = true, }, - .probe_new = si2168_probe, + .probe = si2168_probe, .remove = si2168_remove, .id_table = si2168_id_table, }; diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index 3395f6b5b948..4d7d0b8b51b4 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c @@ -416,7 +416,7 @@ static struct i2c_driver sp2_driver = { .driver = { .name = "sp2", }, - .probe_new = sp2_probe, + .probe = sp2_probe, .remove = sp2_remove, .id_table = sp2_id, }; diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 9bde0ad6f26e..a07dc5fdeb3d 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -5084,7 +5084,7 @@ static struct i2c_driver stv090x_driver = { .name = "stv090x", .suppress_bind_attrs = true, }, - .probe_new = stv090x_probe, + .probe = stv090x_probe, .remove = stv090x_remove, .id_table = stv090x_id_table, }; diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index b2f456116c60..11653f846c12 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c @@ -480,7 +480,7 @@ static struct i2c_driver stv6110x_driver = { .name = "stv6110x", .suppress_bind_attrs = true, }, - .probe_new = stv6110x_probe, + .probe = stv6110x_probe, .remove = stv6110x_remove, .id_table = stv6110x_id_table, }; diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index 77a991bf4713..879f028f9682 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -840,7 +840,7 @@ static struct i2c_driver tc90522_driver = { .driver = { .name = "tc90522", }, - .probe_new = tc90522_probe, + .probe = tc90522_probe, .remove = tc90522_remove, .id_table = tc90522_id, }; diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index c8e5617d08c0..6640851d8bbc 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -1240,7 +1240,7 @@ static struct i2c_driver tda10071_driver = { .name = "tda10071", .suppress_bind_attrs = true, }, - .probe_new = tda10071_probe, + .probe = tda10071_probe, .remove = tda10071_remove, .id_table = tda10071_id_table, }; diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index c28fee7509cd..f5b60f827697 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -720,7 +720,7 @@ static struct i2c_driver ts2020_driver = { .driver = { .name = "ts2020", }, - .probe_new = ts2020_probe, + .probe = ts2020_probe, .remove = ts2020_remove, .id_table = ts2020_id_table, }; diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 256d55bb2b1d..cf675ac4b132 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -338,6 +338,19 @@ config VIDEO_OG01A1B To compile this driver as a module, choose M here: the module will be called og01a1b. +config VIDEO_OV01A10 + tristate "OmniVision OV01A10 sensor support" + depends on VIDEO_DEV && I2C + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the OmniVision + OV01A10 camera. + + To compile this driver as a module, choose M here: the + module will be called ov01a10. + config VIDEO_OV02A10 tristate "OmniVision OV02A10 sensor support" depends on VIDEO_DEV && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index b44dacf935f4..c743aeb5d1ad 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o +obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o obj-$(CONFIG_VIDEO_OV08X40) += ov08x40.o diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c index 44c26af49071..5f605b9be3b1 100644 --- a/drivers/media/i2c/ad5820.c +++ b/drivers/media/i2c/ad5820.c @@ -370,7 +370,7 @@ static struct i2c_driver ad5820_i2c_driver = { .pm = &ad5820_pm, .of_match_table = ad5820_of_table, }, - .probe_new = ad5820_probe, + .probe = ad5820_probe, .remove = ad5820_remove, .id_table = ad5820_id_table, }; diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index a61a77de6eee..98ca417b8004 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -535,7 +535,7 @@ static struct i2c_driver adp1653_i2c_driver = { .name = ADP1653_NAME, .pm = &adp1653_pm_ops, }, - .probe_new = adp1653_probe, + .probe = adp1653_probe, .remove = adp1653_remove, .id_table = adp1653_id_table, }; diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index aa0f80e299b3..4a2b9fd9e2da 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -387,7 +387,7 @@ static struct i2c_driver adv7170_driver = { .driver = { .name = "adv7170", }, - .probe_new = adv7170_probe, + .probe = adv7170_probe, .remove = adv7170_remove, .id_table = adv7170_id, }; diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index d9bea2b9ec33..e454cba4b026 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -442,7 +442,7 @@ static struct i2c_driver adv7175_driver = { .driver = { .name = "adv7175", }, - .probe_new = adv7175_probe, + .probe = adv7175_probe, .remove = adv7175_remove, .id_table = adv7175_id, }; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index a22402b7acff..99ba925e8ec8 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1610,7 +1610,7 @@ static struct i2c_driver adv7180_driver = { .pm = ADV7180_PM_OPS, .of_match_table = of_match_ptr(adv7180_of_id), }, - .probe_new = adv7180_probe, + .probe = adv7180_probe, .remove = adv7180_remove, .id_table = adv7180_id, }; diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index 98b63d79d33d..3659feafac69 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -631,7 +631,7 @@ static struct i2c_driver adv7183_driver = { .driver = { .name = "adv7183", }, - .probe_new = adv7183_probe, + .probe = adv7183_probe, .remove = adv7183_remove, .id_table = adv7183_id, }; diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index 7e84869d2434..ff21cd4744d3 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c @@ -521,7 +521,7 @@ static struct i2c_driver adv7343_driver = { .of_match_table = of_match_ptr(adv7343_of_match), .name = "adv7343", }, - .probe_new = adv7343_probe, + .probe = adv7343_probe, .remove = adv7343_remove, .id_table = adv7343_id, }; diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c index 61e916cbe651..7638af455cef 100644 --- a/drivers/media/i2c/adv7393.c +++ b/drivers/media/i2c/adv7393.c @@ -455,7 +455,7 @@ static struct i2c_driver adv7393_driver = { .driver = { .name = "adv7393", }, - .probe_new = adv7393_probe, + .probe = adv7393_probe, .remove = adv7393_remove, .id_table = adv7393_id, }; diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index 4498d78a2357..3eb6d5e8f082 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -847,7 +847,7 @@ static struct i2c_driver adv748x_driver = { .of_match_table = adv748x_of_table, .pm = &adv748x_pm_ops, }, - .probe_new = adv748x_probe, + .probe = adv748x_probe, .remove = adv748x_remove, }; diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c index 3999fa524cab..a9183d9282fd 100644 --- a/drivers/media/i2c/adv7511-v4l2.c +++ b/drivers/media/i2c/adv7511-v4l2.c @@ -1957,7 +1957,7 @@ static struct i2c_driver adv7511_driver = { .driver = { .name = "adv7511-v4l2", }, - .probe_new = adv7511_probe, + .probe = adv7511_probe, .remove = adv7511_remove, .id_table = adv7511_id, }; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 3d0898c4175e..b202a85fbeaa 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3689,7 +3689,7 @@ static struct i2c_driver adv76xx_driver = { .name = "adv7604", .of_match_table = of_match_ptr(adv76xx_of_id), }, - .probe_new = adv76xx_probe, + .probe = adv76xx_probe, .remove = adv76xx_remove, .id_table = adv76xx_i2c_id, }; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index cb8655574119..c1664a3620c8 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3619,7 +3619,7 @@ static struct i2c_driver adv7842_driver = { .driver = { .name = "adv7842", }, - .probe_new = adv7842_probe, + .probe = adv7842_probe, .remove = adv7842_remove, .id_table = adv7842_id, }; diff --git a/drivers/media/i2c/ak7375.c b/drivers/media/i2c/ak7375.c index e7cec45bc271..463b51d46320 100644 --- a/drivers/media/i2c/ak7375.c +++ b/drivers/media/i2c/ak7375.c @@ -306,7 +306,7 @@ static struct i2c_driver ak7375_i2c_driver = { .pm = &ak7375_pm_ops, .of_match_table = ak7375_of_table, }, - .probe_new = ak7375_probe, + .probe = ak7375_probe, .remove = ak7375_remove, }; module_i2c_driver(ak7375_i2c_driver); diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index 7c9ab76e2448..ce840adc2aa7 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -314,7 +314,7 @@ static struct i2c_driver ak881x_i2c_driver = { .driver = { .name = "ak881x", }, - .probe_new = ak881x_probe, + .probe = ak881x_probe, .remove = ak881x_remove, .id_table = ak881x_id, }; diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index 77f597571167..a4e39871e8f7 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -1198,7 +1198,7 @@ static struct i2c_driver ar0521_i2c_driver = { .pm = &ar0521_pm_ops, .of_match_table = ar0521_dt_ids, }, - .probe_new = ar0521_probe, + .probe = ar0521_probe, .remove = ar0521_remove, }; diff --git a/drivers/media/i2c/bt819.c b/drivers/media/i2c/bt819.c index 39f8a5361166..b4a25cc996dc 100644 --- a/drivers/media/i2c/bt819.c +++ b/drivers/media/i2c/bt819.c @@ -468,7 +468,7 @@ static struct i2c_driver bt819_driver = { .driver = { .name = "bt819", }, - .probe_new = bt819_probe, + .probe = bt819_probe, .remove = bt819_remove, .id_table = bt819_id, }; diff --git a/drivers/media/i2c/bt856.c b/drivers/media/i2c/bt856.c index d1d397b15b85..814acbd6a5a8 100644 --- a/drivers/media/i2c/bt856.c +++ b/drivers/media/i2c/bt856.c @@ -239,7 +239,7 @@ static struct i2c_driver bt856_driver = { .driver = { .name = "bt856", }, - .probe_new = bt856_probe, + .probe = bt856_probe, .remove = bt856_remove, .id_table = bt856_id, }; diff --git a/drivers/media/i2c/bt866.c b/drivers/media/i2c/bt866.c index d632d9a07f04..dada059cbce4 100644 --- a/drivers/media/i2c/bt866.c +++ b/drivers/media/i2c/bt866.c @@ -206,7 +206,7 @@ static struct i2c_driver bt866_driver = { .driver = { .name = "bt866", }, - .probe_new = bt866_probe, + .probe = bt866_probe, .remove = bt866_remove, .id_table = bt866_id, }; diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 559a415fd827..49e0d9a09530 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3731,7 +3731,7 @@ static struct i2c_driver ccs_i2c_driver = { .name = CCS_NAME, .pm = &ccs_pm_ops, }, - .probe_new = ccs_probe, + .probe = ccs_probe, .remove = ccs_remove, }; diff --git a/drivers/media/i2c/cs3308.c b/drivers/media/i2c/cs3308.c index a0b66c04fe25..61afa3d799d2 100644 --- a/drivers/media/i2c/cs3308.c +++ b/drivers/media/i2c/cs3308.c @@ -118,7 +118,7 @@ static struct i2c_driver cs3308_driver = { .driver = { .name = "cs3308", }, - .probe_new = cs3308_probe, + .probe = cs3308_probe, .remove = cs3308_remove, .id_table = cs3308_id, }; diff --git a/drivers/media/i2c/cs5345.c b/drivers/media/i2c/cs5345.c index ac4b5632fc46..3019a132e079 100644 --- a/drivers/media/i2c/cs5345.c +++ b/drivers/media/i2c/cs5345.c @@ -198,7 +198,7 @@ static struct i2c_driver cs5345_driver = { .driver = { .name = "cs5345", }, - .probe_new = cs5345_probe, + .probe = cs5345_probe, .remove = cs5345_remove, .id_table = cs5345_id, }; diff --git a/drivers/media/i2c/cs53l32a.c b/drivers/media/i2c/cs53l32a.c index 670f89de32d4..82881b79e730 100644 --- a/drivers/media/i2c/cs53l32a.c +++ b/drivers/media/i2c/cs53l32a.c @@ -209,7 +209,7 @@ static struct i2c_driver cs53l32a_driver = { .driver = { .name = "cs53l32a", }, - .probe_new = cs53l32a_probe, + .probe = cs53l32a_probe, .remove = cs53l32a_remove, .id_table = cs53l32a_id, }; diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 46cf422270b2..5aec25289062 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -6045,7 +6045,7 @@ static struct i2c_driver cx25840_driver = { .driver = { .name = "cx25840", }, - .probe_new = cx25840_probe, + .probe = cx25840_probe, .remove = cx25840_remove, .id_table = cx25840_id, }; diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index af59687383aa..cc09b32ede60 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -299,7 +299,7 @@ static struct i2c_driver dw9714_i2c_driver = { .pm = &dw9714_pm_ops, .of_match_table = dw9714_of_table, }, - .probe_new = dw9714_probe, + .probe = dw9714_probe, .remove = dw9714_remove, .id_table = dw9714_id_table, }; diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c index 83a3ee275bbe..daabbece8c7e 100644 --- a/drivers/media/i2c/dw9768.c +++ b/drivers/media/i2c/dw9768.c @@ -549,7 +549,7 @@ static struct i2c_driver dw9768_i2c_driver = { .pm = &dw9768_pm_ops, .of_match_table = dw9768_of_table, }, - .probe_new = dw9768_probe, + .probe = dw9768_probe, .remove = dw9768_remove, }; module_i2c_driver(dw9768_i2c_driver); diff --git a/drivers/media/i2c/dw9807-vcm.c b/drivers/media/i2c/dw9807-vcm.c index 3599720db7e9..4148009e0e01 100644 --- a/drivers/media/i2c/dw9807-vcm.c +++ b/drivers/media/i2c/dw9807-vcm.c @@ -310,7 +310,7 @@ static struct i2c_driver dw9807_i2c_driver = { .pm = &dw9807_pm_ops, .of_match_table = dw9807_of_table, }, - .probe_new = dw9807_probe, + .probe = dw9807_probe, .remove = dw9807_remove, }; diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c index ff9bb9fc97dd..d6fc843f9368 100644 --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -1501,7 +1501,7 @@ static struct i2c_driver et8ek8_i2c_driver = { .pm = &et8ek8_pm_ops, .of_match_table = et8ek8_of_table, }, - .probe_new = et8ek8_probe, + .probe = et8ek8_probe, .remove = __exit_p(et8ek8_remove), .id_table = et8ek8_id_table, }; diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index 7daefab35cf0..50e78f5b058c 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -1350,7 +1350,7 @@ static struct i2c_driver hi556_i2c_driver = { .pm = &hi556_pm_ops, .acpi_match_table = ACPI_PTR(hi556_acpi_ids), }, - .probe_new = hi556_probe, + .probe = hi556_probe, .remove = hi556_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c index 306dc35e925f..fa0038749a3b 100644 --- a/drivers/media/i2c/hi846.c +++ b/drivers/media/i2c/hi846.c @@ -1353,7 +1353,8 @@ static int hi846_set_ctrl(struct v4l2_ctrl *ctrl) exposure_max); } - if (!pm_runtime_get_if_in_use(&client->dev)) + ret = pm_runtime_get_if_in_use(&client->dev); + if (!ret || ret == -EAGAIN) return 0; switch (ctrl->id) { @@ -2189,7 +2190,7 @@ static struct i2c_driver hi846_i2c_driver = { .pm = &hi846_pm_ops, .of_match_table = hi846_of_match, }, - .probe_new = hi846_probe, + .probe = hi846_probe, .remove = hi846_remove, }; diff --git a/drivers/media/i2c/hi847.c b/drivers/media/i2c/hi847.c index 5a82b15a9513..7cdce392e137 100644 --- a/drivers/media/i2c/hi847.c +++ b/drivers/media/i2c/hi847.c @@ -2999,7 +2999,7 @@ static struct i2c_driver hi847_i2c_driver = { .pm = &hi847_pm_ops, .acpi_match_table = ACPI_PTR(hi847_acpi_ids), }, - .probe_new = hi847_probe, + .probe = hi847_probe, .remove = hi847_remove, }; diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c index 64c70ebf9869..3e870fa9ff79 100644 --- a/drivers/media/i2c/imx208.c +++ b/drivers/media/i2c/imx208.c @@ -1100,7 +1100,7 @@ static struct i2c_driver imx208_i2c_driver = { .pm = &imx208_pm_ops, .acpi_match_table = ACPI_PTR(imx208_acpi_ids), }, - .probe_new = imx208_probe, + .probe = imx208_probe, .remove = imx208_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 710c9fb515fd..2f9c8582f940 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -1112,7 +1112,7 @@ static struct i2c_driver imx214_i2c_driver = { .pm = &imx214_pm_ops, .name = "imx214", }, - .probe_new = imx214_probe, + .probe = imx214_probe, .remove = imx214_remove, }; diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index f9471c9e3a74..d737d5e9a4a6 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -1583,7 +1583,7 @@ static struct i2c_driver imx219_i2c_driver = { .of_match_table = imx219_dt_ids, .pm = &imx219_pm_ops, }, - .probe_new = imx219_probe, + .probe = imx219_probe, .remove = imx219_remove, }; diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 85d73b186111..e196565e846e 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -1395,7 +1395,7 @@ static struct i2c_driver imx258_i2c_driver = { .acpi_match_table = ACPI_PTR(imx258_acpi_ids), .of_match_table = imx258_dt_ids, }, - .probe_new = imx258_probe, + .probe = imx258_probe, .remove = imx258_remove, }; diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c index 9219f3c9594b..f33b692e6951 100644 --- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -2168,7 +2168,7 @@ static struct i2c_driver imx274_i2c_driver = { .pm = &imx274_pm_ops, .of_match_table = imx274_of_id_table, }, - .probe_new = imx274_probe, + .probe = imx274_probe, .remove = imx274_remove, .id_table = imx274_id, }; diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 5ea25b7acc55..b3f832e9d7e1 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -1716,10 +1716,10 @@ static const struct of_device_id imx290_of_match[] = { MODULE_DEVICE_TABLE(of, imx290_of_match); static struct i2c_driver imx290_i2c_driver = { - .probe_new = imx290_probe, + .probe = imx290_probe, .remove = imx290_remove, .driver = { - .name = "imx290", + .name = "imx290", .pm = pm_ptr(&imx290_pm_ops), .of_match_table = imx290_of_match, }, diff --git a/drivers/media/i2c/imx296.c b/drivers/media/i2c/imx296.c index 4f22c0515ef8..c0b9a5349668 100644 --- a/drivers/media/i2c/imx296.c +++ b/drivers/media/i2c/imx296.c @@ -922,10 +922,12 @@ static int imx296_read_temperature(struct imx296 *sensor, int *temp) if (ret < 0) return ret; - tmdout = imx296_read(sensor, IMX296_TMDOUT) & IMX296_TMDOUT_MASK; + tmdout = imx296_read(sensor, IMX296_TMDOUT); if (tmdout < 0) return tmdout; + tmdout &= IMX296_TMDOUT_MASK; + /* T(°C) = 246.312 - 0.304 * TMDOUT */; *temp = 246312 - 304 * tmdout; @@ -1152,7 +1154,7 @@ static struct i2c_driver imx296_i2c_driver = { .name = "imx296", .pm = &imx296_pm_ops }, - .probe_new = imx296_probe, + .probe = imx296_probe, .remove = imx296_remove, }; diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 45b1b61b2880..a2140848d0d6 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -2558,7 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = { .pm = &imx319_pm_ops, .acpi_match_table = ACPI_PTR(imx319_acpi_ids), }, - .probe_new = imx319_probe, + .probe = imx319_probe, .remove = imx319_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index 309c706114d2..d722c9b7cd31 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -49,7 +49,8 @@ #define IMX334_INCLK_RATE 24000000 /* CSI2 HW configuration */ -#define IMX334_LINK_FREQ 891000000 +#define IMX334_LINK_FREQ_891M 891000000 +#define IMX334_LINK_FREQ_445M 445500000 #define IMX334_NUM_DATA_LANES 4 #define IMX334_REG_MIN 0x00 @@ -117,6 +118,7 @@ struct imx334_mode { * @vblank: Vertical blanking in lines * @cur_mode: Pointer to current selected sensor mode * @mutex: Mutex for serializing sensor controls + * @menu_skip_mask: Menu skip mask for link_freq_ctrl * @cur_code: current selected format code * @streaming: Flag indicating streaming state */ @@ -139,12 +141,14 @@ struct imx334 { u32 vblank; const struct imx334_mode *cur_mode; struct mutex mutex; + unsigned long menu_skip_mask; u32 cur_code; bool streaming; }; static const s64 link_freq[] = { - IMX334_LINK_FREQ, + IMX334_LINK_FREQ_891M, + IMX334_LINK_FREQ_445M, }; /* Sensor mode registers for 1920x1080@30fps */ @@ -468,7 +472,7 @@ static const struct imx334_mode supported_modes[] = { .vblank_min = 45, .vblank_max = 132840, .pclk = 297000000, - .link_freq_idx = 0, + .link_freq_idx = 1, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs), .regs = mode_1920x1080_regs, @@ -598,13 +602,22 @@ static int imx334_update_controls(struct imx334 *imx334, if (ret) return ret; + ret = __v4l2_ctrl_modify_range(imx334->pclk_ctrl, mode->pclk, + mode->pclk, 1, mode->pclk); + if (ret) + return ret; + ret = __v4l2_ctrl_modify_range(imx334->hblank_ctrl, mode->hblank, mode->hblank, 1, mode->hblank); if (ret) return ret; - return __v4l2_ctrl_modify_range(imx334->vblank_ctrl, mode->vblank_min, + ret = __v4l2_ctrl_modify_range(imx334->vblank_ctrl, mode->vblank_min, mode->vblank_max, 1, mode->vblank); + if (ret) + return ret; + + return __v4l2_ctrl_s_ctrl(imx334->vblank_ctrl, mode->vblank); } /** @@ -698,6 +711,8 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl) pm_runtime_put(imx334->dev); break; + case V4L2_CID_PIXEL_RATE: + case V4L2_CID_LINK_FREQ: case V4L2_CID_HBLANK: ret = 0; break; @@ -885,7 +900,17 @@ static int imx334_init_pad_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_format fmt = { 0 }; fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - imx334_fill_pad_format(imx334, &supported_modes[0], &fmt); + + mutex_lock(&imx334->mutex); + + imx334_fill_pad_format(imx334, imx334->cur_mode, &fmt); + + __v4l2_ctrl_modify_range(imx334->link_freq_ctrl, 0, + __fls(imx334->menu_skip_mask), + ~(imx334->menu_skip_mask), + __ffs(imx334->menu_skip_mask)); + + mutex_unlock(&imx334->mutex); return imx334_set_pad_format(sd, sd_state, &fmt); } @@ -1046,8 +1071,8 @@ static int imx334_parse_hw_config(struct imx334 *imx334) }; struct fwnode_handle *ep; unsigned long rate; + unsigned int i, j; int ret; - int i; if (!fwnode) return -ENXIO; @@ -1097,11 +1122,20 @@ static int imx334_parse_hw_config(struct imx334 *imx334) goto done_endpoint_free; } - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) - if (bus_cfg.link_frequencies[i] == IMX334_LINK_FREQ) + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { + for (j = 0; j < ARRAY_SIZE(link_freq); j++) { + if (bus_cfg.link_frequencies[i] == link_freq[j]) { + set_bit(j, &imx334->menu_skip_mask); + break; + } + } + + if (j == ARRAY_SIZE(link_freq)) { + ret = dev_err_probe(imx334->dev, -EINVAL, + "no supported link freq found\n"); goto done_endpoint_free; - - ret = -EINVAL; + } + } done_endpoint_free: v4l2_fwnode_endpoint_free(&bus_cfg); @@ -1232,10 +1266,10 @@ static int imx334_init_controls(struct imx334 *imx334) imx334->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx334_ctrl_ops, V4L2_CID_LINK_FREQ, - ARRAY_SIZE(link_freq) - - 1, - mode->link_freq_idx, + __fls(imx334->menu_skip_mask), + __ffs(imx334->menu_skip_mask), link_freq); + if (imx334->link_freq_ctrl) imx334->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; @@ -1302,7 +1336,7 @@ static int imx334_probe(struct i2c_client *client) } /* Set default mode to max resolution */ - imx334->cur_mode = &supported_modes[0]; + imx334->cur_mode = &supported_modes[__ffs(imx334->menu_skip_mask)]; imx334->cur_code = imx334_mbus_codes[0]; imx334->vblank = imx334->cur_mode->vblank; @@ -1382,7 +1416,7 @@ static const struct of_device_id imx334_of_match[] = { MODULE_DEVICE_TABLE(of, imx334_of_match); static struct i2c_driver imx334_driver = { - .probe_new = imx334_probe, + .probe = imx334_probe, .remove = imx334_remove, .driver = { .name = "imx334", diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 078ede2b7a00..482a0b7f040a 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -1112,7 +1112,7 @@ static const struct of_device_id imx335_of_match[] = { MODULE_DEVICE_TABLE(of, imx335_of_match); static struct i2c_driver imx335_driver = { - .probe_new = imx335_probe, + .probe = imx335_probe, .remove = imx335_remove, .driver = { .name = "imx335", diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 25d4dbb6041e..6571a98b1e9e 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -1845,7 +1845,7 @@ static struct i2c_driver imx355_i2c_driver = { .pm = &imx355_pm_ops, .acpi_match_table = ACPI_PTR(imx355_acpi_ids), }, - .probe_new = imx355_probe, + .probe = imx355_probe, .remove = imx355_remove, }; module_i2c_driver(imx355_i2c_driver); diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c index e1e986dc8856..c7e862ae4040 100644 --- a/drivers/media/i2c/imx412.c +++ b/drivers/media/i2c/imx412.c @@ -1293,7 +1293,7 @@ static const struct of_device_id imx412_of_match[] = { MODULE_DEVICE_TABLE(of, imx412_of_match); static struct i2c_driver imx412_driver = { - .probe_new = imx412_probe, + .probe = imx412_probe, .remove = imx412_remove, .driver = { .name = "imx412", diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c index d90392df98c7..4b5d1ee9cc6b 100644 --- a/drivers/media/i2c/imx415.c +++ b/drivers/media/i2c/imx415.c @@ -1283,7 +1283,7 @@ static const struct of_device_id imx415_of_match[] = { MODULE_DEVICE_TABLE(of, imx415_of_match); static struct i2c_driver imx415_driver = { - .probe_new = imx415_probe, + .probe = imx415_probe, .remove = imx415_remove, .driver = { .name = "imx415", diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index 51921068931d..b37a2aaf8ac0 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -988,7 +988,7 @@ static struct i2c_driver ir_kbd_driver = { .driver = { .name = "ir-kbd-i2c", }, - .probe_new = ir_probe, + .probe = ir_probe, .remove = ir_remove, .id_table = ir_kbd_id, }; diff --git a/drivers/media/i2c/isl7998x.c b/drivers/media/i2c/isl7998x.c index ae7af2cc94f5..92e49d95363d 100644 --- a/drivers/media/i2c/isl7998x.c +++ b/drivers/media/i2c/isl7998x.c @@ -1614,7 +1614,7 @@ static struct i2c_driver isl7998x_i2c_driver = { .of_match_table = of_match_ptr(isl7998x_of_match), .pm = &isl7998x_pm_ops, }, - .probe_new = isl7998x_probe, + .probe = isl7998x_probe, .remove = isl7998x_remove, .id_table = isl7998x_id, }; diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c index 0d86f2db7ad2..5c583f57e3f3 100644 --- a/drivers/media/i2c/ks0127.c +++ b/drivers/media/i2c/ks0127.c @@ -696,7 +696,7 @@ static struct i2c_driver ks0127_driver = { .driver = { .name = "ks0127", }, - .probe_new = ks0127_probe, + .probe = ks0127_probe, .remove = ks0127_remove, .id_table = ks0127_id, }; diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 5ef613604be7..05283ac68f2d 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -467,7 +467,7 @@ static struct i2c_driver lm3560_i2c_driver = { .name = LM3560_NAME, .pm = NULL, }, - .probe_new = lm3560_probe, + .probe = lm3560_probe, .remove = lm3560_remove, .id_table = lm3560_id_table, }; diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index 2a0cf74d2bed..fab3a7e05f92 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -396,7 +396,7 @@ static struct i2c_driver lm3646_i2c_driver = { .driver = { .name = LM3646_NAME, }, - .probe_new = lm3646_probe, + .probe = lm3646_probe, .remove = lm3646_remove, .id_table = lm3646_id_table, }; diff --git a/drivers/media/i2c/m52790.c b/drivers/media/i2c/m52790.c index 0e6507ab7e08..f8a69142aae9 100644 --- a/drivers/media/i2c/m52790.c +++ b/drivers/media/i2c/m52790.c @@ -172,7 +172,7 @@ static struct i2c_driver m52790_driver = { .driver = { .name = "m52790", }, - .probe_new = m52790_probe, + .probe = m52790_probe, .remove = m52790_remove, .id_table = m52790_id, }; diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index 1019020f3a37..70c2a2948fd4 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c @@ -1429,7 +1429,7 @@ static struct i2c_driver max2175_driver = { .name = DRIVER_NAME, .of_match_table = max2175_of_ids, }, - .probe_new = max2175_probe, + .probe = max2175_probe, .remove = max2175_remove, .id_table = max2175_id, }; diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 13a986b88588..88c58e0c49aa 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -1716,7 +1716,7 @@ static struct i2c_driver max9286_i2c_driver = { .name = "max9286", .of_match_table = of_match_ptr(max9286_dt_ids), }, - .probe_new = max9286_probe, + .probe = max9286_probe, .remove = max9286_remove, }; diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index dbd2f0bd3651..5b72d4434224 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c @@ -433,7 +433,7 @@ static struct i2c_driver ml86v7667_i2c_driver = { .driver = { .name = DRV_NAME, }, - .probe_new = ml86v7667_probe, + .probe = ml86v7667_probe, .remove = ml86v7667_remove, .id_table = ml86v7667_id, }; diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index 12032e28b428..bec76801487a 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -892,7 +892,7 @@ static struct i2c_driver msp_driver = { .name = "msp3400", .pm = &msp3400_pm_ops, }, - .probe_new = msp_probe, + .probe = msp_probe, .remove = msp_remove, .id_table = msp_id, }; diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c index ebf9cf1e1bce..ce9568e8391c 100644 --- a/drivers/media/i2c/mt9m001.c +++ b/drivers/media/i2c/mt9m001.c @@ -877,7 +877,7 @@ static struct i2c_driver mt9m001_i2c_driver = { .pm = &mt9m001_pm_ops, .of_match_table = mt9m001_of_match, }, - .probe_new = mt9m001_probe, + .probe = mt9m001_probe, .remove = mt9m001_remove, .id_table = mt9m001_id, }; diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index f5fe272d1205..2878d328fc01 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -1384,7 +1384,7 @@ static struct i2c_driver mt9m111_i2c_driver = { .name = "mt9m111", .of_match_table = of_match_ptr(mt9m111_of_match), }, - .probe_new = mt9m111_probe, + .probe = mt9m111_probe, .remove = mt9m111_remove, .id_table = mt9m111_id, }; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 9e023a4b9bd1..348f1e1098fb 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -1248,7 +1248,7 @@ static struct i2c_driver mt9p031_i2c_driver = { .of_match_table = of_match_ptr(mt9p031_of_match), .name = "mt9p031", }, - .probe_new = mt9p031_probe, + .probe = mt9p031_probe, .remove = mt9p031_remove, .id_table = mt9p031_id, }; diff --git a/drivers/media/i2c/mt9t112.c b/drivers/media/i2c/mt9t112.c index a82f056787b8..93f34b767027 100644 --- a/drivers/media/i2c/mt9t112.c +++ b/drivers/media/i2c/mt9t112.c @@ -1119,7 +1119,7 @@ static struct i2c_driver mt9t112_i2c_driver = { .driver = { .name = "mt9t112", }, - .probe_new = mt9t112_probe, + .probe = mt9t112_probe, .remove = mt9t112_remove, .id_table = mt9t112_id, }; diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index c54c7fbf0963..774861ba7747 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -585,7 +585,7 @@ static struct i2c_driver mt9v011_driver = { .driver = { .name = "mt9v011", }, - .probe_new = mt9v011_probe, + .probe = mt9v011_probe, .remove = mt9v011_remove, .id_table = mt9v011_id, }; diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 7cfd4ebdd2e6..00e7bc6e3235 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -1296,7 +1296,7 @@ static struct i2c_driver mt9v032_driver = { .name = "mt9v032", .of_match_table = of_match_ptr(mt9v032_of_match), }, - .probe_new = mt9v032_probe, + .probe = mt9v032_probe, .remove = mt9v032_remove, .id_table = mt9v032_id, }; diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c index 46d91cd0870c..1f7edc0f5b1a 100644 --- a/drivers/media/i2c/mt9v111.c +++ b/drivers/media/i2c/mt9v111.c @@ -1265,7 +1265,7 @@ static struct i2c_driver mt9v111_driver = { .name = "mt9v111", .of_match_table = mt9v111_of_match, }, - .probe_new = mt9v111_probe, + .probe = mt9v111_probe, .remove = mt9v111_remove, }; diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c index 35663c10fcd9..b5948759342e 100644 --- a/drivers/media/i2c/og01a1b.c +++ b/drivers/media/i2c/og01a1b.c @@ -1115,7 +1115,7 @@ static struct i2c_driver og01a1b_i2c_driver = { .pm = &og01a1b_pm_ops, .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids), }, - .probe_new = og01a1b_probe, + .probe = og01a1b_probe, .remove = og01a1b_remove, }; diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c new file mode 100644 index 000000000000..de5bc19e715b --- /dev/null +++ b/drivers/media/i2c/ov01a10.c @@ -0,0 +1,1004 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023 Intel Corporation. + */ + +#include <asm/unaligned.h> + +#include <linux/acpi.h> +#include <linux/bitfield.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> + +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-event.h> +#include <media/v4l2-fwnode.h> + +#define OV01A10_LINK_FREQ_400MHZ 400000000ULL +#define OV01A10_SCLK 40000000LL +#define OV01A10_DATA_LANES 1 + +#define OV01A10_REG_CHIP_ID 0x300a +#define OV01A10_CHIP_ID 0x560141 + +#define OV01A10_REG_MODE_SELECT 0x0100 +#define OV01A10_MODE_STANDBY 0x00 +#define OV01A10_MODE_STREAMING 0x01 + +/* pixel array */ +#define OV01A10_PIXEL_ARRAY_WIDTH 1296 +#define OV01A10_PIXEL_ARRAY_HEIGHT 816 +#define OV01A10_ACITVE_WIDTH 1280 +#define OV01A10_ACITVE_HEIGHT 800 + +/* vertical and horizontal timings */ +#define OV01A10_REG_VTS 0x380e +#define OV01A10_VTS_DEF 0x0380 +#define OV01A10_VTS_MIN 0x0380 +#define OV01A10_VTS_MAX 0xffff +#define OV01A10_HTS_DEF 1488 + +/* exposure controls */ +#define OV01A10_REG_EXPOSURE 0x3501 +#define OV01A10_EXPOSURE_MIN 4 +#define OV01A10_EXPOSURE_MAX_MARGIN 8 +#define OV01A10_EXPOSURE_STEP 1 + +/* analog gain controls */ +#define OV01A10_REG_ANALOG_GAIN 0x3508 +#define OV01A10_ANAL_GAIN_MIN 0x100 +#define OV01A10_ANAL_GAIN_MAX 0xffff +#define OV01A10_ANAL_GAIN_STEP 1 + +/* digital gain controls */ +#define OV01A10_REG_DIGITAL_GAIN_B 0x350a +#define OV01A10_REG_DIGITAL_GAIN_GB 0x3510 +#define OV01A10_REG_DIGITAL_GAIN_GR 0x3513 +#define OV01A10_REG_DIGITAL_GAIN_R 0x3516 +#define OV01A10_DGTL_GAIN_MIN 0 +#define OV01A10_DGTL_GAIN_MAX 0x3ffff +#define OV01A10_DGTL_GAIN_STEP 1 +#define OV01A10_DGTL_GAIN_DEFAULT 1024 + +/* test pattern control */ +#define OV01A10_REG_TEST_PATTERN 0x4503 +#define OV01A10_TEST_PATTERN_ENABLE BIT(7) +#define OV01A10_LINK_FREQ_400MHZ_INDEX 0 + +/* flip and mirror control */ +#define OV01A10_REG_FORMAT1 0x3820 +#define OV01A10_VFLIP_MASK BIT(4) +#define OV01A10_HFLIP_MASK BIT(3) + +/* window offset */ +#define OV01A10_REG_X_WIN 0x3811 +#define OV01A10_REG_Y_WIN 0x3813 + +struct ov01a10_reg { + u16 address; + u8 val; +}; + +struct ov01a10_reg_list { + u32 num_of_regs; + const struct ov01a10_reg *regs; +}; + +struct ov01a10_link_freq_config { + const struct ov01a10_reg_list reg_list; +}; + +struct ov01a10_mode { + u32 width; + u32 height; + u32 hts; + u32 vts_def; + u32 vts_min; + u32 link_freq_index; + + const struct ov01a10_reg_list reg_list; +}; + +static const struct ov01a10_reg mipi_data_rate_720mbps[] = { + {0x0103, 0x01}, + {0x0302, 0x00}, + {0x0303, 0x06}, + {0x0304, 0x01}, + {0x0305, 0xe0}, + {0x0306, 0x00}, + {0x0308, 0x01}, + {0x0309, 0x00}, + {0x030c, 0x01}, + {0x0322, 0x01}, + {0x0323, 0x06}, + {0x0324, 0x01}, + {0x0325, 0x68}, +}; + +static const struct ov01a10_reg sensor_1280x800_setting[] = { + {0x3002, 0xa1}, + {0x301e, 0xf0}, + {0x3022, 0x01}, + {0x3501, 0x03}, + {0x3502, 0x78}, + {0x3504, 0x0c}, + {0x3508, 0x01}, + {0x3509, 0x00}, + {0x3601, 0xc0}, + {0x3603, 0x71}, + {0x3610, 0x68}, + {0x3611, 0x86}, + {0x3640, 0x10}, + {0x3641, 0x80}, + {0x3642, 0xdc}, + {0x3646, 0x55}, + {0x3647, 0x57}, + {0x364b, 0x00}, + {0x3653, 0x10}, + {0x3655, 0x00}, + {0x3656, 0x00}, + {0x365f, 0x0f}, + {0x3661, 0x45}, + {0x3662, 0x24}, + {0x3663, 0x11}, + {0x3664, 0x07}, + {0x3709, 0x34}, + {0x370b, 0x6f}, + {0x3714, 0x22}, + {0x371b, 0x27}, + {0x371c, 0x67}, + {0x371d, 0xa7}, + {0x371e, 0xe7}, + {0x3730, 0x81}, + {0x3733, 0x10}, + {0x3734, 0x40}, + {0x3737, 0x04}, + {0x3739, 0x1c}, + {0x3767, 0x00}, + {0x376c, 0x81}, + {0x3772, 0x14}, + {0x37c2, 0x04}, + {0x37d8, 0x03}, + {0x37d9, 0x0c}, + {0x37e0, 0x00}, + {0x37e1, 0x08}, + {0x37e2, 0x10}, + {0x37e3, 0x04}, + {0x37e4, 0x04}, + {0x37e5, 0x03}, + {0x37e6, 0x04}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x05}, + {0x3805, 0x0f}, + {0x3806, 0x03}, + {0x3807, 0x2f}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x03}, + {0x380b, 0x20}, + {0x380c, 0x02}, + {0x380d, 0xe8}, + {0x380e, 0x03}, + {0x380f, 0x80}, + {0x3810, 0x00}, + {0x3811, 0x08}, + {0x3812, 0x00}, + {0x3813, 0x08}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x01}, + {0x3817, 0x01}, + {0x3820, 0xa0}, + {0x3822, 0x13}, + {0x3832, 0x28}, + {0x3833, 0x10}, + {0x3b00, 0x00}, + {0x3c80, 0x00}, + {0x3c88, 0x02}, + {0x3c8c, 0x07}, + {0x3c8d, 0x40}, + {0x3cc7, 0x80}, + {0x4000, 0xc3}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x02}, + {0x4009, 0x19}, + {0x400a, 0x01}, + {0x400b, 0x6c}, + {0x4011, 0x00}, + {0x4041, 0x00}, + {0x4300, 0xff}, + {0x4301, 0x00}, + {0x4302, 0x0f}, + {0x4503, 0x00}, + {0x4601, 0x50}, + {0x4800, 0x64}, + {0x481f, 0x34}, + {0x4825, 0x33}, + {0x4837, 0x11}, + {0x4881, 0x40}, + {0x4883, 0x01}, + {0x4890, 0x00}, + {0x4901, 0x00}, + {0x4902, 0x00}, + {0x4b00, 0x2a}, + {0x4b0d, 0x00}, + {0x450a, 0x04}, + {0x450b, 0x00}, + {0x5000, 0x65}, + {0x5200, 0x18}, + {0x5004, 0x00}, + {0x5080, 0x40}, + {0x0305, 0xf4}, + {0x0325, 0xc2}, +}; + +static const char * const ov01a10_test_pattern_menu[] = { + "Disabled", + "Color Bar", + "Top-Bottom Darker Color Bar", + "Right-Left Darker Color Bar", + "Color Bar type 4", +}; + +static const s64 link_freq_menu_items[] = { + OV01A10_LINK_FREQ_400MHZ, +}; + +static const struct ov01a10_link_freq_config link_freq_configs[] = { + [OV01A10_LINK_FREQ_400MHZ_INDEX] = { + .reg_list = { + .num_of_regs = ARRAY_SIZE(mipi_data_rate_720mbps), + .regs = mipi_data_rate_720mbps, + } + }, +}; + +static const struct ov01a10_mode supported_modes[] = { + { + .width = OV01A10_ACITVE_WIDTH, + .height = OV01A10_ACITVE_HEIGHT, + .hts = OV01A10_HTS_DEF, + .vts_def = OV01A10_VTS_DEF, + .vts_min = OV01A10_VTS_MIN, + .reg_list = { + .num_of_regs = ARRAY_SIZE(sensor_1280x800_setting), + .regs = sensor_1280x800_setting, + }, + .link_freq_index = OV01A10_LINK_FREQ_400MHZ_INDEX, + }, +}; + +struct ov01a10 { + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; + + /* v4l2 controls */ + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *exposure; + + const struct ov01a10_mode *cur_mode; + + /* streaming state */ + bool streaming; +}; + +static inline struct ov01a10 *to_ov01a10(struct v4l2_subdev *subdev) +{ + return container_of(subdev, struct ov01a10, sd); +} + +static int ov01a10_read_reg(struct ov01a10 *ov01a10, u16 reg, u16 len, u32 *val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + struct i2c_msg msgs[2]; + u8 addr_buf[2]; + u8 data_buf[4] = {0}; + int ret = 0; + + if (len > sizeof(data_buf)) + return -EINVAL; + + put_unaligned_be16(reg, addr_buf); + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = sizeof(addr_buf); + msgs[0].buf = addr_buf; + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = &data_buf[sizeof(data_buf) - len]; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + + if (ret != ARRAY_SIZE(msgs)) + return ret < 0 ? ret : -EIO; + + *val = get_unaligned_be32(data_buf); + + return 0; +} + +static int ov01a10_write_reg(struct ov01a10 *ov01a10, u16 reg, u16 len, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + u8 buf[6]; + int ret = 0; + + if (len > 4) + return -EINVAL; + + put_unaligned_be16(reg, buf); + put_unaligned_be32(val << 8 * (4 - len), buf + 2); + + ret = i2c_master_send(client, buf, len + 2); + if (ret != len + 2) + return ret < 0 ? ret : -EIO; + + return 0; +} + +static int ov01a10_write_reg_list(struct ov01a10 *ov01a10, + const struct ov01a10_reg_list *r_list) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + unsigned int i; + int ret = 0; + + for (i = 0; i < r_list->num_of_regs; i++) { + ret = ov01a10_write_reg(ov01a10, r_list->regs[i].address, 1, + r_list->regs[i].val); + if (ret) { + dev_err_ratelimited(&client->dev, + "write reg 0x%4.4x err = %d\n", + r_list->regs[i].address, ret); + return ret; + } + } + + return 0; +} + +static int ov01a10_update_digital_gain(struct ov01a10 *ov01a10, u32 d_gain) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + u32 real = d_gain << 6; + int ret = 0; + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_B, 3, real); + if (ret) { + dev_err(&client->dev, "failed to set DIGITAL_GAIN_B\n"); + return ret; + } + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_GB, 3, real); + if (ret) { + dev_err(&client->dev, "failed to set DIGITAL_GAIN_GB\n"); + return ret; + } + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_GR, 3, real); + if (ret) { + dev_err(&client->dev, "failed to set DIGITAL_GAIN_GR\n"); + return ret; + } + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_R, 3, real); + if (ret) + dev_err(&client->dev, "failed to set DIGITAL_GAIN_R\n"); + + return ret; +} + +static int ov01a10_test_pattern(struct ov01a10 *ov01a10, u32 pattern) +{ + if (!pattern) + return 0; + + pattern = (pattern - 1) | OV01A10_TEST_PATTERN_ENABLE; + + return ov01a10_write_reg(ov01a10, OV01A10_REG_TEST_PATTERN, 1, pattern); +} + +/* for vflip and hflip, use 0x9 as window offset to keep the bayer */ +static int ov01a10_set_hflip(struct ov01a10 *ov01a10, u32 hflip) +{ + int ret; + u32 val, offset; + + offset = hflip ? 0x9 : 0x8; + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_X_WIN, 1, offset); + if (ret) + return ret; + + ret = ov01a10_read_reg(ov01a10, OV01A10_REG_FORMAT1, 1, &val); + if (ret) + return ret; + + val = hflip ? val | FIELD_PREP(OV01A10_HFLIP_MASK, 0x1) : + val & ~OV01A10_HFLIP_MASK; + + return ov01a10_write_reg(ov01a10, OV01A10_REG_FORMAT1, 1, val); +} + +static int ov01a10_set_vflip(struct ov01a10 *ov01a10, u32 vflip) +{ + int ret; + u32 val, offset; + + offset = vflip ? 0x9 : 0x8; + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_Y_WIN, 1, offset); + if (ret) + return ret; + + ret = ov01a10_read_reg(ov01a10, OV01A10_REG_FORMAT1, 1, &val); + if (ret) + return ret; + + val = vflip ? val | FIELD_PREP(OV01A10_VFLIP_MASK, 0x1) : + val & ~OV01A10_VFLIP_MASK; + + return ov01a10_write_reg(ov01a10, OV01A10_REG_FORMAT1, 1, val); +} + +static int ov01a10_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov01a10 *ov01a10 = container_of(ctrl->handler, + struct ov01a10, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + s64 exposure_max; + int ret = 0; + + if (ctrl->id == V4L2_CID_VBLANK) { + exposure_max = ov01a10->cur_mode->height + ctrl->val - + OV01A10_EXPOSURE_MAX_MARGIN; + __v4l2_ctrl_modify_range(ov01a10->exposure, + ov01a10->exposure->minimum, + exposure_max, ov01a10->exposure->step, + exposure_max); + } + + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_ANALOGUE_GAIN: + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_ANALOG_GAIN, 2, + ctrl->val); + break; + + case V4L2_CID_DIGITAL_GAIN: + ret = ov01a10_update_digital_gain(ov01a10, ctrl->val); + break; + + case V4L2_CID_EXPOSURE: + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_EXPOSURE, 2, + ctrl->val); + break; + + case V4L2_CID_VBLANK: + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_VTS, 2, + ov01a10->cur_mode->height + ctrl->val); + break; + + case V4L2_CID_TEST_PATTERN: + ret = ov01a10_test_pattern(ov01a10, ctrl->val); + break; + + case V4L2_CID_HFLIP: + ov01a10_set_hflip(ov01a10, ctrl->val); + break; + + case V4L2_CID_VFLIP: + ov01a10_set_vflip(ov01a10, ctrl->val); + break; + + default: + ret = -EINVAL; + break; + } + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops ov01a10_ctrl_ops = { + .s_ctrl = ov01a10_set_ctrl, +}; + +static int ov01a10_init_controls(struct ov01a10 *ov01a10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + struct v4l2_fwnode_device_properties props; + u32 vblank_min, vblank_max, vblank_default; + struct v4l2_ctrl_handler *ctrl_hdlr; + const struct ov01a10_mode *cur_mode; + s64 exposure_max, h_blank; + int ret = 0; + int size; + + ret = v4l2_fwnode_device_parse(&client->dev, &props); + if (ret) + return ret; + + ctrl_hdlr = &ov01a10->ctrl_handler; + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); + if (ret) + return ret; + + cur_mode = ov01a10->cur_mode; + size = ARRAY_SIZE(link_freq_menu_items); + + ov01a10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, + &ov01a10_ctrl_ops, + V4L2_CID_LINK_FREQ, + size - 1, 0, + link_freq_menu_items); + if (ov01a10->link_freq) + ov01a10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + ov01a10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, + V4L2_CID_PIXEL_RATE, 0, + OV01A10_SCLK, 1, OV01A10_SCLK); + + vblank_min = cur_mode->vts_min - cur_mode->height; + vblank_max = OV01A10_VTS_MAX - cur_mode->height; + vblank_default = cur_mode->vts_def - cur_mode->height; + ov01a10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, + V4L2_CID_VBLANK, vblank_min, + vblank_max, 1, vblank_default); + + h_blank = cur_mode->hts - cur_mode->width; + ov01a10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, + V4L2_CID_HBLANK, h_blank, h_blank, + 1, h_blank); + if (ov01a10->hblank) + ov01a10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + OV01A10_ANAL_GAIN_MIN, OV01A10_ANAL_GAIN_MAX, + OV01A10_ANAL_GAIN_STEP, OV01A10_ANAL_GAIN_MIN); + v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + OV01A10_DGTL_GAIN_MIN, OV01A10_DGTL_GAIN_MAX, + OV01A10_DGTL_GAIN_STEP, OV01A10_DGTL_GAIN_DEFAULT); + + exposure_max = cur_mode->vts_def - OV01A10_EXPOSURE_MAX_MARGIN; + ov01a10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, + V4L2_CID_EXPOSURE, + OV01A10_EXPOSURE_MIN, + exposure_max, + OV01A10_EXPOSURE_STEP, + exposure_max); + + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov01a10_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(ov01a10_test_pattern_menu) - 1, + 0, 0, ov01a10_test_pattern_menu); + + v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov01a10_ctrl_ops, + &props); + if (ret) + goto fail; + + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; + goto fail; + } + + ov01a10->sd.ctrl_handler = ctrl_hdlr; + + return 0; +fail: + v4l2_ctrl_handler_free(ctrl_hdlr); + + return ret; +} + +static void ov01a10_update_pad_format(const struct ov01a10_mode *mode, + struct v4l2_mbus_framefmt *fmt) +{ + fmt->width = mode->width; + fmt->height = mode->height; + fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_RAW; +} + +static int ov01a10_start_streaming(struct ov01a10 *ov01a10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + const struct ov01a10_reg_list *reg_list; + int link_freq_index; + int ret = 0; + + link_freq_index = ov01a10->cur_mode->link_freq_index; + reg_list = &link_freq_configs[link_freq_index].reg_list; + ret = ov01a10_write_reg_list(ov01a10, reg_list); + if (ret) { + dev_err(&client->dev, "failed to set plls\n"); + return ret; + } + + reg_list = &ov01a10->cur_mode->reg_list; + ret = ov01a10_write_reg_list(ov01a10, reg_list); + if (ret) { + dev_err(&client->dev, "failed to set mode\n"); + return ret; + } + + ret = __v4l2_ctrl_handler_setup(ov01a10->sd.ctrl_handler); + if (ret) + return ret; + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_MODE_SELECT, 1, + OV01A10_MODE_STREAMING); + if (ret) + dev_err(&client->dev, "failed to start streaming\n"); + + return ret; +} + +static void ov01a10_stop_streaming(struct ov01a10 *ov01a10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + int ret = 0; + + ret = ov01a10_write_reg(ov01a10, OV01A10_REG_MODE_SELECT, 1, + OV01A10_MODE_STANDBY); + if (ret) + dev_err(&client->dev, "failed to stop streaming\n"); +} + +static int ov01a10_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ov01a10 *ov01a10 = to_ov01a10(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct v4l2_subdev_state *state; + int ret = 0; + + state = v4l2_subdev_lock_and_get_active_state(sd); + if (ov01a10->streaming == enable) + goto unlock; + + if (enable) { + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) + goto unlock; + + ret = ov01a10_start_streaming(ov01a10); + if (ret) { + pm_runtime_put(&client->dev); + goto unlock; + } + + goto done; + } + + ov01a10_stop_streaming(ov01a10); + pm_runtime_put(&client->dev); +done: + ov01a10->streaming = enable; +unlock: + v4l2_subdev_unlock_state(state); + + return ret; +} + +static int __maybe_unused ov01a10_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov01a10 *ov01a10 = to_ov01a10(sd); + struct v4l2_subdev_state *state; + + state = v4l2_subdev_lock_and_get_active_state(sd); + if (ov01a10->streaming) + ov01a10_stop_streaming(ov01a10); + + v4l2_subdev_unlock_state(state); + + return 0; +} + +static int __maybe_unused ov01a10_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov01a10 *ov01a10 = to_ov01a10(sd); + struct v4l2_subdev_state *state; + int ret = 0; + + state = v4l2_subdev_lock_and_get_active_state(sd); + if (!ov01a10->streaming) + goto exit; + + ret = ov01a10_start_streaming(ov01a10); + if (ret) { + ov01a10->streaming = false; + ov01a10_stop_streaming(ov01a10); + } + +exit: + v4l2_subdev_unlock_state(state); + + return ret; +} + +static int ov01a10_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + struct ov01a10 *ov01a10 = to_ov01a10(sd); + const struct ov01a10_mode *mode; + struct v4l2_mbus_framefmt *format; + s32 vblank_def, h_blank; + + mode = v4l2_find_nearest_size(supported_modes, + ARRAY_SIZE(supported_modes), width, + height, fmt->format.width, + fmt->format.height); + + ov01a10_update_pad_format(mode, &fmt->format); + + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + ov01a10->cur_mode = mode; + __v4l2_ctrl_s_ctrl(ov01a10->link_freq, mode->link_freq_index); + __v4l2_ctrl_s_ctrl_int64(ov01a10->pixel_rate, OV01A10_SCLK); + + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(ov01a10->vblank, + mode->vts_min - mode->height, + OV01A10_VTS_MAX - mode->height, 1, + vblank_def); + __v4l2_ctrl_s_ctrl(ov01a10->vblank, vblank_def); + h_blank = mode->hts - mode->width; + __v4l2_ctrl_modify_range(ov01a10->hblank, h_blank, h_blank, 1, + h_blank); + } + + format = v4l2_subdev_get_pad_format(sd, sd_state, fmt->stream); + *format = fmt->format; + + return 0; +} + +static int ov01a10_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_TRY, + .format = { + .width = OV01A10_ACITVE_WIDTH, + .height = OV01A10_ACITVE_HEIGHT, + }, + }; + + ov01a10_set_format(sd, state, &fmt); + + return 0; +} + +static int ov01a10_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index > 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_SBGGR10_1X10; + + return 0; +} + +static int ov01a10_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes) || + fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = fse->min_width; + fse->min_height = supported_modes[fse->index].height; + fse->max_height = fse->min_height; + + return 0; +} + +static int ov01a10_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_NATIVE_SIZE: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = OV01A10_PIXEL_ARRAY_WIDTH; + sel->r.height = OV01A10_PIXEL_ARRAY_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.top = (OV01A10_PIXEL_ARRAY_HEIGHT - + OV01A10_ACITVE_HEIGHT) / 2; + sel->r.left = (OV01A10_PIXEL_ARRAY_WIDTH - + OV01A10_ACITVE_WIDTH) / 2; + sel->r.width = OV01A10_ACITVE_WIDTH; + sel->r.height = OV01A10_ACITVE_HEIGHT; + return 0; + } + + return -EINVAL; +} + +static const struct v4l2_subdev_core_ops ov01a10_core_ops = { + .log_status = v4l2_ctrl_subdev_log_status, + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static const struct v4l2_subdev_video_ops ov01a10_video_ops = { + .s_stream = ov01a10_set_stream, +}; + +static const struct v4l2_subdev_pad_ops ov01a10_pad_ops = { + .init_cfg = ov01a10_init_cfg, + .set_fmt = ov01a10_set_format, + .get_fmt = v4l2_subdev_get_fmt, + .get_selection = ov01a10_get_selection, + .enum_mbus_code = ov01a10_enum_mbus_code, + .enum_frame_size = ov01a10_enum_frame_size, +}; + +static const struct v4l2_subdev_ops ov01a10_subdev_ops = { + .core = &ov01a10_core_ops, + .video = &ov01a10_video_ops, + .pad = &ov01a10_pad_ops, +}; + +static const struct media_entity_operations ov01a10_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static int ov01a10_identify_module(struct ov01a10 *ov01a10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd); + int ret; + u32 val; + + ret = ov01a10_read_reg(ov01a10, OV01A10_REG_CHIP_ID, 3, &val); + if (ret) + return ret; + + if (val != OV01A10_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + OV01A10_CHIP_ID, val); + return -EIO; + } + + return 0; +} + +static void ov01a10_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + v4l2_ctrl_handler_free(sd->ctrl_handler); + + pm_runtime_disable(&client->dev); +} + +static int ov01a10_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct ov01a10 *ov01a10; + int ret = 0; + + ov01a10 = devm_kzalloc(dev, sizeof(*ov01a10), GFP_KERNEL); + if (!ov01a10) + return -ENOMEM; + + v4l2_i2c_subdev_init(&ov01a10->sd, client, &ov01a10_subdev_ops); + + ret = ov01a10_identify_module(ov01a10); + if (ret) + return dev_err_probe(dev, ret, + "failed to find sensor\n"); + + ov01a10->cur_mode = &supported_modes[0]; + + ret = ov01a10_init_controls(ov01a10); + if (ret) { + dev_err(dev, "failed to init controls: %d\n", ret); + return ret; + } + + ov01a10->sd.state_lock = ov01a10->ctrl_handler.lock; + ov01a10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS; + ov01a10->sd.entity.ops = &ov01a10_subdev_entity_ops; + ov01a10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + ov01a10->pad.flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&ov01a10->sd.entity, 1, &ov01a10->pad); + if (ret) { + dev_err(dev, "Failed to init entity pads: %d\n", ret); + goto err_handler_free; + } + + ret = v4l2_subdev_init_finalize(&ov01a10->sd); + if (ret) { + dev_err(dev, "Failed to allocate subdev state: %d\n", ret); + goto err_media_entity_cleanup; + } + + ret = v4l2_async_register_subdev_sensor(&ov01a10->sd); + if (ret < 0) { + dev_err(dev, "Failed to register subdev: %d\n", ret); + goto err_media_entity_cleanup; + } + + pm_runtime_enable(dev); + pm_runtime_idle(dev); + + return 0; + +err_media_entity_cleanup: + media_entity_cleanup(&ov01a10->sd.entity); + +err_handler_free: + v4l2_ctrl_handler_free(ov01a10->sd.ctrl_handler); + + return ret; +} + +static const struct dev_pm_ops ov01a10_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ov01a10_suspend, ov01a10_resume) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id ov01a10_acpi_ids[] = { + { "OVTI01A0" }, + { } +}; + +MODULE_DEVICE_TABLE(acpi, ov01a10_acpi_ids); +#endif + +static struct i2c_driver ov01a10_i2c_driver = { + .driver = { + .name = "ov01a10", + .pm = &ov01a10_pm_ops, + .acpi_match_table = ACPI_PTR(ov01a10_acpi_ids), + }, + .probe_new = ov01a10_probe, + .remove = ov01a10_remove, +}; + +module_i2c_driver(ov01a10_i2c_driver); + +MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>"); +MODULE_AUTHOR("Wang Yating <yating.wang@intel.com>"); +MODULE_DESCRIPTION("OmniVision OV01A10 sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c index 2c1eb724d8e5..741d977a76f3 100644 --- a/drivers/media/i2c/ov02a10.c +++ b/drivers/media/i2c/ov02a10.c @@ -1002,8 +1002,8 @@ static struct i2c_driver ov02a10_i2c_driver = { .pm = &ov02a10_pm_ops, .of_match_table = ov02a10_of_match, }, - .probe_new = &ov02a10_probe, - .remove = &ov02a10_remove, + .probe = ov02a10_probe, + .remove = ov02a10_remove, }; module_i2c_driver(ov02a10_i2c_driver); diff --git a/drivers/media/i2c/ov08d10.c b/drivers/media/i2c/ov08d10.c index a39e086a51c5..7d55d4ca24de 100644 --- a/drivers/media/i2c/ov08d10.c +++ b/drivers/media/i2c/ov08d10.c @@ -1520,7 +1520,7 @@ static struct i2c_driver ov08d10_i2c_driver = { .pm = &ov08d10_pm_ops, .acpi_match_table = ACPI_PTR(ov08d10_acpi_ids), }, - .probe_new = ov08d10_probe, + .probe = ov08d10_probe, .remove = ov08d10_remove, }; diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 72ae7fba94eb..77bcdcd0824c 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -3313,7 +3313,7 @@ static struct i2c_driver ov08x40_i2c_driver = { .pm = &ov08x40_pm_ops, .acpi_match_table = ACPI_PTR(ov08x40_acpi_ids), }, - .probe_new = ov08x40_probe, + .probe = ov08x40_probe, .remove = ov08x40_remove, }; diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 69a7a2c590db..3db3e64fa3ff 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1806,7 +1806,7 @@ static struct i2c_driver ov13858_i2c_driver = { .pm = &ov13858_pm_ops, .acpi_match_table = ACPI_PTR(ov13858_acpi_ids), }, - .probe_new = ov13858_probe, + .probe = ov13858_probe, .remove = ov13858_remove, .id_table = ov13858_id_table, }; diff --git a/drivers/media/i2c/ov13b10.c b/drivers/media/i2c/ov13b10.c index c1430044fb1e..6110fb1e6bc6 100644 --- a/drivers/media/i2c/ov13b10.c +++ b/drivers/media/i2c/ov13b10.c @@ -1496,7 +1496,7 @@ static struct i2c_driver ov13b10_i2c_driver = { .pm = &ov13b10_pm_ops, .acpi_match_table = ACPI_PTR(ov13b10_acpi_ids), }, - .probe_new = ov13b10_probe, + .probe = ov13b10_probe, .remove = ov13b10_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 39d56838a4ef..ec801a81c2d0 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -1298,7 +1298,7 @@ static struct i2c_driver ov2640_i2c_driver = { .name = "ov2640", .of_match_table = of_match_ptr(ov2640_of_match), }, - .probe_new = ov2640_probe, + .probe = ov2640_probe, .remove = ov2640_remove, .id_table = ov2640_id, }; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 42fc64ada08c..5429bd2eb053 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1584,7 +1584,7 @@ static struct i2c_driver ov2659_i2c_driver = { .pm = &ov2659_pm_ops, .of_match_table = of_match_ptr(ov2659_of_match), }, - .probe_new = ov2659_probe, + .probe = ov2659_probe, .remove = ov2659_remove, .id_table = ov2659_id, }; diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 54153bf66bdd..d06e9fc37f77 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -1158,7 +1158,7 @@ static struct i2c_driver ov2680_i2c_driver = { .pm = &ov2680_pm_ops, .of_match_table = of_match_ptr(ov2680_dt_ids), }, - .probe_new = ov2680_probe, + .probe = ov2680_probe, .remove = ov2680_remove, }; module_i2c_driver(ov2680_i2c_driver); diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c index f119a93e7c64..303793e1f97d 100644 --- a/drivers/media/i2c/ov2685.c +++ b/drivers/media/i2c/ov2685.c @@ -903,8 +903,8 @@ static struct i2c_driver ov2685_i2c_driver = { .pm = &ov2685_pm_ops, .of_match_table = of_match_ptr(ov2685_of_match), }, - .probe_new = &ov2685_probe, - .remove = &ov2685_remove, + .probe = ov2685_probe, + .remove = ov2685_remove, }; module_i2c_driver(ov2685_i2c_driver); diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 89d126240c34..158d934733c3 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -1215,7 +1215,7 @@ static struct i2c_driver ov2740_i2c_driver = { .pm = pm_sleep_ptr(&ov2740_pm_ops), .acpi_match_table = ov2740_acpi_ids, }, - .probe_new = ov2740_probe, + .probe = ov2740_probe, .remove = ov2740_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index c602e507d42b..fda217d2cb10 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -1008,7 +1008,7 @@ static struct i2c_driver ov4689_i2c_driver = { .pm = &ov4689_pm_ops, .of_match_table = ov4689_of_match, }, - .probe_new = ov4689_probe, + .probe = ov4689_probe, .remove = ov4689_remove, }; diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 1536649b9e90..36b509714c8c 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -2815,7 +2815,6 @@ static int ov5640_get_fmt(struct v4l2_subdev *sd, static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt, - enum ov5640_frame_rate fr, const struct ov5640_mode_info **new_mode) { struct ov5640_dev *sensor = to_ov5640_dev(sd); @@ -2927,19 +2926,6 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) hblank, hblank, 1, hblank); vblank = timings->vblank_def; - - if (sensor->current_fr != mode->def_fps) { - /* - * Compute the vertical blanking according to the framerate - * configured with s_frame_interval. - */ - int fie_num = sensor->frame_interval.numerator; - int fie_denom = sensor->frame_interval.denominator; - - vblank = ((fie_num * pixel_rate / fie_denom) / timings->htot) - - mode->height; - } - __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, OV5640_MAX_VTS - mode->height, 1, vblank); __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank); @@ -2975,8 +2961,7 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd, goto out; } - ret = ov5640_try_fmt_internal(sd, mbus_fmt, - sensor->current_fr, &new_mode); + ret = ov5640_try_fmt_internal(sd, mbus_fmt, &new_mode); if (ret) goto out; @@ -3851,7 +3836,7 @@ static int ov5640_probe(struct i2c_client *client) /* * default init sequence initialize sensor to - * YUV422 UYVY VGA@30fps + * YUV422 UYVY VGA(30FPS in parallel mode, 60 in MIPI CSI-2 mode) */ sensor->frame_interval.numerator = 1; sensor->frame_interval.denominator = ov5640_framerates[OV5640_30_FPS]; @@ -4011,7 +3996,7 @@ static struct i2c_driver ov5640_i2c_driver = { .pm = &ov5640_pm_ops, }, .id_table = ov5640_id, - .probe_new = ov5640_probe, + .probe = ov5640_probe, .remove = ov5640_remove, }; diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index c8999fc4f26f..a70db7e601a4 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -1286,7 +1286,7 @@ static struct i2c_driver ov5645_i2c_driver = { .name = "ov5645", .pm = &ov5645_pm_ops, }, - .probe_new = ov5645_probe, + .probe = ov5645_probe, .remove = ov5645_remove, .id_table = ov5645_id, }; diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 233576ee9503..8de398423b7c 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -1515,7 +1515,7 @@ static struct i2c_driver ov5647_driver = { .name = "ov5647", .pm = &ov5647_pm_ops, }, - .probe_new = ov5647_probe, + .probe = ov5647_probe, .remove = ov5647_remove, .id_table = ov5647_id, }; diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c index 17465fcf28e3..aa10eb4e3991 100644 --- a/drivers/media/i2c/ov5648.c +++ b/drivers/media/i2c/ov5648.c @@ -2616,8 +2616,8 @@ static struct i2c_driver ov5648_driver = { .of_match_table = ov5648_of_match, .pm = &ov5648_pm_ops, }, - .probe_new = ov5648_probe, - .remove = ov5648_remove, + .probe = ov5648_probe, + .remove = ov5648_remove, }; module_i2c_driver(ov5648_driver); diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index c026610d0f31..d722348b938b 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -2853,7 +2853,7 @@ static struct i2c_driver ov5670_i2c_driver = { .acpi_match_table = ACPI_PTR(ov5670_acpi_ids), .of_match_table = ov5670_of_ids, }, - .probe_new = ov5670_probe, + .probe = ov5670_probe, .remove = ov5670_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index d55180b3b7aa..700c4b69846f 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -1435,7 +1435,7 @@ static struct i2c_driver ov5675_i2c_driver = { .acpi_match_table = ACPI_PTR(ov5675_acpi_ids), .of_match_table = ov5675_of_match, }, - .probe_new = ov5675_probe, + .probe = ov5675_probe, .remove = ov5675_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index e3c3bed69ad6..7f9212cce239 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c @@ -404,8 +404,8 @@ static int ov5693_read_reg(struct ov5693_device *ov5693, u32 addr, u32 *value) ret = i2c_transfer(client->adapter, msg, 2); if (ret < 0) return dev_err_probe(&client->dev, ret, - "Failed to read register 0x%04x: %d\n", - addr & OV5693_REG_ADDR_MASK, ret); + "Failed to read register 0x%04x\n", + addr & OV5693_REG_ADDR_MASK); *value = 0; for (i = 0; i < len; ++i) { @@ -1554,7 +1554,7 @@ static struct i2c_driver ov5693_driver = { .of_match_table = ov5693_of_match, .pm = &ov5693_pm_ops, }, - .probe_new = ov5693_probe, + .probe = ov5693_probe, .remove = ov5693_remove, }; module_i2c_driver(ov5693_driver); diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index b287c28920a6..3023b7254167 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -1392,8 +1392,8 @@ static struct i2c_driver ov5695_i2c_driver = { .pm = &ov5695_pm_ops, .of_match_table = of_match_ptr(ov5695_of_match), }, - .probe_new = &ov5695_probe, - .remove = &ov5695_remove, + .probe = ov5695_probe, + .remove = ov5695_remove, }; module_i2c_driver(ov5695_i2c_driver); diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index 4c0ea2ae671b..1ad07935f046 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c @@ -1113,7 +1113,7 @@ static struct i2c_driver ov6650_i2c_driver = { .driver = { .name = "ov6650", }, - .probe_new = ov6650_probe, + .probe = ov6650_probe, .remove = ov6650_remove, .id_table = ov6650_id, }; diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c index 88e987435285..675fb37a6fea 100644 --- a/drivers/media/i2c/ov7251.c +++ b/drivers/media/i2c/ov7251.c @@ -1806,7 +1806,7 @@ static struct i2c_driver ov7251_i2c_driver = { .name = "ov7251", .pm = &ov7251_pm_ops, }, - .probe_new = ov7251_probe, + .probe = ov7251_probe, .remove = ov7251_remove, }; diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c index e6751d5cc64b..293f5f404358 100644 --- a/drivers/media/i2c/ov7640.c +++ b/drivers/media/i2c/ov7640.c @@ -86,7 +86,7 @@ static struct i2c_driver ov7640_driver = { .driver = { .name = "ov7640", }, - .probe_new = ov7640_probe, + .probe = ov7640_probe, .remove = ov7640_remove, .id_table = ov7640_id, }; diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index ecbded4f0765..2f55491ef571 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -2033,7 +2033,7 @@ static struct i2c_driver ov7670_driver = { .name = "ov7670", .of_match_table = of_match_ptr(ov7670_of_match), }, - .probe_new = ov7670_probe, + .probe = ov7670_probe, .remove = ov7670_remove, .id_table = ov7670_id, }; diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c index a238e63425f8..386d69c8e074 100644 --- a/drivers/media/i2c/ov772x.c +++ b/drivers/media/i2c/ov772x.c @@ -1551,7 +1551,7 @@ static struct i2c_driver ov772x_i2c_driver = { .name = "ov772x", .of_match_table = ov772x_of_match, }, - .probe_new = ov772x_probe, + .probe = ov772x_probe, .remove = ov772x_remove, .id_table = ov772x_id, }; diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index c9fd9b0bc54a..10e47c7d4e0c 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c @@ -1212,7 +1212,7 @@ static struct i2c_driver ov7740_i2c_driver = { .pm = &ov7740_pm_ops, .of_match_table = of_match_ptr(ov7740_of_match), }, - .probe_new = ov7740_probe, + .probe = ov7740_probe, .remove = ov7740_remove, .id_table = ov7740_id, }; diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index b5c7881383ca..f053c3a7676a 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -2527,7 +2527,7 @@ static struct i2c_driver ov8856_i2c_driver = { .acpi_match_table = ACPI_PTR(ov8856_acpi_ids), .of_match_table = ov8856_of_match, }, - .probe_new = ov8856_probe, + .probe = ov8856_probe, .remove = ov8856_remove, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c index 9ca8a17bfbb9..3af6125a2eee 100644 --- a/drivers/media/i2c/ov8858.c +++ b/drivers/media/i2c/ov8858.c @@ -1998,8 +1998,8 @@ static struct i2c_driver ov8858_i2c_driver = { .pm = &ov8858_pm_ops, .of_match_table = ov8858_of_match, }, - .probe_new = &ov8858_probe, - .remove = &ov8858_remove, + .probe = ov8858_probe, + .remove = ov8858_remove, }; module_i2c_driver(ov8858_i2c_driver); diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index cae1866134a0..f2213c6158d3 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -3158,8 +3158,8 @@ static struct i2c_driver ov8865_driver = { .acpi_match_table = ov8865_acpi_match, .pm = &ov8865_pm_ops, }, - .probe_new = ov8865_probe, - .remove = ov8865_remove, + .probe = ov8865_probe, + .remove = ov8865_remove, }; module_i2c_driver(ov8865_driver); diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c index 7f46cac38aab..068c7449f50e 100644 --- a/drivers/media/i2c/ov9282.c +++ b/drivers/media/i2c/ov9282.c @@ -1512,7 +1512,7 @@ static const struct of_device_id ov9282_of_match[] = { MODULE_DEVICE_TABLE(of, ov9282_of_match); static struct i2c_driver ov9282_driver = { - .probe_new = ov9282_probe, + .probe = ov9282_probe, .remove = ov9282_remove, .driver = { .name = "ov9282", diff --git a/drivers/media/i2c/ov9640.c b/drivers/media/i2c/ov9640.c index a80fa59bf2ae..cbaea049531d 100644 --- a/drivers/media/i2c/ov9640.c +++ b/drivers/media/i2c/ov9640.c @@ -762,7 +762,7 @@ static struct i2c_driver ov9640_i2c_driver = { .driver = { .name = "ov9640", }, - .probe_new = ov9640_probe, + .probe = ov9640_probe, .remove = ov9640_remove, .id_table = ov9640_id, }; diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 7e7cb1e4520e..da1ab5135eaa 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1571,7 +1571,7 @@ static struct i2c_driver ov965x_i2c_driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(ov965x_of_match), }, - .probe_new = ov965x_probe, + .probe = ov965x_probe, .remove = ov965x_remove, .id_table = ov965x_id, }; diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index 8b0a158cb297..b6244772bc59 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -1028,7 +1028,7 @@ static struct i2c_driver ov9734_i2c_driver = { .pm = &ov9734_pm_ops, .acpi_match_table = ov9734_acpi_ids, }, - .probe_new = ov9734_probe, + .probe = ov9734_probe, .remove = ov9734_remove, }; diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index a2263fa825b5..01a2596282f0 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -676,7 +676,7 @@ static struct i2c_driver rdacm20_i2c_driver = { .name = "rdacm20", .of_match_table = rdacm20_of_ids, }, - .probe_new = rdacm20_probe, + .probe = rdacm20_probe, .remove = rdacm20_remove, .shutdown = rdacm20_shutdown, }; diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 9ccc56c30d3b..043fec778a5e 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -635,7 +635,7 @@ static struct i2c_driver rdacm21_i2c_driver = { .name = "rdacm21", .of_match_table = rdacm21_of_ids, }, - .probe_new = rdacm21_probe, + .probe = rdacm21_probe, .remove = rdacm21_remove, }; diff --git a/drivers/media/i2c/rj54n1cb0c.c b/drivers/media/i2c/rj54n1cb0c.c index 9db5473daba0..b430046f9e2a 100644 --- a/drivers/media/i2c/rj54n1cb0c.c +++ b/drivers/media/i2c/rj54n1cb0c.c @@ -1421,7 +1421,7 @@ static struct i2c_driver rj54n1_i2c_driver = { .driver = { .name = "rj54n1cb0c", }, - .probe_new = rj54n1_probe, + .probe = rj54n1_probe, .remove = rj54n1_remove, .id_table = rj54n1_id, }; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 7938a3327d3e..ed5b10731a14 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1729,7 +1729,7 @@ static struct i2c_driver s5c73m3_i2c_driver = { .of_match_table = of_match_ptr(s5c73m3_of_match), .name = DRIVER_NAME, }, - .probe_new = s5c73m3_probe, + .probe = s5c73m3_probe, .remove = s5c73m3_remove, .id_table = s5c73m3_id, }; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 960fbf6428ea..67da2045f543 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -2021,7 +2021,7 @@ static struct i2c_driver s5k5baf_i2c_driver = { .of_match_table = s5k5baf_of_match, .name = S5K5BAF_DRIVER_NAME }, - .probe_new = s5k5baf_probe, + .probe = s5k5baf_probe, .remove = s5k5baf_remove, .id_table = s5k5baf_id, }; diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index ef6673b10580..b3560c8f8b41 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -373,7 +373,7 @@ static struct i2c_driver s5k6a3_driver = { .of_match_table = of_match_ptr(s5k6a3_of_match), .name = S5K6A3_DRV_NAME, }, - .probe_new = s5k6a3_probe, + .probe = s5k6a3_probe, .remove = s5k6a3_remove, .id_table = s5k6a3_ids, }; diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c index 8752f7cff611..dea9fc09356f 100644 --- a/drivers/media/i2c/saa6588.c +++ b/drivers/media/i2c/saa6588.c @@ -505,7 +505,7 @@ static struct i2c_driver saa6588_driver = { .driver = { .name = "saa6588", }, - .probe_new = saa6588_probe, + .probe = saa6588_probe, .remove = saa6588_remove, .id_table = saa6588_id, }; diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index 892d64fe6e81..c106e7a7d1f4 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -781,7 +781,7 @@ static struct i2c_driver saa6752hs_driver = { .driver = { .name = "saa6752hs", }, - .probe_new = saa6752hs_probe, + .probe = saa6752hs_probe, .remove = saa6752hs_remove, .id_table = saa6752hs_id, }; diff --git a/drivers/media/i2c/saa7110.c b/drivers/media/i2c/saa7110.c index b58e71517376..1520790338ce 100644 --- a/drivers/media/i2c/saa7110.c +++ b/drivers/media/i2c/saa7110.c @@ -448,7 +448,7 @@ static struct i2c_driver saa7110_driver = { .driver = { .name = "saa7110", }, - .probe_new = saa7110_probe, + .probe = saa7110_probe, .remove = saa7110_remove, .id_table = saa7110_id, }; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index efeda3956f81..a1c71187e773 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1951,7 +1951,7 @@ static struct i2c_driver saa711x_driver = { .driver = { .name = "saa7115", }, - .probe_new = saa711x_probe, + .probe = saa711x_probe, .remove = saa711x_remove, .id_table = saa711x_id, }; diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c index f98f3a1c38a9..818ed19cf37b 100644 --- a/drivers/media/i2c/saa7127.c +++ b/drivers/media/i2c/saa7127.c @@ -810,7 +810,7 @@ static struct i2c_driver saa7127_driver = { .driver = { .name = "saa7127", }, - .probe_new = saa7127_probe, + .probe = saa7127_probe, .remove = saa7127_remove, .id_table = saa7127_id, }; diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index df01059076fa..933ec0171430 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -1343,7 +1343,7 @@ static struct i2c_driver saa717x_driver = { .driver = { .name = "saa717x", }, - .probe_new = saa717x_probe, + .probe = saa717x_probe, .remove = saa717x_remove, .id_table = saa717x_id, }; diff --git a/drivers/media/i2c/saa7185.c b/drivers/media/i2c/saa7185.c index c78f2e95ba37..5535d71f4860 100644 --- a/drivers/media/i2c/saa7185.c +++ b/drivers/media/i2c/saa7185.c @@ -343,7 +343,7 @@ static struct i2c_driver saa7185_driver = { .driver = { .name = "saa7185", }, - .probe_new = saa7185_probe, + .probe = saa7185_probe, .remove = saa7185_remove, .id_table = saa7185_id, }; diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c index eef6c8a7c9c9..0f53834f3ae4 100644 --- a/drivers/media/i2c/sony-btf-mpx.c +++ b/drivers/media/i2c/sony-btf-mpx.c @@ -375,7 +375,7 @@ static struct i2c_driver sony_btf_mpx_driver = { .driver = { .name = "sony-btf-mpx", }, - .probe_new = sony_btf_mpx_probe, + .probe = sony_btf_mpx_probe, .remove = sony_btf_mpx_remove, .id_table = sony_btf_mpx_id, }; diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c index 31b89aff0e86..906553a28676 100644 --- a/drivers/media/i2c/st-mipid02.c +++ b/drivers/media/i2c/st-mipid02.c @@ -736,8 +736,13 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, { struct mipid02_dev *bridge = to_mipid02_dev(sd); - /* source pad mirror active sink pad */ - format->format = bridge->fmt; + /* source pad mirror sink pad */ + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + format->format = bridge->fmt; + else + format->format = *v4l2_subdev_get_try_format(sd, sd_state, + MIPID02_SINK_0); + /* but code may need to be converted */ format->format.code = serial_to_parallel_code(format->format.code); @@ -745,7 +750,8 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, if (format->which != V4L2_SUBDEV_FORMAT_TRY) return; - *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format; + *v4l2_subdev_get_try_format(sd, sd_state, MIPID02_SOURCE) = + format->format; } static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, @@ -763,6 +769,9 @@ static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, fmt = &bridge->fmt; *fmt = format->format; + + /* Propagate the format change to the source pad */ + mipid02_set_fmt_source(sd, sd_state, format); } static int mipid02_set_fmt(struct v4l2_subdev *sd, @@ -1091,7 +1100,7 @@ static struct i2c_driver mipid02_i2c_driver = { .name = "st-mipid02", .of_match_table = mipid02_dt_ids, }, - .probe_new = mipid02_probe, + .probe = mipid02_probe, .remove = mipid02_remove, }; diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index adbd093ad190..30f82ca344c4 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -1951,7 +1951,7 @@ static struct i2c_driver vgxy61_i2c_driver = { .of_match_table = vgxy61_dt_ids, .pm = &vgxy61_pm_ops, }, - .probe_new = vgxy61_probe, + .probe = vgxy61_probe, .remove = vgxy61_remove, }; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 9197fa0b1bc2..15f8163be9bf 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2206,7 +2206,7 @@ static struct i2c_driver tc358743_driver = { .name = "tc358743", .of_match_table = of_match_ptr(tc358743_of_match), }, - .probe_new = tc358743_probe, + .probe = tc358743_probe, .remove = tc358743_remove, .id_table = tc358743_id, }; diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index ec1a193ba161..e9b2d906c177 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -1686,7 +1686,7 @@ static struct i2c_driver tc358746_driver = { .pm = pm_ptr(&tc358746_pm_ops), .of_match_table = tc358746_of_match, }, - .probe_new = tc358746_probe, + .probe = tc358746_probe, .remove = tc358746_remove, }; diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 27f6393dc327..325e99125941 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2834,7 +2834,7 @@ static struct i2c_driver tda1997x_i2c_driver = { .name = "tda1997x", .of_match_table = of_match_ptr(tda1997x_of_id), }, - .probe_new = tda1997x_probe, + .probe = tda1997x_probe, .remove = tda1997x_remove, .id_table = tda1997x_i2c_id, }; diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c index bbceaac8e0b3..6ecdc8e2e0c6 100644 --- a/drivers/media/i2c/tda7432.c +++ b/drivers/media/i2c/tda7432.c @@ -409,7 +409,7 @@ static struct i2c_driver tda7432_driver = { .driver = { .name = "tda7432", }, - .probe_new = tda7432_probe, + .probe = tda7432_probe, .remove = tda7432_remove, .id_table = tda7432_id, }; diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c index 25fbd7e3950e..1911ef2126be 100644 --- a/drivers/media/i2c/tda9840.c +++ b/drivers/media/i2c/tda9840.c @@ -191,7 +191,7 @@ static struct i2c_driver tda9840_driver = { .driver = { .name = "tda9840", }, - .probe_new = tda9840_probe, + .probe = tda9840_probe, .remove = tda9840_remove, .id_table = tda9840_id, }; diff --git a/drivers/media/i2c/tea6415c.c b/drivers/media/i2c/tea6415c.c index d375d2d24354..3ed6e441d515 100644 --- a/drivers/media/i2c/tea6415c.c +++ b/drivers/media/i2c/tea6415c.c @@ -150,7 +150,7 @@ static struct i2c_driver tea6415c_driver = { .driver = { .name = "tea6415c", }, - .probe_new = tea6415c_probe, + .probe = tea6415c_probe, .remove = tea6415c_remove, .id_table = tea6415c_id, }; diff --git a/drivers/media/i2c/tea6420.c b/drivers/media/i2c/tea6420.c index 9da1f3b02c57..63f23784bb41 100644 --- a/drivers/media/i2c/tea6420.c +++ b/drivers/media/i2c/tea6420.c @@ -132,7 +132,7 @@ static struct i2c_driver tea6420_driver = { .driver = { .name = "tea6420", }, - .probe_new = tea6420_probe, + .probe = tea6420_probe, .remove = tea6420_remove, .id_table = tea6420_id, }; diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index 67de90cf696e..ea70c1c13872 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c @@ -376,7 +376,7 @@ static struct i2c_driver ths7303_driver = { .driver = { .name = "ths73x3", }, - .probe_new = ths7303_probe, + .probe = ths7303_probe, .remove = ths7303_remove, .id_table = ths7303_id, }; diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 081ef5a4b950..0e0f676cd221 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -499,7 +499,7 @@ static struct i2c_driver ths8200_driver = { .name = "ths8200", .of_match_table = of_match_ptr(ths8200_of_match), }, - .probe_new = ths8200_probe, + .probe = ths8200_probe, .remove = ths8200_remove, .id_table = ths8200_id, }; diff --git a/drivers/media/i2c/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c index 47198e803817..d800ff8af1ff 100644 --- a/drivers/media/i2c/tlv320aic23b.c +++ b/drivers/media/i2c/tlv320aic23b.c @@ -197,7 +197,7 @@ static struct i2c_driver tlv320aic23b_driver = { .driver = { .name = "tlv320aic23b", }, - .probe_new = tlv320aic23b_probe, + .probe = tlv320aic23b_probe, .remove = tlv320aic23b_remove, .id_table = tlv320aic23b_id, }; diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index a54c76d9e23b..ba20f35cafd5 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -2095,7 +2095,7 @@ static struct i2c_driver tvaudio_driver = { .driver = { .name = "tvaudio", }, - .probe_new = tvaudio_probe, + .probe = tvaudio_probe, .remove = tvaudio_remove, .id_table = tvaudio_id, }; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index f294cae72b01..aa6d4b67b6d5 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1208,7 +1208,7 @@ static struct i2c_driver tvp514x_driver = { .of_match_table = of_match_ptr(tvp514x_of_match), .name = TVP514X_MODULE_NAME, }, - .probe_new = tvp514x_probe, + .probe = tvp514x_probe, .remove = tvp514x_remove, .id_table = tvp514x_id, }; diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 859f1cb2fa74..c7fb35ee3f9d 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -2280,7 +2280,7 @@ static struct i2c_driver tvp5150_driver = { .name = "tvp5150", .pm = &tvp5150_pm_ops, }, - .probe_new = tvp5150_probe, + .probe = tvp5150_probe, .remove = tvp5150_remove, .id_table = tvp5150_id, }; diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 4ccd218f5584..a2d7bc799849 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1079,7 +1079,7 @@ static struct i2c_driver tvp7002_driver = { .of_match_table = of_match_ptr(tvp7002_of_match), .name = TVP7002_MODULE_NAME, }, - .probe_new = tvp7002_probe, + .probe = tvp7002_probe, .remove = tvp7002_remove, .id_table = tvp7002_id, }; diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c index 710790ece11b..6a2521e3a25c 100644 --- a/drivers/media/i2c/tw2804.c +++ b/drivers/media/i2c/tw2804.c @@ -423,7 +423,7 @@ static struct i2c_driver tw2804_driver = { .driver = { .name = "tw2804", }, - .probe_new = tw2804_probe, + .probe = tw2804_probe, .remove = tw2804_remove, .id_table = tw2804_id, }; diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c index 428ee55787e1..996be3960af3 100644 --- a/drivers/media/i2c/tw9903.c +++ b/drivers/media/i2c/tw9903.c @@ -254,7 +254,7 @@ static struct i2c_driver tw9903_driver = { .driver = { .name = "tw9903", }, - .probe_new = tw9903_probe, + .probe = tw9903_probe, .remove = tw9903_remove, .id_table = tw9903_id, }; diff --git a/drivers/media/i2c/tw9906.c b/drivers/media/i2c/tw9906.c index 7824ed9b04ed..25c625f6d6e4 100644 --- a/drivers/media/i2c/tw9906.c +++ b/drivers/media/i2c/tw9906.c @@ -222,7 +222,7 @@ static struct i2c_driver tw9906_driver = { .driver = { .name = "tw9906", }, - .probe_new = tw9906_probe, + .probe = tw9906_probe, .remove = tw9906_remove, .id_table = tw9906_id, }; diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c index 459fa22f4341..477a64d8f8ab 100644 --- a/drivers/media/i2c/tw9910.c +++ b/drivers/media/i2c/tw9910.c @@ -1012,7 +1012,7 @@ static struct i2c_driver tw9910_i2c_driver = { .driver = { .name = "tw9910", }, - .probe_new = tw9910_probe, + .probe = tw9910_probe, .remove = tw9910_remove, .id_table = tw9910_id, }; diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c index b6873d866272..da7bc4700bed 100644 --- a/drivers/media/i2c/uda1342.c +++ b/drivers/media/i2c/uda1342.c @@ -88,7 +88,7 @@ static struct i2c_driver uda1342_driver = { .driver = { .name = "uda1342", }, - .probe_new = uda1342_probe, + .probe = uda1342_probe, .remove = uda1342_remove, .id_table = uda1342_id, }; diff --git a/drivers/media/i2c/upd64031a.c b/drivers/media/i2c/upd64031a.c index 47eed3aab060..54c2ba0ba375 100644 --- a/drivers/media/i2c/upd64031a.c +++ b/drivers/media/i2c/upd64031a.c @@ -228,7 +228,7 @@ static struct i2c_driver upd64031a_driver = { .driver = { .name = "upd64031a", }, - .probe_new = upd64031a_probe, + .probe = upd64031a_probe, .remove = upd64031a_remove, .id_table = upd64031a_id, }; diff --git a/drivers/media/i2c/upd64083.c b/drivers/media/i2c/upd64083.c index 3f5a7d4853a1..2a820589a4cb 100644 --- a/drivers/media/i2c/upd64083.c +++ b/drivers/media/i2c/upd64083.c @@ -199,7 +199,7 @@ static struct i2c_driver upd64083_driver = { .driver = { .name = "upd64083", }, - .probe_new = upd64083_probe, + .probe = upd64083_probe, .remove = upd64083_remove, .id_table = upd64083_id, }; diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c index dddf9827b314..6f98abc7ccc1 100644 --- a/drivers/media/i2c/video-i2c.c +++ b/drivers/media/i2c/video-i2c.c @@ -274,7 +274,7 @@ static const struct hwmon_channel_info amg88xx_temp = { .config = amg88xx_temp_config, }; -static const struct hwmon_channel_info *amg88xx_info[] = { +static const struct hwmon_channel_info * const amg88xx_info[] = { &amg88xx_temp, NULL }; @@ -959,7 +959,7 @@ static struct i2c_driver video_i2c_driver = { .of_match_table = video_i2c_of_match, .pm = &video_i2c_pm_ops, }, - .probe_new = video_i2c_probe, + .probe = video_i2c_probe, .remove = video_i2c_remove, .id_table = video_i2c_id_table, }; diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c index ed1c58ea8ed3..0ba3c2b68037 100644 --- a/drivers/media/i2c/vp27smpx.c +++ b/drivers/media/i2c/vp27smpx.c @@ -181,7 +181,7 @@ static struct i2c_driver vp27smpx_driver = { .driver = { .name = "vp27smpx", }, - .probe_new = vp27smpx_probe, + .probe = vp27smpx_probe, .remove = vp27smpx_remove, .id_table = vp27smpx_id, }; diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c index aa73d5dcc3e7..1eaae886f217 100644 --- a/drivers/media/i2c/vpx3220.c +++ b/drivers/media/i2c/vpx3220.c @@ -546,7 +546,7 @@ static struct i2c_driver vpx3220_driver = { .driver = { .name = "vpx3220", }, - .probe_new = vpx3220_probe, + .probe = vpx3220_probe, .remove = vpx3220_remove, .id_table = vpx3220_id, }; diff --git a/drivers/media/i2c/wm8739.c b/drivers/media/i2c/wm8739.c index 8b34a673ffd3..19bf7a00dff9 100644 --- a/drivers/media/i2c/wm8739.c +++ b/drivers/media/i2c/wm8739.c @@ -252,7 +252,7 @@ static struct i2c_driver wm8739_driver = { .driver = { .name = "wm8739", }, - .probe_new = wm8739_probe, + .probe = wm8739_probe, .remove = wm8739_remove, .id_table = wm8739_id, }; diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c index 56d98518f7eb..d1b716fd6f11 100644 --- a/drivers/media/i2c/wm8775.c +++ b/drivers/media/i2c/wm8775.c @@ -298,7 +298,7 @@ static struct i2c_driver wm8775_driver = { .driver = { .name = "wm8775", }, - .probe_new = wm8775_probe, + .probe = wm8775_probe, .remove = wm8775_remove, .id_table = wm8775_id, }; diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index e7216a985ba6..83468d4a440b 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -1052,25 +1052,19 @@ static void __media_entity_remove_link(struct media_entity *entity, kfree(link); } -int media_get_pad_index(struct media_entity *entity, bool is_sink, +int media_get_pad_index(struct media_entity *entity, u32 pad_type, enum media_pad_signal_type sig_type) { - int i; - bool pad_is_sink; + unsigned int i; if (!entity) return -EINVAL; for (i = 0; i < entity->num_pads; i++) { - if (entity->pads[i].flags & MEDIA_PAD_FL_SINK) - pad_is_sink = true; - else if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE) - pad_is_sink = false; - else - continue; /* This is an error! */ - - if (pad_is_sink != is_sink) + if ((entity->pads[i].flags & + (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE)) != pad_type) continue; + if (entity->pads[i].sig_type == sig_type) return i; } @@ -1416,7 +1410,7 @@ struct media_pad *media_pad_remote_pad_unique(const struct media_pad *pad) EXPORT_SYMBOL_GPL(media_pad_remote_pad_unique); int media_entity_get_fwnode_pad(struct media_entity *entity, - struct fwnode_handle *fwnode, + const struct fwnode_handle *fwnode, unsigned long direction_flags) { struct fwnode_endpoint endpoint; diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index 85fcdc59f0d1..d234a0f404d6 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -534,7 +534,7 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct mutex_lock(&dst_ca_mutex); dvbdev = file->private_data; - state = (struct dst_state *)dvbdev->priv; + state = dvbdev->priv; p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); diff --git a/drivers/media/pci/cx18/cx18-av-vbi.c b/drivers/media/pci/cx18/cx18-av-vbi.c index a0d465924e75..65281d40c681 100644 --- a/drivers/media/pci/cx18/cx18-av-vbi.c +++ b/drivers/media/pci/cx18/cx18-av-vbi.c @@ -51,7 +51,7 @@ struct vbi_anc_data { u8 sdid; u8 data_count; u8 idid[2]; - u8 payload[1]; /* data_count of payload */ + u8 payload[]; /* data_count of payload */ /* u8 checksum; */ /* u8 fill[]; Variable number of fill bytes */ }; diff --git a/drivers/media/pci/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c index 33e5a5b5fab4..cf82360a503d 100644 --- a/drivers/media/pci/cx18/cx18-dvb.c +++ b/drivers/media/pci/cx18/cx18-dvb.c @@ -234,7 +234,7 @@ static int dvb_register(struct cx18_stream *stream); static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct cx18_stream *stream = (struct cx18_stream *) demux->priv; + struct cx18_stream *stream = demux->priv; struct cx18 *cx; int ret; u32 v; @@ -305,7 +305,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct cx18_stream *stream = (struct cx18_stream *)demux->priv; + struct cx18_stream *stream = demux->priv; struct cx18 *cx; int ret = -EINVAL; diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c index 3c84cb121632..34984a7474ed 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -1375,7 +1375,8 @@ struct sensor_async_subdev { struct csi2_bus_info csi2; }; -#define to_sensor_asd(asd) container_of(asd, struct sensor_async_subdev, asd) +#define to_sensor_asd(__asd) \ + container_of_const(__asd, struct sensor_async_subdev, asd) /* The .bound() notifier callback when a match is found */ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, @@ -1417,31 +1418,27 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) struct sensor_async_subdev *s_asd; struct v4l2_async_subdev *asd; struct cio2_queue *q; - unsigned int pad; int ret; list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) { s_asd = to_sensor_asd(asd); q = &cio2->queue[s_asd->csi2.port]; - for (pad = 0; pad < q->sensor->entity.num_pads; pad++) - if (q->sensor->entity.pads[pad].flags & - MEDIA_PAD_FL_SOURCE) - break; - - if (pad == q->sensor->entity.num_pads) { - dev_err(dev, "failed to find src pad for %s\n", - q->sensor->name); - return -ENXIO; + ret = media_entity_get_fwnode_pad(&q->sensor->entity, + s_asd->asd.match.fwnode, + MEDIA_PAD_FL_SOURCE); + if (ret < 0) { + dev_err(dev, "no pad for endpoint %pfw (%d)\n", + s_asd->asd.match.fwnode, ret); + return ret; } - ret = media_create_pad_link( - &q->sensor->entity, pad, - &q->subdev.entity, CIO2_PAD_SINK, - 0); + ret = media_create_pad_link(&q->sensor->entity, ret, + &q->subdev.entity, CIO2_PAD_SINK, + 0); if (ret) { - dev_err(dev, "failed to create link for %s\n", - q->sensor->name); + dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n", + q->sensor->name, s_asd->asd.match.fwnode, ret); return ret; } } diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 24421c116b0b..3eb749db1ca7 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -280,7 +280,7 @@ out: static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct saa7164_port *port = (struct saa7164_port *) demux->priv; + struct saa7164_port *port = demux->priv; struct saa7164_dvb *dvb = &port->dvb; struct saa7164_dev *dev = port->dev; int ret = 0; @@ -307,7 +307,7 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct saa7164_port *port = (struct saa7164_port *) demux->priv; + struct saa7164_port *port = demux->priv; struct saa7164_dvb *dvb = &port->dvb; struct saa7164_dev *dev = port->dev; int ret = 0; diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index 5d5796f24469..710595987522 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -308,7 +308,7 @@ int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, static int budget_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; + struct budget *budget = demux->priv; int status = 0; dprintk(2, "budget: %p\n", budget); @@ -327,7 +327,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) static int budget_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; + struct budget *budget = demux->priv; int status = 0; dprintk(2, "budget: %p\n", budget); diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 3fa1a74a2e20..6515f3cdb7a7 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -279,6 +279,7 @@ static void vdec_handle_resolution_change(struct vpu_inst *inst) vdec->source_change--; vpu_notify_source_change(inst); + vpu_set_last_buffer_dequeued(inst, false); } static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force) @@ -314,7 +315,7 @@ static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst) return; if (vdec->eos_received) { - if (!vpu_set_last_buffer_dequeued(inst)) { + if (!vpu_set_last_buffer_dequeued(inst, true)) { vdec->eos_received--; vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0); } @@ -569,7 +570,7 @@ static int vdec_drain(struct vpu_inst *inst) return 0; if (!vdec->params.frame_count) { - vpu_set_last_buffer_dequeued(inst); + vpu_set_last_buffer_dequeued(inst, true); return 0; } @@ -608,7 +609,7 @@ static int vdec_cmd_stop(struct vpu_inst *inst) vpu_trace(inst->dev, "[%d]\n", inst->id); if (inst->state == VPU_CODEC_STATE_DEINIT) { - vpu_set_last_buffer_dequeued(inst); + vpu_set_last_buffer_dequeued(inst, true); } else { vdec->drain = 1; vdec_drain(inst); diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c index e6e8fe45fc7c..58480e2755ec 100644 --- a/drivers/media/platform/amphion/venc.c +++ b/drivers/media/platform/amphion/venc.c @@ -458,7 +458,7 @@ static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd vpu_inst_lock(inst); if (cmd->cmd == V4L2_ENC_CMD_STOP) { if (inst->state == VPU_CODEC_STATE_DEINIT) - vpu_set_last_buffer_dequeued(inst); + vpu_set_last_buffer_dequeued(inst, true); else venc_request_eos(inst); } @@ -878,7 +878,7 @@ static void venc_set_last_buffer_dequeued(struct vpu_inst *inst) struct venc_t *venc = inst->priv; if (venc->stopped && list_empty(&venc->frames)) - vpu_set_last_buffer_dequeued(inst); + vpu_set_last_buffer_dequeued(inst, true); } static void venc_stop_done(struct vpu_inst *inst) diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index ef44bff9fbaf..c1d6606ad7e5 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -1313,6 +1313,15 @@ static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_i return sizeof(hdr); } +static int vpu_malone_insert_scode_vc1_g_seq(struct malone_scode_t *scode) +{ + if (!scode->inst->total_input_count) + return 0; + if (vpu_vb_is_codecconfig(to_vb2_v4l2_buffer(scode->vb))) + scode->need_data = 0; + return 0; +} + static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode) { struct vb2_v4l2_buffer *vbuf; @@ -1344,6 +1353,8 @@ static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode) int size = 0; u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN]; + if (vpu_vb_is_codecconfig(to_vb2_v4l2_buffer(scode->vb))) + scode->need_data = 0; if (scode->inst->total_input_count) return 0; scode->need_data = 0; @@ -1458,6 +1469,7 @@ static const struct malone_scode_handler scode_handlers[] = { }, { .pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G, + .insert_scode_seq = vpu_malone_insert_scode_vc1_g_seq, .insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic, }, { diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 6773b885597c..810e93d2c954 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -100,7 +100,7 @@ int vpu_notify_source_change(struct vpu_inst *inst) return 0; } -int vpu_set_last_buffer_dequeued(struct vpu_inst *inst) +int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos) { struct vb2_queue *q; @@ -116,7 +116,8 @@ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst) vpu_trace(inst->dev, "last buffer dequeued\n"); q->last_buffer_dequeued = true; wake_up(&q->done_wq); - vpu_notify_eos(inst); + if (eos) + vpu_notify_eos(inst); return 0; } diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h index ef5de6b66e47..60f43056a7a2 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.h +++ b/drivers/media/platform/amphion/vpu_v4l2.h @@ -27,7 +27,7 @@ struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 void vpu_v4l2_set_error(struct vpu_inst *inst); int vpu_notify_eos(struct vpu_inst *inst); int vpu_notify_source_change(struct vpu_inst *inst); -int vpu_set_last_buffer_dequeued(struct vpu_inst *inst); +int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos); void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state); int vpu_get_num_buffers(struct vpu_inst *inst, u32 type); bool vpu_is_source_empty(struct vpu_inst *inst); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 0051f372a66c..4768156181c9 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -28,6 +28,7 @@ #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" +#if defined(CONFIG_OF) static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, @@ -101,6 +102,7 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { .flags = MTK_JPEG_FMT_FLAG_CAPTURE, }, }; +#endif #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) @@ -936,148 +938,6 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, return 0; } -static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) -{ - struct mtk_jpegenc_comp_dev *comp_jpeg; - struct mtk_jpeg_dev *jpeg = ctx->jpeg; - unsigned long flags; - int hw_id = -1; - int i; - - spin_lock_irqsave(&jpeg->hw_lock, flags); - for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) { - comp_jpeg = jpeg->enc_hw_dev[i]; - if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { - hw_id = i; - comp_jpeg->hw_state = MTK_JPEG_HW_BUSY; - break; - } - } - spin_unlock_irqrestore(&jpeg->hw_lock, flags); - - return hw_id; -} - -static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx, - int hw_id, - struct vb2_v4l2_buffer *src_buf, - struct vb2_v4l2_buffer *dst_buf) -{ - struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id]; - - jpeg->hw_param.curr_ctx = ctx; - jpeg->hw_param.src_buffer = src_buf; - jpeg->hw_param.dst_buffer = dst_buf; - - return 0; -} - -static int mtk_jpegenc_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id) -{ - unsigned long flags; - - spin_lock_irqsave(&jpeg->hw_lock, flags); - jpeg->enc_hw_dev[hw_id]->hw_state = MTK_JPEG_HW_IDLE; - spin_unlock_irqrestore(&jpeg->hw_lock, flags); - - return 0; -} - -static void mtk_jpegenc_worker(struct work_struct *work) -{ - struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX]; - enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - struct mtk_jpeg_src_buf *jpeg_dst_buf; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - int ret, i, hw_id = 0; - unsigned long flags; - - struct mtk_jpeg_ctx *ctx = container_of(work, - struct mtk_jpeg_ctx, - jpeg_work); - struct mtk_jpeg_dev *jpeg = ctx->jpeg; - - for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) - comp_jpeg[i] = jpeg->enc_hw_dev[i]; - i = 0; - -retry_select: - hw_id = mtk_jpegenc_get_hw(ctx); - if (hw_id < 0) { - ret = wait_event_interruptible(jpeg->hw_wq, - atomic_read(&jpeg->hw_rdy) > 0); - if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) { - dev_err(jpeg->dev, "%s : %d, all HW are busy\n", - __func__, __LINE__); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - return; - } - - goto retry_select; - } - - atomic_dec(&jpeg->hw_rdy); - src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - if (!src_buf) - goto getbuf_fail; - - dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - if (!dst_buf) - goto getbuf_fail; - - v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); - - mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf); - ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); - if (ret < 0) { - dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n", - __func__, __LINE__); - goto enc_end; - } - - ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk); - if (ret) { - dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n", - __func__, __LINE__); - goto enc_end; - } - - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - - schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, - msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); - - spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); - jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); - jpeg_dst_buf->curr_ctx = ctx; - jpeg_dst_buf->frame_num = ctx->total_frame_num; - ctx->total_frame_num++; - mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base); - mtk_jpeg_set_enc_dst(ctx, - comp_jpeg[hw_id]->reg_base, - &dst_buf->vb2_buf); - mtk_jpeg_set_enc_src(ctx, - comp_jpeg[hw_id]->reg_base, - &src_buf->vb2_buf); - mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base); - mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); - - return; - -enc_end: - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_buf_done(src_buf, buf_state); - v4l2_m2m_buf_done(dst_buf, buf_state); -getbuf_fail: - atomic_inc(&jpeg->hw_rdy); - mtk_jpegenc_put_hw(jpeg, hw_id); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); -} - static void mtk_jpeg_enc_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; @@ -1128,173 +988,6 @@ static void mtk_jpeg_multicore_enc_device_run(void *priv) queue_work(jpeg->workqueue, &ctx->jpeg_work); } -static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx) -{ - struct mtk_jpegdec_comp_dev *comp_jpeg; - struct mtk_jpeg_dev *jpeg = ctx->jpeg; - unsigned long flags; - int hw_id = -1; - int i; - - spin_lock_irqsave(&jpeg->hw_lock, flags); - for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) { - comp_jpeg = jpeg->dec_hw_dev[i]; - if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { - hw_id = i; - comp_jpeg->hw_state = MTK_JPEG_HW_BUSY; - break; - } - } - spin_unlock_irqrestore(&jpeg->hw_lock, flags); - - return hw_id; -} - -static int mtk_jpegdec_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id) -{ - unsigned long flags; - - spin_lock_irqsave(&jpeg->hw_lock, flags); - jpeg->dec_hw_dev[hw_id]->hw_state = - MTK_JPEG_HW_IDLE; - spin_unlock_irqrestore(&jpeg->hw_lock, flags); - - return 0; -} - -static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx, - int hw_id, - struct vb2_v4l2_buffer *src_buf, - struct vb2_v4l2_buffer *dst_buf) -{ - struct mtk_jpegdec_comp_dev *jpeg = - ctx->jpeg->dec_hw_dev[hw_id]; - - jpeg->hw_param.curr_ctx = ctx; - jpeg->hw_param.src_buffer = src_buf; - jpeg->hw_param.dst_buffer = dst_buf; - - return 0; -} - -static void mtk_jpegdec_worker(struct work_struct *work) -{ - struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx, - jpeg_work); - struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX]; - enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - struct mtk_jpeg_dev *jpeg = ctx->jpeg; - int ret, i, hw_id = 0; - struct mtk_jpeg_bs bs; - struct mtk_jpeg_fb fb; - unsigned long flags; - - for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) - comp_jpeg[i] = jpeg->dec_hw_dev[i]; - i = 0; - -retry_select: - hw_id = mtk_jpegdec_get_hw(ctx); - if (hw_id < 0) { - ret = wait_event_interruptible_timeout(jpeg->hw_wq, - atomic_read(&jpeg->hw_rdy) > 0, - MTK_JPEG_HW_TIMEOUT_MSEC); - if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) { - dev_err(jpeg->dev, "%s : %d, all HW are busy\n", - __func__, __LINE__); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - return; - } - - goto retry_select; - } - - atomic_dec(&jpeg->hw_rdy); - src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - if (!src_buf) - goto getbuf_fail; - - dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - if (!dst_buf) - goto getbuf_fail; - - v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); - jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); - jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); - - if (mtk_jpeg_check_resolution_change(ctx, - &jpeg_src_buf->dec_param)) { - mtk_jpeg_queue_src_chg_event(ctx); - ctx->state = MTK_JPEG_SOURCE_CHANGE; - goto getbuf_fail; - } - - jpeg_src_buf->curr_ctx = ctx; - jpeg_src_buf->frame_num = ctx->total_frame_num; - jpeg_dst_buf->curr_ctx = ctx; - jpeg_dst_buf->frame_num = ctx->total_frame_num; - - mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf); - ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); - if (ret < 0) { - dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n", - __func__, __LINE__); - goto dec_end; - } - - ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk); - if (ret) { - dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n", - __func__, __LINE__); - goto clk_end; - } - - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - - schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, - msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); - - mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); - if (mtk_jpeg_set_dec_dst(ctx, - &jpeg_src_buf->dec_param, - &dst_buf->vb2_buf, &fb)) { - dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n", - __func__, __LINE__); - goto setdst_end; - } - - spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); - ctx->total_frame_num++; - mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base); - mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base, - &jpeg_src_buf->dec_param, - jpeg_src_buf->bs_size, - &bs, - &fb); - mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); - - return; - -setdst_end: - clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk); -clk_end: - pm_runtime_put(comp_jpeg[hw_id]->dev); -dec_end: - v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_buf_done(src_buf, buf_state); - v4l2_m2m_buf_done(dst_buf, buf_state); -getbuf_fail: - atomic_inc(&jpeg->hw_rdy); - mtk_jpegdec_put_hw(jpeg, hw_id); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); -} - static void mtk_jpeg_multicore_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; @@ -1430,101 +1123,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) jpeg->variant->clks); } -static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) -{ - struct mtk_jpeg_ctx *ctx; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - u32 result_size; - - ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - if (!ctx) { - v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); - return IRQ_HANDLED; - } - - src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - - result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); - vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); - - buf_state = VB2_BUF_STATE_DONE; - - v4l2_m2m_buf_done(src_buf, buf_state); - v4l2_m2m_buf_done(dst_buf, buf_state); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - pm_runtime_put(ctx->jpeg->dev); - return IRQ_HANDLED; -} - -static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) -{ - struct mtk_jpeg_dev *jpeg = priv; - u32 irq_status; - irqreturn_t ret = IRQ_NONE; - - cancel_delayed_work(&jpeg->job_timeout_work); - - irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) & - JPEG_ENC_INT_STATUS_MASK_ALLIRQ; - if (irq_status) - writel(0, jpeg->reg_base + JPEG_ENC_INT_STS); - - if (!(irq_status & JPEG_ENC_INT_STATUS_DONE)) - return ret; - - ret = mtk_jpeg_enc_done(jpeg); - return ret; -} - -static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) -{ - struct mtk_jpeg_dev *jpeg = priv; - struct mtk_jpeg_ctx *ctx; - struct vb2_v4l2_buffer *src_buf, *dst_buf; - struct mtk_jpeg_src_buf *jpeg_src_buf; - enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - u32 dec_irq_ret; - u32 dec_ret; - int i; - - cancel_delayed_work(&jpeg->job_timeout_work); - - dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base); - dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret); - ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - if (!ctx) { - v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); - return IRQ_HANDLED; - } - - src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); - - if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) - mtk_jpeg_dec_reset(jpeg->reg_base); - - if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) { - dev_err(jpeg->dev, "decode failed\n"); - goto dec_end; - } - - for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) - vb2_set_plane_payload(&dst_buf->vb2_buf, i, - jpeg_src_buf->dec_param.comp_size[i]); - - buf_state = VB2_BUF_STATE_DONE; - -dec_end: - v4l2_m2m_buf_done(src_buf, buf_state); - v4l2_m2m_buf_done(dst_buf, buf_state); - v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); - pm_runtime_put(ctx->jpeg->dev); - return IRQ_HANDLED; -} - static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) { struct mtk_jpeg_q_data *q = &ctx->out_q; @@ -1637,15 +1235,6 @@ static const struct v4l2_file_operations mtk_jpeg_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { - { .id = "jpgdec-smi" }, - { .id = "jpgdec" }, -}; - -static struct clk_bulk_data mtk_jpeg_clocks[] = { - { .id = "jpgenc" }, -}; - static void mtk_jpeg_job_timeout_work(struct work_struct *work) { struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev, @@ -1867,6 +1456,419 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { }; #if defined(CONFIG_OF) +static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) +{ + struct mtk_jpegenc_comp_dev *comp_jpeg; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + unsigned long flags; + int hw_id = -1; + int i; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) { + comp_jpeg = jpeg->enc_hw_dev[i]; + if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { + hw_id = i; + comp_jpeg->hw_state = MTK_JPEG_HW_BUSY; + break; + } + } + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + + return hw_id; +} + +static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx, + int hw_id, + struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf) +{ + struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id]; + + jpeg->hw_param.curr_ctx = ctx; + jpeg->hw_param.src_buffer = src_buf; + jpeg->hw_param.dst_buffer = dst_buf; + + return 0; +} + +static int mtk_jpegenc_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id) +{ + unsigned long flags; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + jpeg->enc_hw_dev[hw_id]->hw_state = MTK_JPEG_HW_IDLE; + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + + return 0; +} + +static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx) +{ + struct mtk_jpegdec_comp_dev *comp_jpeg; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + unsigned long flags; + int hw_id = -1; + int i; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) { + comp_jpeg = jpeg->dec_hw_dev[i]; + if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) { + hw_id = i; + comp_jpeg->hw_state = MTK_JPEG_HW_BUSY; + break; + } + } + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + + return hw_id; +} + +static int mtk_jpegdec_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id) +{ + unsigned long flags; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + jpeg->dec_hw_dev[hw_id]->hw_state = + MTK_JPEG_HW_IDLE; + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + + return 0; +} + +static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx, + int hw_id, + struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf) +{ + struct mtk_jpegdec_comp_dev *jpeg = + ctx->jpeg->dec_hw_dev[hw_id]; + + jpeg->hw_param.curr_ctx = ctx; + jpeg->hw_param.src_buffer = src_buf; + jpeg->hw_param.dst_buffer = dst_buf; + + return 0; +} + +static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) +{ + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 result_size; + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); + + buf_state = VB2_BUF_STATE_DONE; + + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + pm_runtime_put(ctx->jpeg->dev); + return IRQ_HANDLED; +} + +static void mtk_jpegenc_worker(struct work_struct *work) +{ + struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX]; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + struct mtk_jpeg_src_buf *jpeg_dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + int ret, i, hw_id = 0; + unsigned long flags; + + struct mtk_jpeg_ctx *ctx = container_of(work, + struct mtk_jpeg_ctx, + jpeg_work); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + + for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) + comp_jpeg[i] = jpeg->enc_hw_dev[i]; + i = 0; + +retry_select: + hw_id = mtk_jpegenc_get_hw(ctx); + if (hw_id < 0) { + ret = wait_event_interruptible(jpeg->hw_wq, + atomic_read(&jpeg->hw_rdy) > 0); + if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) { + dev_err(jpeg->dev, "%s : %d, all HW are busy\n", + __func__, __LINE__); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + return; + } + + goto retry_select; + } + + atomic_dec(&jpeg->hw_rdy); + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + if (!src_buf) + goto getbuf_fail; + + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + if (!dst_buf) + goto getbuf_fail; + + v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); + + mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf); + ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); + if (ret < 0) { + dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n", + __func__, __LINE__); + goto enc_end; + } + + ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk); + if (ret) { + dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n", + __func__, __LINE__); + goto enc_end; + } + + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + + spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); + jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); + jpeg_dst_buf->curr_ctx = ctx; + jpeg_dst_buf->frame_num = ctx->total_frame_num; + ctx->total_frame_num++; + mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base); + mtk_jpeg_set_enc_dst(ctx, + comp_jpeg[hw_id]->reg_base, + &dst_buf->vb2_buf); + mtk_jpeg_set_enc_src(ctx, + comp_jpeg[hw_id]->reg_base, + &src_buf->vb2_buf); + mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base); + mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); + + return; + +enc_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); +getbuf_fail: + atomic_inc(&jpeg->hw_rdy); + mtk_jpegenc_put_hw(jpeg, hw_id); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static void mtk_jpegdec_worker(struct work_struct *work) +{ + struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx, + jpeg_work); + struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX]; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + int ret, i, hw_id = 0; + struct mtk_jpeg_bs bs; + struct mtk_jpeg_fb fb; + unsigned long flags; + + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) + comp_jpeg[i] = jpeg->dec_hw_dev[i]; + i = 0; + +retry_select: + hw_id = mtk_jpegdec_get_hw(ctx); + if (hw_id < 0) { + ret = wait_event_interruptible_timeout(jpeg->hw_wq, + atomic_read(&jpeg->hw_rdy) > 0, + MTK_JPEG_HW_TIMEOUT_MSEC); + if (ret != 0 || (i++ > MTK_JPEG_MAX_RETRY_TIME)) { + dev_err(jpeg->dev, "%s : %d, all HW are busy\n", + __func__, __LINE__); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + return; + } + + goto retry_select; + } + + atomic_dec(&jpeg->hw_rdy); + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + if (!src_buf) + goto getbuf_fail; + + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + if (!dst_buf) + goto getbuf_fail; + + v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf); + + if (mtk_jpeg_check_resolution_change(ctx, + &jpeg_src_buf->dec_param)) { + mtk_jpeg_queue_src_chg_event(ctx); + ctx->state = MTK_JPEG_SOURCE_CHANGE; + goto getbuf_fail; + } + + jpeg_src_buf->curr_ctx = ctx; + jpeg_src_buf->frame_num = ctx->total_frame_num; + jpeg_dst_buf->curr_ctx = ctx; + jpeg_dst_buf->frame_num = ctx->total_frame_num; + + mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf); + ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev); + if (ret < 0) { + dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n", + __func__, __LINE__); + goto dec_end; + } + + ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk); + if (ret) { + dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n", + __func__, __LINE__); + goto clk_end; + } + + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + + mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); + if (mtk_jpeg_set_dec_dst(ctx, + &jpeg_src_buf->dec_param, + &dst_buf->vb2_buf, &fb)) { + dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n", + __func__, __LINE__); + goto setdst_end; + } + + spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); + ctx->total_frame_num++; + mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base); + mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base, + &jpeg_src_buf->dec_param, + jpeg_src_buf->bs_size, + &bs, + &fb); + mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); + + return; + +setdst_end: + clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk); +clk_end: + pm_runtime_put(comp_jpeg[hw_id]->dev); +dec_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); +getbuf_fail: + atomic_inc(&jpeg->hw_rdy); + mtk_jpegdec_put_hw(jpeg, hw_id); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + u32 irq_status; + irqreturn_t ret = IRQ_NONE; + + cancel_delayed_work(&jpeg->job_timeout_work); + + irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) & + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; + if (irq_status) + writel(0, jpeg->reg_base + JPEG_ENC_INT_STS); + + if (!(irq_status & JPEG_ENC_INT_STATUS_DONE)) + return ret; + + ret = mtk_jpeg_enc_done(jpeg); + return ret; +} + +static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_src_buf *jpeg_src_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 dec_irq_ret; + u32 dec_ret; + int i; + + cancel_delayed_work(&jpeg->job_timeout_work); + + dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base); + dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret); + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + + if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) + mtk_jpeg_dec_reset(jpeg->reg_base); + + if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) { + dev_err(jpeg->dev, "decode failed\n"); + goto dec_end; + } + + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, + jpeg_src_buf->dec_param.comp_size[i]); + + buf_state = VB2_BUF_STATE_DONE; + +dec_end: + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + pm_runtime_put(ctx->jpeg->dev); + return IRQ_HANDLED; +} + +static struct clk_bulk_data mtk_jpeg_clocks[] = { + { .id = "jpgenc" }, +}; + +static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { + { .id = "jpgdec-smi" }, + { .id = "jpgdec" }, +}; + static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = { .clks = mt8173_jpeg_dec_clocks, .num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks), diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c index b95c45791c29..bb9cdc9e0e90 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c @@ -7,15 +7,10 @@ #include <linux/kernel.h> #include <linux/videodev2.h> +#include <media/jpeg.h> #include "mtk_jpeg_dec_parse.h" -#define TEM 0x01 -#define SOF0 0xc0 -#define RST 0xd0 -#define SOI 0xd8 -#define EOI 0xd9 - struct mtk_jpeg_stream { u8 *addr; u32 size; @@ -83,7 +78,7 @@ static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va, length = 0; switch (byte) { - case SOF0: + case JPEG_MARKER_SOF0: /* length */ if (read_word_be(&stream, &word)) break; @@ -123,10 +118,10 @@ static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va, notfound = !(i == param->comp_num); break; - case RST ... RST + 7: - case SOI: - case EOI: - case TEM: + case JPEG_MARKER_RST ... JPEG_MARKER_RST + 7: + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + case JPEG_MARKER_TEM: break; default: if (read_word_be(&stream, &word)) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index 19a4a085f73a..a605e80c7dc3 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -1035,6 +1035,7 @@ static int mdp_comp_sub_create(struct mdp_dev *mdp) { struct device *dev = &mdp->pdev->dev; struct device_node *node, *parent; + int ret = 0; parent = dev->of_node->parent; @@ -1060,16 +1061,22 @@ static int mdp_comp_sub_create(struct mdp_dev *mdp) dev_err(dev, "Fail to get sub comp. id: type %d alias %d\n", type, alias_id); - return -EINVAL; + ret = -EINVAL; + goto err_free_node; } mdp_comp_alias_id[type]++; comp = mdp_comp_create(mdp, node, id); - if (IS_ERR(comp)) - return PTR_ERR(comp); + if (IS_ERR(comp)) { + ret = PTR_ERR(comp); + goto err_free_node; + } } + return ret; - return 0; +err_free_node: + of_node_put(node); + return ret; } void mdp_comp_destroy(struct mdp_dev *mdp) diff --git a/drivers/media/platform/mediatek/vcodec/Makefile b/drivers/media/platform/mediatek/vcodec/Makefile index 93e7a343b5b0..d24b452d0fb3 100644 --- a/drivers/media/platform/mediatek/vcodec/Makefile +++ b/drivers/media/platform/mediatek/vcodec/Makefile @@ -13,6 +13,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_h264_req_if.o \ vdec/vdec_h264_req_common.o \ vdec/vdec_h264_req_multi_if.o \ + vdec/vdec_hevc_req_multi_if.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c index 9c652beb3f19..7bd300341cf0 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -310,7 +310,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) { - vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE); dev->core_workqueue = alloc_ordered_workqueue("core-decoder", WQ_MEM_RECLAIM | WQ_FREEZABLE); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c index b753bf54ebd9..e1cb2f8dca33 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c @@ -148,20 +148,21 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) ret = mtk_vcodec_init_dec_clk(pdev, &subdev_dev->pm); if (ret) return ret; - pm_runtime_enable(&pdev->dev); + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; of_id = of_match_device(mtk_vdec_hw_match, dev); if (!of_id) { dev_err(dev, "Can't get vdec subdev id.\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data; if (hw_idx >= MTK_VDEC_HW_MAX) { dev_err(dev, "Hardware index %d not correct.\n", hw_idx); - ret = -EINVAL; - goto err; + return -EINVAL; } main_dev->subdev_dev[hw_idx] = subdev_dev; @@ -173,14 +174,14 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) { ret = mtk_vdec_hw_init_irq(subdev_dev); if (ret) - goto err; + return ret; } subdev_dev->reg_base[VDEC_HW_MISC] = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC])) { ret = PTR_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC]); - goto err; + return ret; } if (!main_dev->subdev_prob_done) @@ -188,21 +189,10 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) platform_set_drvdata(pdev, subdev_dev); return 0; -err: - pm_runtime_disable(subdev_dev->pm.dev); - return ret; -} - -static int mtk_vdec_hw_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - - return 0; } static struct platform_driver mtk_vdec_driver = { .probe = mtk_vdec_hw_probe, - .remove = mtk_vdec_hw_remove, .driver = { .name = "mtk-vdec-comp", .of_match_table = mtk_vdec_hw_match, diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c index 3000db975e5f..7b3eb0ccb522 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c @@ -107,11 +107,63 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { }, .codec_type = V4L2_PIX_FMT_VP9_FRAME, }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_SPS, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_PPS, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + .def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, + .menu_skip_mask = + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE, + .min = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED, + .def = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED, + .max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_HEVC_START_CODE, + .min = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B, + .def = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B, + .max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B, + }, + .codec_type = V4L2_PIX_FMT_HEVC_SLICE, + }, }; #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static struct mtk_video_fmt mtk_video_formats[5]; +static struct mtk_video_fmt mtk_video_formats[6]; static struct mtk_video_fmt default_out_format; static struct mtk_video_fmt default_cap_format; @@ -240,7 +292,7 @@ static void mtk_vdec_worker(struct work_struct *work) mtk_v4l2_err("vb2 buffer media request is NULL"); ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg); - if (ret) { + if (ret && ret != -EAGAIN) { mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>", ctx->id, vb2_src->index, bs_src->size, vb2_src->timestamp, ret, res_chg); @@ -356,6 +408,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, case V4L2_PIX_FMT_H264_SLICE: case V4L2_PIX_FMT_VP8_FRAME: case V4L2_PIX_FMT_VP9_FRAME: + case V4L2_PIX_FMT_HEVC_SLICE: mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].type = MTK_FMT_DEC; mtk_video_formats[count_formats].num_planes = 1; @@ -412,6 +465,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_vcodec_add_formats(V4L2_PIX_FMT_VP9_FRAME, ctx); out_format_count++; } + if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_HEVC_FRAME) { + mtk_vcodec_add_formats(V4L2_PIX_FMT_HEVC_SLICE, ctx); + out_format_count++; + } if (cap_format_count) default_cap_format = mtk_video_formats[cap_format_count - 1]; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h index 9acab54fd650..1f4c5774ec47 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h @@ -347,6 +347,7 @@ enum mtk_vdec_format_types { MTK_VDEC_FORMAT_H264_SLICE = 0x100, MTK_VDEC_FORMAT_VP8_FRAME = 0x200, MTK_VDEC_FORMAT_VP9_FRAME = 0x400, + MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000, MTK_VCODEC_INNER_RACING = 0x20000, }; @@ -461,7 +462,6 @@ struct mtk_vcodec_enc_pdata { * @enc_capability: used to identify encode capability * * @core_workqueue: queue used for core hardware decode - * @msg_queue_core_ctx: msg queue context used for core workqueue * * @subdev_dev: subdev hardware device * @subdev_prob_done: check whether all used hw device is prob done @@ -510,7 +510,6 @@ struct mtk_vcodec_dev { unsigned int enc_capability; struct workqueue_struct *core_workqueue; - struct vdec_msg_queue_ctx msg_queue_core_ctx; void *subdev_dev[MTK_VDEC_HW_MAX]; int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c index db65e77bd373..9ff439a50f53 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c @@ -505,13 +505,13 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, f->fmt.pix.pixelformat = fmt->fourcc; } - q_data->visible_width = f->fmt.pix_mp.width; - q_data->visible_height = f->fmt.pix_mp.height; - q_data->fmt = fmt; - ret = vidioc_try_fmt_out(ctx, f, q_data->fmt); + ret = vidioc_try_fmt_out(ctx, f, fmt); if (ret) return ret; + q_data->fmt = fmt; + q_data->visible_width = f->fmt.pix_mp.width; + q_data->visible_height = f->fmt.pix_mp.height; q_data->coded_width = f->fmt.pix_mp.width; q_data->coded_height = f->fmt.pix_mp.height; diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c index 999ce7ee5fdc..a7e8e3257b7f 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c @@ -596,7 +596,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_err(inst, "failed to get lat buffer"); + mtk_vcodec_debug(inst, "failed to get lat buffer"); return -EAGAIN; } share_info = lat_buf->private_data; @@ -672,7 +672,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, sizeof(share_info->h264_slice_params)); - vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); } /* wait decoder done interrupt */ @@ -698,7 +698,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, sizeof(share_info->h264_slice_params)); - vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); } mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c new file mode 100644 index 000000000000..1e6ab138b0bb --- /dev/null +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c @@ -0,0 +1,1097 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Yunfei Dong <yunfei.dong@mediatek.com> + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <media/videobuf2-dma-contig.h> + +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_drv_base.h" +#include "../vdec_drv_if.h" +#include "../vdec_vpu_if.h" + +/* the size used to store hevc wrap information */ +#define VDEC_HEVC_WRAP_SZ (532 * SZ_1K) + +#define HEVC_MAX_MV_NUM 32 + +/* get used parameters for sps/pps */ +#define GET_HEVC_VDEC_FLAG(cond, flag) \ + { dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); } +#define GET_HEVC_VDEC_PARAM(param) \ + { dst_param->param = src_param->param; } + +/** + * enum vdec_hevc_core_dec_err_type - core decode error type + * + * @TRANS_BUFFER_FULL: trans buffer is full + * @SLICE_HEADER_FULL: slice header buffer is full + */ +enum vdec_hevc_core_dec_err_type { + TRANS_BUFFER_FULL = 1, + SLICE_HEADER_FULL, +}; + +/** + * struct mtk_hevc_dpb_info - hevc dpb information + * + * @y_dma_addr: Y plane physical address + * @c_dma_addr: CbCr plane physical address + * @reference_flag: reference picture flag (short/long term reference picture) + * @field: field picture flag + */ +struct mtk_hevc_dpb_info { + dma_addr_t y_dma_addr; + dma_addr_t c_dma_addr; + int reference_flag; + int field; +}; + +/* + * struct mtk_hevc_sps_param - parameters for sps + */ +struct mtk_hevc_sps_param { + unsigned char video_parameter_set_id; + unsigned char seq_parameter_set_id; + unsigned short pic_width_in_luma_samples; + unsigned short pic_height_in_luma_samples; + unsigned char bit_depth_luma_minus8; + unsigned char bit_depth_chroma_minus8; + unsigned char log2_max_pic_order_cnt_lsb_minus4; + unsigned char sps_max_dec_pic_buffering_minus1; + unsigned char sps_max_num_reorder_pics; + unsigned char sps_max_latency_increase_plus1; + unsigned char log2_min_luma_coding_block_size_minus3; + unsigned char log2_diff_max_min_luma_coding_block_size; + unsigned char log2_min_luma_transform_block_size_minus2; + unsigned char log2_diff_max_min_luma_transform_block_size; + unsigned char max_transform_hierarchy_depth_inter; + unsigned char max_transform_hierarchy_depth_intra; + unsigned char pcm_sample_bit_depth_luma_minus1; + unsigned char pcm_sample_bit_depth_chroma_minus1; + unsigned char log2_min_pcm_luma_coding_block_size_minus3; + unsigned char log2_diff_max_min_pcm_luma_coding_block_size; + unsigned char num_short_term_ref_pic_sets; + unsigned char num_long_term_ref_pics_sps; + unsigned char chroma_format_idc; + unsigned char sps_max_sub_layers_minus1; + unsigned char separate_colour_plane; + unsigned char scaling_list_enabled; + unsigned char amp_enabled; + unsigned char sample_adaptive_offset; + unsigned char pcm_enabled; + unsigned char pcm_loop_filter_disabled; + unsigned char long_term_ref_pics_enabled; + unsigned char sps_temporal_mvp_enabled; + unsigned char strong_intra_smoothing_enabled; + unsigned char reserved[5]; +}; + +/* + * struct mtk_hevc_pps_param - parameters for pps + */ +struct mtk_hevc_pps_param { + unsigned char pic_parameter_set_id; + unsigned char num_extra_slice_header_bits; + unsigned char num_ref_idx_l0_default_active_minus1; + unsigned char num_ref_idx_l1_default_active_minus1; + char init_qp_minus26; + unsigned char diff_cu_qp_delta_depth; + char pps_cb_qp_offset; + char pps_cr_qp_offset; + unsigned char num_tile_columns_minus1; + unsigned char num_tile_rows_minus1; + unsigned char column_width_minus1[20]; + unsigned char row_height_minus1[22]; + char pps_beta_offset_div2; + char pps_tc_offset_div2; + unsigned char log2_parallel_merge_level_minus2; + char dependent_slice_segment_enabled; + char output_flag_present; + char sign_data_hiding_enabled; + char cabac_init_present; + char constrained_intra_pred; + char transform_skip_enabled; + char cu_qp_delta_enabled; + char pps_slice_chroma_qp_offsets_present; + char weighted_pred; + char weighted_bipred; + char transquant_bypass_enabled; + char pps_flag_tiles_enabled; + char entropy_coding_sync_enabled; + char loop_filter_across_tiles_enabled; + char pps_loop_filter_across_slices_enabled; + char deblocking_filter_override_enabled; + char pps_disable_deflocking_filter; + char lists_modification_present; + char slice_segment_header_extersion_present; + char deblocking_filter_control_present; + char uniform_spacing; + char reserved[6]; +}; + +/* + * struct mtk_hevc_slice_header_param - parameters for slice header + */ +struct mtk_hevc_slice_header_param { + unsigned int slice_type; + unsigned int num_active_ref_layer_pics; + int slice_qp; + int slice_qp_delta_cb; + int slice_qp_delta_cr; + int num_ref_idx[3]; + unsigned int col_ref_idx; + unsigned int five_minus_max_num_merge_cand; + int slice_deblocking_filter_beta_offset_div2; + int slice_deblocking_filter_tc_offset_div2; + unsigned char sao_enable_flag; + unsigned char sao_enable_flag_chroma; + unsigned char cabac_init_flag; + unsigned char slice_tmvp_flags_present; + unsigned char col_from_l0_flag; + unsigned char mvd_l1_zero_flag; + unsigned char slice_loop_filter_across_slices_enabled_flag; + unsigned char deblocking_filter_disable_flag; + unsigned int slice_reg0; + unsigned int slice_reg1; + unsigned int slice_reg2; + unsigned int num_rps_curr_temp_list; + unsigned int ref_list_mode; + int str_num_delta_pocs; + int str_num_negtive_pos_pics; + int num_long_term; + int num_long_term_sps; + unsigned int max_cu_width; + unsigned int max_cu_height; + unsigned int num_entry_point_offsets; + unsigned int last_lcu_x_in_tile[17]; + unsigned int last_lcu_y_in_tile[17]; + unsigned char nal_unit_type; +}; + +/* + * struct slice_api_hevc_scaling_matrix - parameters for scaling list + */ +struct slice_api_hevc_scaling_matrix { + unsigned char scaling_list_4x4[6][16]; + unsigned char scaling_list_8x8[6][64]; + unsigned char scaling_list_16x16[6][64]; + unsigned char scaling_list_32x32[2][64]; + unsigned char scaling_list_dc_coef_16x16[6]; + unsigned char scaling_list_dc_coef_32x32[2]; +}; + +/* + * struct slice_hevc_dpb_entry - each dpb information + */ +struct slice_hevc_dpb_entry { + u64 timestamp; + unsigned char flags; + unsigned char field_pic; + int pic_order_cnt_val; +}; + +/* + * struct slice_api_hevc_decode_param - parameters for decode. + */ +struct slice_api_hevc_decode_param { + struct slice_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + int pic_order_cnt_val; + unsigned short short_term_ref_pic_set_size; + unsigned short long_term_ref_pic_set_size; + unsigned char num_active_dpb_entries; + unsigned char num_poc_st_curr_before; + unsigned char num_poc_st_curr_after; + unsigned char num_poc_lt_curr; + unsigned char poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + unsigned char poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + unsigned char poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + unsigned char num_delta_pocs_of_ref_rps_idx; + int flags; +}; + +/** + * struct hevc_fb - hevc decode frame buffer information + * + * @vdec_fb_va: virtual address of struct vdec_fb + * @y_fb_dma: dma address of Y frame buffer (luma) + * @c_fb_dma: dma address of C frame buffer (chroma) + * @poc: picture order count of frame buffer + * @reserved: for 8 bytes alignment + */ +struct hevc_fb { + u64 vdec_fb_va; + u64 y_fb_dma; + u64 c_fb_dma; + s32 poc; + u32 reserved; +}; + +/** + * struct vdec_hevc_slice_lat_dec_param - parameters for decode current frame + * + * @sps: hevc sps syntax parameters + * @pps: hevc pps syntax parameters + * @slice_header: hevc slice header syntax parameters + * @scaling_matrix: hevc scaling list parameters + * @decode_params: decoder parameters of each frame used for hardware decode + * @hevc_dpb_info: dpb reference list + */ +struct vdec_hevc_slice_lat_dec_param { + struct mtk_hevc_sps_param sps; + struct mtk_hevc_pps_param pps; + struct mtk_hevc_slice_header_param slice_header; + struct slice_api_hevc_scaling_matrix scaling_matrix; + struct slice_api_hevc_decode_param decode_params; + struct mtk_hevc_dpb_info hevc_dpb_info[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; +}; + +/** + * struct vdec_hevc_slice_info - decode information + * + * @wdma_end_addr_offset: wdma end address offset + * @timeout: Decode timeout: 1 timeout, 0 no timeount + * @vdec_fb_va: VDEC frame buffer struct virtual address + * @crc: Used to check whether hardware's status is right + */ +struct vdec_hevc_slice_info { + u64 wdma_end_addr_offset; + u64 timeout; + u64 vdec_fb_va; + u32 crc[8]; +}; + +/* + * struct vdec_hevc_slice_mem - memory address and size + */ +struct vdec_hevc_slice_mem { + union { + u64 buf; + dma_addr_t dma_addr; + }; + union { + size_t size; + dma_addr_t dma_addr_end; + u64 padding; + }; +}; + +/** + * struct vdec_hevc_slice_fb - frame buffer for decoding + * @y: current y buffer address info + * @c: current c buffer address info + */ +struct vdec_hevc_slice_fb { + struct vdec_hevc_slice_mem y; + struct vdec_hevc_slice_mem c; +}; + +/** + * struct vdec_hevc_slice_vsi - shared memory for decode information exchange + * between SCP and Host. + * + * @bs: input buffer info + * + * @ube: ube buffer + * @trans: transcoded buffer + * @err_map: err map buffer + * @slice_bc: slice bc buffer + * @wrap: temp buffer + * + * @fb: current y/c buffer + * @mv_buf_dma: HW working motion vector buffer + * @dec: decode information (AP-R, VPU-W) + * @hevc_slice_params: decode parameters for hw used + */ +struct vdec_hevc_slice_vsi { + /* used in LAT stage */ + struct vdec_hevc_slice_mem bs; + + struct vdec_hevc_slice_mem ube; + struct vdec_hevc_slice_mem trans; + struct vdec_hevc_slice_mem err_map; + struct vdec_hevc_slice_mem slice_bc; + struct vdec_hevc_slice_mem wrap; + + struct vdec_hevc_slice_fb fb; + struct vdec_hevc_slice_mem mv_buf_dma[HEVC_MAX_MV_NUM]; + struct vdec_hevc_slice_info dec; + struct vdec_hevc_slice_lat_dec_param hevc_slice_params; +}; + +/** + * struct vdec_hevc_slice_share_info - shared information used to exchange + * message between lat and core + * + * @sps: sequence header information from user space + * @dec_params: decoder params from user space + * @hevc_slice_params: decoder params used for hardware + * @trans: trans buffer dma address + */ +struct vdec_hevc_slice_share_info { + struct v4l2_ctrl_hevc_sps sps; + struct v4l2_ctrl_hevc_decode_params dec_params; + struct vdec_hevc_slice_lat_dec_param hevc_slice_params; + struct vdec_hevc_slice_mem trans; +}; + +/** + * struct vdec_hevc_slice_inst - hevc decoder instance + * + * @slice_dec_num: how many picture be decoded + * @ctx: point to mtk_vcodec_ctx + * @mv_buf: HW working motion vector buffer + * @vpu: VPU instance + * @vsi: vsi used for lat + * @vsi_core: vsi used for core + * @wrap_addr: wrap address used for hevc + * + * @hevc_slice_param: the parameters that hardware use to decode + * + * @resolution_changed: resolution changed + * @realloc_mv_buf: reallocate mv buffer + * @cap_num_planes: number of capture queue plane + */ +struct vdec_hevc_slice_inst { + unsigned int slice_dec_num; + struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_mem mv_buf[HEVC_MAX_MV_NUM]; + struct vdec_vpu_inst vpu; + struct vdec_hevc_slice_vsi *vsi; + struct vdec_hevc_slice_vsi *vsi_core; + struct mtk_vcodec_mem wrap_addr; + + struct vdec_hevc_slice_lat_dec_param hevc_slice_param; + + unsigned int resolution_changed; + unsigned int realloc_mv_buf; + unsigned int cap_num_planes; +}; + +static unsigned int vdec_hevc_get_mv_buf_size(unsigned int width, unsigned int height) +{ + const unsigned int unit_size = (width / 16) * (height / 16) + 8; + + return 64 * unit_size; +} + +static void *vdec_hevc_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); + + if (!ctrl) + return ERR_PTR(-EINVAL); + + return ctrl->p_cur.p; +} + +static void vdec_hevc_fill_dpb_info(struct mtk_vcodec_ctx *ctx, + struct slice_api_hevc_decode_param *decode_params, + struct mtk_hevc_dpb_info *hevc_dpb_info) +{ + const struct slice_hevc_dpb_entry *dpb; + struct vb2_queue *vq; + struct vb2_buffer *vb; + int index; + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + for (index = 0; index < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; index++) { + dpb = &decode_params->dpb[index]; + if (index >= decode_params->num_active_dpb_entries) + continue; + + vb = vb2_find_buffer(vq, dpb->timestamp); + if (!vb) { + dev_err(&ctx->dev->plat_dev->dev, + "Reference invalid: dpb_index(%d) timestamp(%lld)", + index, dpb->timestamp); + continue; + } + + hevc_dpb_info[index].field = dpb->field_pic; + + hevc_dpb_info[index].y_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) + hevc_dpb_info[index].c_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1); + else + hevc_dpb_info[index].c_dma_addr = + hevc_dpb_info[index].y_dma_addr + ctx->picinfo.fb_sz[0]; + } +} + +static void vdec_hevc_copy_sps_params(struct mtk_hevc_sps_param *dst_param, + const struct v4l2_ctrl_hevc_sps *src_param) +{ + GET_HEVC_VDEC_PARAM(video_parameter_set_id); + GET_HEVC_VDEC_PARAM(seq_parameter_set_id); + GET_HEVC_VDEC_PARAM(pic_width_in_luma_samples); + GET_HEVC_VDEC_PARAM(pic_height_in_luma_samples); + GET_HEVC_VDEC_PARAM(bit_depth_luma_minus8); + GET_HEVC_VDEC_PARAM(bit_depth_chroma_minus8); + GET_HEVC_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4); + GET_HEVC_VDEC_PARAM(sps_max_dec_pic_buffering_minus1); + GET_HEVC_VDEC_PARAM(sps_max_num_reorder_pics); + GET_HEVC_VDEC_PARAM(sps_max_latency_increase_plus1); + GET_HEVC_VDEC_PARAM(log2_min_luma_coding_block_size_minus3); + GET_HEVC_VDEC_PARAM(log2_diff_max_min_luma_coding_block_size); + GET_HEVC_VDEC_PARAM(log2_min_luma_transform_block_size_minus2); + GET_HEVC_VDEC_PARAM(log2_diff_max_min_luma_transform_block_size); + GET_HEVC_VDEC_PARAM(max_transform_hierarchy_depth_inter); + GET_HEVC_VDEC_PARAM(max_transform_hierarchy_depth_intra); + GET_HEVC_VDEC_PARAM(pcm_sample_bit_depth_luma_minus1); + GET_HEVC_VDEC_PARAM(pcm_sample_bit_depth_chroma_minus1); + GET_HEVC_VDEC_PARAM(log2_min_pcm_luma_coding_block_size_minus3); + GET_HEVC_VDEC_PARAM(log2_diff_max_min_pcm_luma_coding_block_size); + GET_HEVC_VDEC_PARAM(num_short_term_ref_pic_sets); + GET_HEVC_VDEC_PARAM(num_long_term_ref_pics_sps); + GET_HEVC_VDEC_PARAM(chroma_format_idc); + GET_HEVC_VDEC_PARAM(sps_max_sub_layers_minus1); + + GET_HEVC_VDEC_FLAG(separate_colour_plane, + V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE); + GET_HEVC_VDEC_FLAG(scaling_list_enabled, + V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED); + GET_HEVC_VDEC_FLAG(amp_enabled, + V4L2_HEVC_SPS_FLAG_AMP_ENABLED); + GET_HEVC_VDEC_FLAG(sample_adaptive_offset, + V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET); + GET_HEVC_VDEC_FLAG(pcm_enabled, + V4L2_HEVC_SPS_FLAG_PCM_ENABLED); + GET_HEVC_VDEC_FLAG(pcm_loop_filter_disabled, + V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED); + GET_HEVC_VDEC_FLAG(long_term_ref_pics_enabled, + V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT); + GET_HEVC_VDEC_FLAG(sps_temporal_mvp_enabled, + V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED); + GET_HEVC_VDEC_FLAG(strong_intra_smoothing_enabled, + V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED); +} + +static void vdec_hevc_copy_pps_params(struct mtk_hevc_pps_param *dst_param, + const struct v4l2_ctrl_hevc_pps *src_param) +{ + int i; + + GET_HEVC_VDEC_PARAM(pic_parameter_set_id); + GET_HEVC_VDEC_PARAM(num_extra_slice_header_bits); + GET_HEVC_VDEC_PARAM(num_ref_idx_l0_default_active_minus1); + GET_HEVC_VDEC_PARAM(num_ref_idx_l1_default_active_minus1); + GET_HEVC_VDEC_PARAM(init_qp_minus26); + GET_HEVC_VDEC_PARAM(diff_cu_qp_delta_depth); + GET_HEVC_VDEC_PARAM(pps_cb_qp_offset); + GET_HEVC_VDEC_PARAM(pps_cr_qp_offset); + GET_HEVC_VDEC_PARAM(num_tile_columns_minus1); + GET_HEVC_VDEC_PARAM(num_tile_rows_minus1); + GET_HEVC_VDEC_PARAM(init_qp_minus26); + GET_HEVC_VDEC_PARAM(diff_cu_qp_delta_depth); + GET_HEVC_VDEC_PARAM(pic_parameter_set_id); + GET_HEVC_VDEC_PARAM(num_extra_slice_header_bits); + GET_HEVC_VDEC_PARAM(num_ref_idx_l0_default_active_minus1); + GET_HEVC_VDEC_PARAM(num_ref_idx_l1_default_active_minus1); + GET_HEVC_VDEC_PARAM(pps_beta_offset_div2); + GET_HEVC_VDEC_PARAM(pps_tc_offset_div2); + GET_HEVC_VDEC_PARAM(log2_parallel_merge_level_minus2); + + for (i = 0; i < ARRAY_SIZE(src_param->column_width_minus1); i++) + GET_HEVC_VDEC_PARAM(column_width_minus1[i]); + for (i = 0; i < ARRAY_SIZE(src_param->row_height_minus1); i++) + GET_HEVC_VDEC_PARAM(row_height_minus1[i]); + + GET_HEVC_VDEC_FLAG(dependent_slice_segment_enabled, + V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED); + GET_HEVC_VDEC_FLAG(output_flag_present, + V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT); + GET_HEVC_VDEC_FLAG(sign_data_hiding_enabled, + V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED); + GET_HEVC_VDEC_FLAG(cabac_init_present, + V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT); + GET_HEVC_VDEC_FLAG(constrained_intra_pred, + V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED); + GET_HEVC_VDEC_FLAG(transform_skip_enabled, + V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED); + GET_HEVC_VDEC_FLAG(cu_qp_delta_enabled, + V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED); + GET_HEVC_VDEC_FLAG(pps_slice_chroma_qp_offsets_present, + V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT); + GET_HEVC_VDEC_FLAG(weighted_pred, + V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED); + GET_HEVC_VDEC_FLAG(weighted_bipred, + V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED); + GET_HEVC_VDEC_FLAG(transquant_bypass_enabled, + V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED); + GET_HEVC_VDEC_FLAG(pps_flag_tiles_enabled, + V4L2_HEVC_PPS_FLAG_TILES_ENABLED); + GET_HEVC_VDEC_FLAG(entropy_coding_sync_enabled, + V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED); + GET_HEVC_VDEC_FLAG(loop_filter_across_tiles_enabled, + V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED); + GET_HEVC_VDEC_FLAG(pps_loop_filter_across_slices_enabled, + V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED); + GET_HEVC_VDEC_FLAG(deblocking_filter_override_enabled, + V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED); + GET_HEVC_VDEC_FLAG(pps_disable_deflocking_filter, + V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER); + GET_HEVC_VDEC_FLAG(lists_modification_present, + V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT); + GET_HEVC_VDEC_FLAG(slice_segment_header_extersion_present, + V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT); + GET_HEVC_VDEC_FLAG(deblocking_filter_control_present, + V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT); + GET_HEVC_VDEC_FLAG(uniform_spacing, + V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING); +} + +static void vdec_hevc_copy_scaling_matrix(struct slice_api_hevc_scaling_matrix *dst_matrix, + const struct v4l2_ctrl_hevc_scaling_matrix *src_matrix) +{ + memcpy(dst_matrix, src_matrix, sizeof(*src_matrix)); +} + +static void +vdec_hevc_copy_decode_params(struct slice_api_hevc_decode_param *dst_param, + const struct v4l2_ctrl_hevc_decode_params *src_param, + const struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]) +{ + struct slice_hevc_dpb_entry *dst_entry; + const struct v4l2_hevc_dpb_entry *src_entry; + int i; + + for (i = 0; i < ARRAY_SIZE(dst_param->dpb); i++) { + dst_entry = &dst_param->dpb[i]; + src_entry = &dpb[i]; + + dst_entry->timestamp = src_entry->timestamp; + dst_entry->flags = src_entry->flags; + dst_entry->field_pic = src_entry->field_pic; + dst_entry->pic_order_cnt_val = src_entry->pic_order_cnt_val; + + GET_HEVC_VDEC_PARAM(poc_st_curr_before[i]); + GET_HEVC_VDEC_PARAM(poc_st_curr_after[i]); + GET_HEVC_VDEC_PARAM(poc_lt_curr[i]); + } + + GET_HEVC_VDEC_PARAM(pic_order_cnt_val); + GET_HEVC_VDEC_PARAM(short_term_ref_pic_set_size); + GET_HEVC_VDEC_PARAM(long_term_ref_pic_set_size); + GET_HEVC_VDEC_PARAM(num_active_dpb_entries); + GET_HEVC_VDEC_PARAM(num_poc_st_curr_before); + GET_HEVC_VDEC_PARAM(num_poc_st_curr_after); + GET_HEVC_VDEC_PARAM(num_delta_pocs_of_ref_rps_idx); + GET_HEVC_VDEC_PARAM(num_poc_lt_curr); + GET_HEVC_VDEC_PARAM(flags); +} + +static int vdec_hevc_slice_fill_decode_parameters(struct vdec_hevc_slice_inst *inst, + struct vdec_hevc_slice_share_info *share_info) +{ + struct vdec_hevc_slice_lat_dec_param *slice_param = &inst->vsi->hevc_slice_params; + const struct v4l2_ctrl_hevc_decode_params *dec_params; + const struct v4l2_ctrl_hevc_scaling_matrix *src_matrix; + const struct v4l2_ctrl_hevc_sps *sps; + const struct v4l2_ctrl_hevc_pps *pps; + + dec_params = + vdec_hevc_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); + if (IS_ERR(dec_params)) + return PTR_ERR(dec_params); + + src_matrix = + vdec_hevc_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_HEVC_SCALING_MATRIX); + if (IS_ERR(src_matrix)) + return PTR_ERR(src_matrix); + + sps = vdec_hevc_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_HEVC_SPS); + if (IS_ERR(sps)) + return PTR_ERR(sps); + + pps = vdec_hevc_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_HEVC_PPS); + if (IS_ERR(pps)) + return PTR_ERR(pps); + + vdec_hevc_copy_sps_params(&slice_param->sps, sps); + vdec_hevc_copy_pps_params(&slice_param->pps, pps); + vdec_hevc_copy_scaling_matrix(&slice_param->scaling_matrix, src_matrix); + + memcpy(&share_info->sps, sps, sizeof(*sps)); + memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params)); + + slice_param->decode_params.num_poc_st_curr_before = dec_params->num_poc_st_curr_before; + slice_param->decode_params.num_poc_st_curr_after = dec_params->num_poc_st_curr_after; + slice_param->decode_params.num_poc_lt_curr = dec_params->num_poc_lt_curr; + slice_param->decode_params.num_delta_pocs_of_ref_rps_idx = + dec_params->num_delta_pocs_of_ref_rps_idx; + + return 0; +} + +static void vdec_hevc_slice_fill_decode_reflist(struct vdec_hevc_slice_inst *inst, + struct vdec_hevc_slice_lat_dec_param *slice_param, + struct vdec_hevc_slice_share_info *share_info) +{ + struct v4l2_ctrl_hevc_decode_params *dec_params = &share_info->dec_params; + + vdec_hevc_copy_decode_params(&slice_param->decode_params, dec_params, + share_info->dec_params.dpb); + + vdec_hevc_fill_dpb_info(inst->ctx, &slice_param->decode_params, + slice_param->hevc_dpb_info); +} + +static int vdec_hevc_slice_alloc_mv_buf(struct vdec_hevc_slice_inst *inst, + struct vdec_pic_info *pic) +{ + unsigned int buf_sz = vdec_hevc_get_mv_buf_size(pic->buf_w, pic->buf_h); + struct mtk_vcodec_mem *mem; + int i, err; + + mtk_v4l2_debug(3, "allocate mv buffer size = 0x%x", buf_sz); + for (i = 0; i < HEVC_MAX_MV_NUM; i++) { + mem = &inst->mv_buf[i]; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + mem->size = buf_sz; + err = mtk_vcodec_mem_alloc(inst->ctx, mem); + if (err) { + mtk_vcodec_err(inst, "failed to allocate mv buf"); + return err; + } + } + + return 0; +} + +static void vdec_hevc_slice_free_mv_buf(struct vdec_hevc_slice_inst *inst) +{ + int i; + struct mtk_vcodec_mem *mem; + + for (i = 0; i < HEVC_MAX_MV_NUM; i++) { + mem = &inst->mv_buf[i]; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + } +} + +static void vdec_hevc_slice_get_pic_info(struct vdec_hevc_slice_inst *inst) +{ + struct mtk_vcodec_ctx *ctx = inst->ctx; + u32 data[3]; + + data[0] = ctx->picinfo.pic_w; + data[1] = ctx->picinfo.pic_h; + data[2] = ctx->capture_fourcc; + vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO); + + ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64); + ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64); + ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0]; + ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1]; + inst->cap_num_planes = + ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; + + mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->picinfo.buf_w, ctx->picinfo.buf_h); + mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], + ctx->picinfo.fb_sz[1]); + + if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || + ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { + inst->resolution_changed = true; + if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w || + ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) + inst->realloc_mv_buf = true; + + mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", + inst->resolution_changed, + inst->realloc_mv_buf, + ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h); + } +} + +static void vdec_hevc_slice_get_crop_info(struct vdec_hevc_slice_inst *inst, + struct v4l2_rect *cr) +{ + cr->left = 0; + cr->top = 0; + cr->width = inst->ctx->picinfo.pic_w; + cr->height = inst->ctx->picinfo.pic_h; + + mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); +} + +static int vdec_hevc_slice_setup_lat_buffer(struct vdec_hevc_slice_inst *inst, + struct mtk_vcodec_mem *bs, + struct vdec_lat_buf *lat_buf, + bool *res_chg) +{ + struct mtk_vcodec_mem *mem; + struct mtk_video_dec_buf *src_buf_info; + struct vdec_hevc_slice_share_info *share_info; + int i, err; + + inst->vsi->bs.dma_addr = (u64)bs->dma_addr; + inst->vsi->bs.size = bs->size; + + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); + lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req; + v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true); + + *res_chg = inst->resolution_changed; + if (inst->resolution_changed) { + mtk_vcodec_debug(inst, "- resolution changed -"); + if (inst->realloc_mv_buf) { + err = vdec_hevc_slice_alloc_mv_buf(inst, &inst->ctx->picinfo); + inst->realloc_mv_buf = false; + if (err) + return err; + } + inst->resolution_changed = false; + } + + for (i = 0; i < HEVC_MAX_MV_NUM; i++) { + mem = &inst->mv_buf[i]; + inst->vsi->mv_buf_dma[i].dma_addr = mem->dma_addr; + inst->vsi->mv_buf_dma[i].size = mem->size; + } + + inst->vsi->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr; + inst->vsi->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size; + + inst->vsi->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr; + inst->vsi->err_map.size = lat_buf->wdma_err_addr.size; + + inst->vsi->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr; + inst->vsi->slice_bc.size = lat_buf->slice_bc_addr.size; + + inst->vsi->trans.dma_addr_end = inst->ctx->msg_queue.wdma_rptr_addr; + inst->vsi->trans.dma_addr = inst->ctx->msg_queue.wdma_wptr_addr; + + share_info = lat_buf->private_data; + share_info->trans.dma_addr = inst->vsi->trans.dma_addr; + share_info->trans.dma_addr_end = inst->vsi->trans.dma_addr_end; + + mtk_vcodec_debug(inst, "lat: ube addr/size(0x%llx 0x%llx) err:0x%llx", + inst->vsi->ube.buf, + inst->vsi->ube.padding, + inst->vsi->err_map.buf); + + mtk_vcodec_debug(inst, "slice addr/size(0x%llx 0x%llx) trans start/end((0x%llx 0x%llx))", + inst->vsi->slice_bc.buf, + inst->vsi->slice_bc.padding, + inst->vsi->trans.buf, + inst->vsi->trans.padding); + + return 0; +} + +static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst, + struct vdec_hevc_slice_share_info *share_info, + struct vdec_lat_buf *lat_buf) +{ + struct mtk_vcodec_mem *mem; + struct mtk_vcodec_ctx *ctx = inst->ctx; + struct vb2_v4l2_buffer *vb2_v4l2; + struct vdec_fb *fb; + u64 y_fb_dma, c_fb_dma; + int i; + + fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); + if (!fb) { + mtk_vcodec_err(inst, "fb buffer is NULL"); + return -EBUSY; + } + + y_fb_dma = (u64)fb->base_y.dma_addr; + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) + c_fb_dma = + y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h; + else + c_fb_dma = (u64)fb->base_c.dma_addr; + + mtk_vcodec_debug(inst, "[hevc-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, + c_fb_dma); + + inst->vsi_core->fb.y.dma_addr = y_fb_dma; + inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0]; + inst->vsi_core->fb.c.dma_addr = c_fb_dma; + inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[1]; + + inst->vsi_core->dec.vdec_fb_va = (unsigned long)fb; + + inst->vsi_core->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr; + inst->vsi_core->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size; + + inst->vsi_core->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr; + inst->vsi_core->err_map.size = lat_buf->wdma_err_addr.size; + + inst->vsi_core->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr; + inst->vsi_core->slice_bc.size = lat_buf->slice_bc_addr.size; + + inst->vsi_core->trans.dma_addr = share_info->trans.dma_addr; + inst->vsi_core->trans.dma_addr_end = share_info->trans.dma_addr_end; + + inst->vsi_core->wrap.dma_addr = inst->wrap_addr.dma_addr; + inst->vsi_core->wrap.size = inst->wrap_addr.size; + + for (i = 0; i < HEVC_MAX_MV_NUM; i++) { + mem = &inst->mv_buf[i]; + inst->vsi_core->mv_buf_dma[i].dma_addr = mem->dma_addr; + inst->vsi_core->mv_buf_dma[i].size = mem->size; + } + + vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + v4l2_m2m_buf_copy_metadata(&lat_buf->ts_info, vb2_v4l2, true); + + return 0; +} + +static int vdec_hevc_slice_init(struct mtk_vcodec_ctx *ctx) +{ + struct vdec_hevc_slice_inst *inst; + int err, vsi_size; + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + inst->ctx = ctx; + + inst->vpu.id = SCP_IPI_VDEC_LAT; + inst->vpu.core_id = SCP_IPI_VDEC_CORE; + inst->vpu.ctx = ctx; + inst->vpu.codec_type = ctx->current_codec; + inst->vpu.capture_type = ctx->capture_fourcc; + + ctx->drv_handle = inst; + err = vpu_dec_init(&inst->vpu); + if (err) { + mtk_vcodec_err(inst, "vdec_hevc init err=%d", err); + goto error_free_inst; + } + + vsi_size = round_up(sizeof(struct vdec_hevc_slice_vsi), VCODEC_DEC_ALIGNED_64); + inst->vsi = inst->vpu.vsi; + inst->vsi_core = + (struct vdec_hevc_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size); + + inst->resolution_changed = true; + inst->realloc_mv_buf = true; + + inst->wrap_addr.size = VDEC_HEVC_WRAP_SZ; + err = mtk_vcodec_mem_alloc(ctx, &inst->wrap_addr); + if (err) + goto error_free_inst; + + mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n", + (int)sizeof(struct mtk_hevc_sps_param), + (int)sizeof(struct mtk_hevc_pps_param), + (int)sizeof(struct vdec_hevc_slice_lat_dec_param), + (int)sizeof(struct mtk_hevc_dpb_info), + vsi_size); + mtk_vcodec_debug(inst, "lat hevc instance >> %p, codec_type = 0x%x", + inst, inst->vpu.codec_type); + + return 0; +error_free_inst: + kfree(inst); + return err; +} + +static void vdec_hevc_slice_deinit(void *h_vdec) +{ + struct vdec_hevc_slice_inst *inst = h_vdec; + struct mtk_vcodec_mem *mem; + + mtk_vcodec_debug_enter(inst); + + vpu_dec_deinit(&inst->vpu); + vdec_hevc_slice_free_mv_buf(inst); + + mem = &inst->wrap_addr; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + + vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx); + kfree(inst); +} + +static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf) +{ + int err, timeout; + struct mtk_vcodec_ctx *ctx = lat_buf->ctx; + struct vdec_hevc_slice_inst *inst = ctx->drv_handle; + struct vdec_hevc_slice_share_info *share_info = lat_buf->private_data; + struct vdec_vpu_inst *vpu = &inst->vpu; + + mtk_vcodec_debug(inst, "[hevc-core] vdec_hevc core decode"); + memcpy(&inst->vsi_core->hevc_slice_params, &share_info->hevc_slice_params, + sizeof(share_info->hevc_slice_params)); + + err = vdec_hevc_slice_setup_core_buffer(inst, share_info, lat_buf); + if (err) + goto vdec_dec_end; + + vdec_hevc_slice_fill_decode_reflist(inst, &inst->vsi_core->hevc_slice_params, + share_info); + err = vpu_dec_core(vpu); + if (err) { + mtk_vcodec_err(inst, "core decode err=%d", err); + goto vdec_dec_end; + } + + /* wait decoder done interrupt */ + timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); + if (timeout) + mtk_vcodec_err(inst, "core decode timeout: pic_%d", + ctx->decoded_frame_cnt); + inst->vsi_core->dec.timeout = !!timeout; + + vpu_dec_core_end(vpu); + mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + ctx->decoded_frame_cnt, + inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], + inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], + inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], + inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); + +vdec_dec_end: + vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end); + ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req); + mtk_vcodec_debug(inst, "core decode done err=%d", err); + ctx->decoded_frame_cnt++; + return 0; +} + +static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + struct vdec_hevc_slice_inst *inst = h_vdec; + struct vdec_vpu_inst *vpu = &inst->vpu; + int err, timeout = 0; + unsigned int data[2]; + struct vdec_lat_buf *lat_buf; + struct vdec_hevc_slice_share_info *share_info; + + if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx, + vdec_hevc_slice_core_decode, + sizeof(*share_info))) + return -ENOMEM; + + /* bs NULL means flush decoder */ + if (!bs) { + vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue); + return vpu_dec_reset(vpu); + } + + lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx); + if (!lat_buf) { + mtk_vcodec_debug(inst, "failed to get lat buffer"); + return -EAGAIN; + } + + share_info = lat_buf->private_data; + err = vdec_hevc_slice_fill_decode_parameters(inst, share_info); + if (err) + goto err_free_fb_out; + + err = vdec_hevc_slice_setup_lat_buffer(inst, bs, lat_buf, res_chg); + if (err) + goto err_free_fb_out; + + err = vpu_dec_start(vpu, data, 2); + if (err) { + mtk_vcodec_debug(inst, "lat decode err: %d", err); + goto err_free_fb_out; + } + + if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { + memcpy(&share_info->hevc_slice_params, &inst->vsi->hevc_slice_params, + sizeof(share_info->hevc_slice_params)); + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); + } + + /* wait decoder done interrupt */ + timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); + if (timeout) + mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num); + inst->vsi->dec.timeout = !!timeout; + + err = vpu_dec_end(vpu); + if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) { + if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); + inst->slice_dec_num++; + mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err); + return -EINVAL; + } + + share_info->trans.dma_addr_end = inst->ctx->msg_queue.wdma_addr.dma_addr + + inst->vsi->dec.wdma_end_addr_offset; + vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end); + + if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { + memcpy(&share_info->hevc_slice_params, &inst->vsi->hevc_slice_params, + sizeof(share_info->hevc_slice_params)); + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf); + } + mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, + inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); + + inst->slice_dec_num++; + return 0; +err_free_fb_out: + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); + mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err); + return err; +} + +static int vdec_hevc_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *unused, bool *res_chg) +{ + struct vdec_hevc_slice_inst *inst = h_vdec; + + if (!h_vdec || inst->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) + return -EINVAL; + + return vdec_hevc_slice_lat_decode(h_vdec, bs, unused, res_chg); +} + +static int vdec_hevc_slice_get_param(void *h_vdec, enum vdec_get_param_type type, + void *out) +{ + struct vdec_hevc_slice_inst *inst = h_vdec; + + switch (type) { + case GET_PARAM_PIC_INFO: + vdec_hevc_slice_get_pic_info(inst); + break; + case GET_PARAM_DPB_SIZE: + *(unsigned int *)out = 6; + break; + case GET_PARAM_CROP_INFO: + vdec_hevc_slice_get_crop_info(inst, out); + break; + default: + mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + return -EINVAL; + } + return 0; +} + +const struct vdec_common_if vdec_hevc_slice_multi_if = { + .init = vdec_hevc_slice_init, + .decode = vdec_hevc_slice_decode, + .get_param = vdec_hevc_slice_get_param, + .deinit = vdec_hevc_slice_deinit, +}; diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c index cf16cf2807f0..c2f90848f498 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c @@ -2069,7 +2069,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx); if (!lat_buf) { - mtk_vcodec_err(instance, "Failed to get VP9 lat buf\n"); + mtk_vcodec_debug(instance, "Failed to get VP9 lat buf\n"); return -EAGAIN; } pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data; @@ -2119,7 +2119,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, vdec_msg_queue_update_ube_wptr(&ctx->msg_queue, vsi->trans.dma_addr_end + ctx->msg_queue.wdma_addr.dma_addr); - vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf); + vdec_msg_queue_qbuf(&ctx->msg_queue.core_ctx, lat_buf); return 0; err_free_fb_out: diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c index f3807f03d880..0bde1eb04015 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c @@ -49,6 +49,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) ctx->dec_if = &vdec_vp9_slice_lat_if; ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE; break; + case V4L2_PIX_FMT_HEVC_SLICE: + ctx->dec_if = &vdec_hevc_slice_multi_if; + ctx->hw_id = MTK_VDEC_LAT0; + break; default: return -EINVAL; } diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h index 076306ff2dd4..ef3a0762fdc8 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h +++ b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.h @@ -61,6 +61,7 @@ extern const struct vdec_common_if vdec_vp8_if; extern const struct vdec_common_if vdec_vp8_slice_if; extern const struct vdec_common_if vdec_vp9_if; extern const struct vdec_common_if vdec_vp9_slice_lat_if; +extern const struct vdec_common_if vdec_hevc_slice_multi_if; /** * vdec_if_init() - initialize decode driver diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c index f3073d1e7f42..66b4175601e3 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c @@ -71,7 +71,6 @@ static void vdec_msg_queue_dec(struct vdec_msg_queue *msg_queue, int hardware_in int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf) { struct list_head *head; - int status; head = vdec_get_buf_list(msg_ctx->hardware_index, buf); if (!head) { @@ -87,12 +86,9 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf if (msg_ctx->hardware_index != MTK_VDEC_CORE) { wake_up_all(&msg_ctx->ready_to_use); } else { - if (buf->ctx->msg_queue.core_work_cnt < - atomic_read(&buf->ctx->msg_queue.core_list_cnt)) { - status = queue_work(buf->ctx->dev->core_workqueue, - &buf->ctx->msg_queue.core_work); - if (status) - buf->ctx->msg_queue.core_work_cnt++; + if (!(buf->ctx->msg_queue.status & CONTEXT_LIST_QUEUED)) { + queue_work(buf->ctx->dev->core_workqueue, &buf->ctx->msg_queue.core_work); + buf->ctx->msg_queue.status |= CONTEXT_LIST_QUEUED; } } @@ -181,49 +177,23 @@ void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t u bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue) { - struct vdec_lat_buf *buf, *tmp; - struct list_head *list_core[3]; - struct vdec_msg_queue_ctx *core_ctx; - int ret, i, in_core_count = 0, count = 0; - long timeout_jiff; - - core_ctx = &msg_queue->ctx->dev->msg_queue_core_ctx; - spin_lock(&core_ctx->ready_lock); - list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) { - if (buf && buf->ctx == msg_queue->ctx) { - list_core[in_core_count++] = &buf->core_list; - list_del(&buf->core_list); - } - } - - for (i = 0; i < in_core_count; i++) { - list_add(list_core[in_core_count - (1 + i)], &core_ctx->ready_queue); - queue_work(msg_queue->ctx->dev->core_workqueue, &msg_queue->core_work); - } - spin_unlock(&core_ctx->ready_lock); - - timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2)); - ret = wait_event_timeout(msg_queue->ctx->msg_queue.core_dec_done, - msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT, - timeout_jiff); - if (ret) { - mtk_v4l2_debug(3, "success to get lat buf: %d", - msg_queue->lat_ctx.ready_num); + if (atomic_read(&msg_queue->lat_list_cnt) == NUM_BUFFER_COUNT) { + mtk_v4l2_debug(3, "wait buf full: list(%d %d) ready_num:%d status:%d", + atomic_read(&msg_queue->lat_list_cnt), + atomic_read(&msg_queue->core_list_cnt), + msg_queue->lat_ctx.ready_num, + msg_queue->status); return true; } - spin_lock(&core_ctx->ready_lock); - list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) { - if (buf && buf->ctx == msg_queue->ctx) { - count++; - list_del(&buf->core_list); - } - } - spin_unlock(&core_ctx->ready_lock); + msg_queue->flush_done = false; + vdec_msg_queue_qbuf(&msg_queue->core_ctx, &msg_queue->empty_lat_buf); + wait_event(msg_queue->core_dec_done, msg_queue->flush_done); - mtk_v4l2_err("failed with lat buf isn't full: list(%d %d) count:%d", - atomic_read(&msg_queue->lat_list_cnt), - atomic_read(&msg_queue->core_list_cnt), count); + mtk_v4l2_debug(3, "flush done => ready_num:%d status:%d list(%d %d)", + msg_queue->lat_ctx.ready_num, msg_queue->status, + atomic_read(&msg_queue->lat_list_cnt), + atomic_read(&msg_queue->core_list_cnt)); return false; } @@ -251,6 +221,8 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, kfree(lat_buf->private_data); } + + cancel_work_sync(&msg_queue->core_work); } static void vdec_msg_queue_core_work(struct work_struct *work) @@ -261,12 +233,23 @@ static void vdec_msg_queue_core_work(struct work_struct *work) container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue); struct mtk_vcodec_dev *dev = ctx->dev; struct vdec_lat_buf *lat_buf; - int status; - lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx); + spin_lock(&msg_queue->core_ctx.ready_lock); + ctx->msg_queue.status &= ~CONTEXT_LIST_QUEUED; + spin_unlock(&msg_queue->core_ctx.ready_lock); + + lat_buf = vdec_msg_queue_dqbuf(&msg_queue->core_ctx); if (!lat_buf) return; + if (lat_buf->is_last_frame) { + ctx->msg_queue.status = CONTEXT_LIST_DEC_DONE; + msg_queue->flush_done = true; + wake_up(&ctx->msg_queue.core_dec_done); + + return; + } + ctx = lat_buf->ctx; mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE); mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE); @@ -277,18 +260,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work) mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE); vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf); - wake_up_all(&ctx->msg_queue.core_dec_done); - spin_lock(&dev->msg_queue_core_ctx.ready_lock); - lat_buf->ctx->msg_queue.core_work_cnt--; - - if (lat_buf->ctx->msg_queue.core_work_cnt < - atomic_read(&lat_buf->ctx->msg_queue.core_list_cnt)) { - status = queue_work(lat_buf->ctx->dev->core_workqueue, - &lat_buf->ctx->msg_queue.core_work); - if (status) - lat_buf->ctx->msg_queue.core_work_cnt++; + if (!(ctx->msg_queue.status & CONTEXT_LIST_QUEUED) && + atomic_read(&msg_queue->core_list_cnt)) { + spin_lock(&msg_queue->core_ctx.ready_lock); + ctx->msg_queue.status |= CONTEXT_LIST_QUEUED; + spin_unlock(&msg_queue->core_ctx.ready_lock); + queue_work(ctx->dev->core_workqueue, &msg_queue->core_work); } - spin_unlock(&dev->msg_queue_core_ctx.ready_lock); } int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, @@ -302,14 +280,14 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, if (msg_queue->wdma_addr.size) return 0; - msg_queue->ctx = ctx; - msg_queue->core_work_cnt = 0; vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0); + vdec_msg_queue_init_ctx(&msg_queue->core_ctx, MTK_VDEC_CORE); INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work); atomic_set(&msg_queue->lat_list_cnt, 0); atomic_set(&msg_queue->core_list_cnt, 0); init_waitqueue_head(&msg_queue->core_dec_done); + msg_queue->status = CONTEXT_LIST_EMPTY; msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(ctx->picinfo.buf_w, @@ -322,6 +300,10 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr; msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr; + msg_queue->empty_lat_buf.ctx = ctx; + msg_queue->empty_lat_buf.core_decode = NULL; + msg_queue->empty_lat_buf.is_last_frame = true; + for (i = 0; i < NUM_BUFFER_COUNT; i++) { lat_buf = &msg_queue->lat_buf[i]; @@ -347,6 +329,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, lat_buf->ctx = ctx; lat_buf->core_decode = core_decode; + lat_buf->is_last_frame = false; err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf); if (err) { mtk_v4l2_err("failed to qbuf buf[%d]", i); diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h index a5d44bc97c16..8f771874f8e6 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h @@ -22,6 +22,18 @@ struct mtk_vcodec_dev; typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf); /** + * enum core_ctx_status - Context decode status for core hardwre. + * @CONTEXT_LIST_EMPTY: No buffer queued on core hardware(must always be 0) + * @CONTEXT_LIST_QUEUED: Buffer queued to core work list + * @CONTEXT_LIST_DEC_DONE: context decode done + */ +enum core_ctx_status { + CONTEXT_LIST_EMPTY = 0, + CONTEXT_LIST_QUEUED, + CONTEXT_LIST_DEC_DONE, +}; + +/** * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed * @ready_to_use: ready used queue used to signalize when get a job queue * @ready_queue: list of ready lat buffer queues @@ -50,6 +62,8 @@ struct vdec_msg_queue_ctx { * @core_decode: different codec use different decode callback function * @lat_list: add lat buffer to lat head list * @core_list: add lat buffer to core head list + * + * @is_last_frame: meaning this buffer is the last frame */ struct vdec_lat_buf { struct mtk_vcodec_mem wdma_err_addr; @@ -62,6 +76,8 @@ struct vdec_lat_buf { core_decode_cb_t core_decode; struct list_head lat_list; struct list_head core_list; + + bool is_last_frame; }; /** @@ -72,12 +88,14 @@ struct vdec_lat_buf { * @wdma_wptr_addr: ube write point * @core_work: core hardware work * @lat_ctx: used to store lat buffer list - * @ctx: point to mtk_vcodec_ctx + * @core_ctx: used to store core buffer list * * @lat_list_cnt: used to record each instance lat list count * @core_list_cnt: used to record each instance core list count + * @flush_done: core flush done status + * @empty_lat_buf: the last lat buf used to flush decode * @core_dec_done: core work queue decode done event - * @core_work_cnt: the number of core work in work queue + * @status: current context decode status for core hardware */ struct vdec_msg_queue { struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT]; @@ -88,12 +106,14 @@ struct vdec_msg_queue { struct work_struct core_work; struct vdec_msg_queue_ctx lat_ctx; - struct mtk_vcodec_ctx *ctx; + struct vdec_msg_queue_ctx core_ctx; atomic_t lat_list_cnt; atomic_t core_list_cnt; + bool flush_done; + struct vdec_lat_buf empty_lat_buf; wait_queue_head_t core_dec_done; - int core_work_cnt; + int status; }; /** diff --git a/drivers/media/platform/nxp/imx7-media-csi.c b/drivers/media/platform/nxp/imx7-media-csi.c index b701e823436a..0bd2613b9320 100644 --- a/drivers/media/platform/nxp/imx7-media-csi.c +++ b/drivers/media/platform/nxp/imx7-media-csi.c @@ -1014,39 +1014,6 @@ static int imx7_csi_enum_mbus_formats(u32 *code, u32 index) return -EINVAL; } -static int imx7_csi_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, - const struct v4l2_mbus_framefmt *mbus, - const struct imx7_csi_pixfmt *cc) -{ - u32 width; - u32 stride; - - if (!cc) { - cc = imx7_csi_find_mbus_format(mbus->code); - if (!cc) - return -EINVAL; - } - - /* Round up width for minimum burst size */ - width = round_up(mbus->width, 8); - - /* Round up stride for IDMAC line start address alignment */ - stride = round_up((width * cc->bpp) >> 3, 8); - - pix->width = width; - pix->height = mbus->height; - pix->pixelformat = cc->fourcc; - pix->colorspace = mbus->colorspace; - pix->xfer_func = mbus->xfer_func; - pix->ycbcr_enc = mbus->ycbcr_enc; - pix->quantization = mbus->quantization; - pix->field = mbus->field; - pix->bytesperline = stride; - pix->sizeimage = stride * pix->height; - - return 0; -} - /* ----------------------------------------------------------------------------- * Video Capture Device - IOCTLs */ @@ -1145,8 +1112,13 @@ static const struct imx7_csi_pixfmt * __imx7_csi_video_try_fmt(struct v4l2_pix_format *pixfmt, struct v4l2_rect *compose) { - struct v4l2_mbus_framefmt fmt_src; const struct imx7_csi_pixfmt *cc; + u32 walign; + + if (compose) { + compose->width = pixfmt->width; + compose->height = pixfmt->height; + } /* * Find the pixel format, default to the first supported format if not @@ -1158,27 +1130,19 @@ __imx7_csi_video_try_fmt(struct v4l2_pix_format *pixfmt, cc = imx7_csi_find_pixel_format(pixfmt->pixelformat); } - /* Allow IDMAC interweave but enforce field order from source. */ - if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) { - switch (pixfmt->field) { - case V4L2_FIELD_SEQ_TB: - pixfmt->field = V4L2_FIELD_INTERLACED_TB; - break; - case V4L2_FIELD_SEQ_BT: - pixfmt->field = V4L2_FIELD_INTERLACED_BT; - break; - default: - break; - } - } + /* + * The width alignment is 8 bytes as indicated by the + * CSI_IMAG_PARA.IMAGE_WIDTH documentation. Convert it to pixels. + * + * TODO: Implement configurable stride support. + */ + walign = 8 * 8 / cc->bpp; + v4l_bound_align_image(&pixfmt->width, 1, 0xffff, walign, + &pixfmt->height, 1, 0xffff, 1, 0); - v4l2_fill_mbus_format(&fmt_src, pixfmt, 0); - imx7_csi_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src, cc); - - if (compose) { - compose->width = fmt_src.width; - compose->height = fmt_src.height; - } + pixfmt->bytesperline = pixfmt->width * cc->bpp / 8; + pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; + pixfmt->field = V4L2_FIELD_NONE; return cc; } @@ -1606,22 +1570,14 @@ static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi) return buf; } -static int imx7_csi_video_init_format(struct imx7_csi *csi) +static void imx7_csi_video_init_format(struct imx7_csi *csi) { - struct v4l2_mbus_framefmt format = { }; - - format.code = IMX7_CSI_DEF_MBUS_CODE; - format.width = IMX7_CSI_DEF_PIX_WIDTH; - format.height = IMX7_CSI_DEF_PIX_HEIGHT; - format.field = V4L2_FIELD_NONE; - - imx7_csi_mbus_fmt_to_pix_fmt(&csi->vdev_fmt, &format, NULL); - csi->vdev_compose.width = format.width; - csi->vdev_compose.height = format.height; + struct v4l2_pix_format *pixfmt = &csi->vdev_fmt; - csi->vdev_cc = imx7_csi_find_pixel_format(csi->vdev_fmt.pixelformat); + pixfmt->width = IMX7_CSI_DEF_PIX_WIDTH; + pixfmt->height = IMX7_CSI_DEF_PIX_HEIGHT; - return 0; + csi->vdev_cc = __imx7_csi_video_try_fmt(pixfmt, &csi->vdev_compose); } static int imx7_csi_video_register(struct imx7_csi *csi) @@ -1634,9 +1590,7 @@ static int imx7_csi_video_register(struct imx7_csi *csi) vdev->v4l2_dev = v4l2_dev; /* Initialize the default format and compose rectangle. */ - ret = imx7_csi_video_init_format(csi); - if (ret < 0) - return ret; + imx7_csi_video_init_format(csi); /* Register the video device. */ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c index b5ffde46f31b..f7447b2f4d77 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c @@ -223,7 +223,7 @@ static int mxc_isi_crossbar_init_cfg(struct v4l2_subdev *sd, route->sink_pad = i; route->source_pad = i + xbar->num_sinks; route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE; - }; + } routing.num_routes = xbar->num_sources; routing.routes = routes; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index e0832f3f4f25..06c95568e5af 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -1541,7 +1541,11 @@ int msm_vfe_register_entities(struct vfe_device *vfe, } video_out->ops = &vfe->video_ops; - video_out->bpl_alignment = 8; + if (vfe->camss->version == CAMSS_845 || + vfe->camss->version == CAMSS_8250) + video_out->bpl_alignment = 16; + else + video_out->bpl_alignment = 8; video_out->line_based = 0; if (i == VFE_LINE_PIX) { video_out->bpl_alignment = 16; diff --git a/drivers/media/platform/renesas/rcar-isp.c b/drivers/media/platform/renesas/rcar-isp.c index f666b621338d..fee1a066f56b 100644 --- a/drivers/media/platform/renesas/rcar-isp.c +++ b/drivers/media/platform/renesas/rcar-isp.c @@ -430,6 +430,7 @@ static int risp_probe_resources(struct rcar_isp *isp, static const struct of_device_id risp_of_id_table[] = { { .compatible = "renesas,r8a779a0-isp" }, + { .compatible = "renesas,r8a779g0-isp" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, risp_of_id_table); diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index ff4bde9cc0e3..3c4f5eb93be1 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -1284,6 +1284,15 @@ static const struct rvin_info rcar_info_r8a779a0 = { .max_height = 4096, }; +static const struct rvin_info rcar_info_r8a779g0 = { + .model = RCAR_GEN3, + .use_mc = true, + .use_isp = true, + .nv12 = true, + .max_width = 4096, + .max_height = 4096, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a774a1", @@ -1349,6 +1358,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a779a0", .data = &rcar_info_r8a779a0, }, + { + .compatible = "renesas,vin-r8a779g0", + .data = &rcar_info_r8a779g0, + }, { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index e34060c2b039..7a134c0eff57 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -483,11 +483,15 @@ enum rcar_csi2_pads { struct rcar_csi2_info { int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps); int (*phy_post_init)(struct rcar_csi2 *priv); + int (*start_receiver)(struct rcar_csi2 *priv); + void (*enter_standby)(struct rcar_csi2 *priv); const struct rcsi2_mbps_reg *hsfreqrange; unsigned int csi0clkfreqrange; unsigned int num_channels; bool clear_ulps; bool use_isp; + bool support_dphy; + bool support_cphy; }; struct rcar_csi2 { @@ -509,6 +513,7 @@ struct rcar_csi2 { struct v4l2_mbus_framefmt mf; int stream_count; + bool cphy; unsigned short lanes; unsigned char lane_swap[4]; }; @@ -533,10 +538,17 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data) iowrite32(data, priv->base + reg); } -static void rcsi2_enter_standby(struct rcar_csi2 *priv) +static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv) { rcsi2_write(priv, PHYCNT_REG, 0); rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR); +} + +static void rcsi2_enter_standby(struct rcar_csi2 *priv) +{ + if (priv->info->enter_standby) + priv->info->enter_standby(priv); + reset_control_assert(priv->rstc); usleep_range(100, 150); pm_runtime_put(priv->dev); @@ -656,7 +668,16 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, return ret; } - if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) { + switch (mbus_config.type) { + case V4L2_MBUS_CSI2_CPHY: + if (!priv->cphy) + return -EINVAL; + break; + case V4L2_MBUS_CSI2_DPHY: + if (priv->cphy) + return -EINVAL; + break; + default: dev_err(priv->dev, "Unsupported media bus type %u\n", mbus_config.type); return -EINVAL; @@ -674,7 +695,7 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, return 0; } -static int rcsi2_start_receiver(struct rcar_csi2 *priv) +static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv) { const struct rcar_csi2_format *format; u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; @@ -821,7 +842,7 @@ static int rcsi2_start(struct rcar_csi2 *priv) if (ret < 0) return ret; - ret = rcsi2_start_receiver(priv); + ret = priv->info->start_receiver(priv); if (ret) { rcsi2_enter_standby(priv); return ret; @@ -1016,15 +1037,41 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, if (vep->base.port || vep->base.id) return -ENOTCONN; - if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { - dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); - return -EINVAL; - } - priv->lanes = vep->bus.mipi_csi2.num_data_lanes; - if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { - dev_err(priv->dev, "Unsupported number of data-lanes: %u\n", - priv->lanes); + + switch (vep->bus_type) { + case V4L2_MBUS_CSI2_DPHY: + if (!priv->info->support_dphy) { + dev_err(priv->dev, "D-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { + dev_err(priv->dev, + "Unsupported number of data-lanes for D-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = false; + break; + case V4L2_MBUS_CSI2_CPHY: + if (!priv->info->support_cphy) { + dev_err(priv->dev, "C-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 3) { + dev_err(priv->dev, + "Unsupported number of data-lanes for C-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = true; + break; + default: + dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); return -EINVAL; } @@ -1048,7 +1095,7 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) struct fwnode_handle *fwnode; struct fwnode_handle *ep; struct v4l2_fwnode_endpoint v4l2_ep = { - .bus_type = V4L2_MBUS_CSI2_DPHY + .bus_type = V4L2_MBUS_UNKNOWN, }; int ret; @@ -1363,63 +1410,90 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { .init_phtw = rcsi2_init_phtw_h3es2, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { .init_phtw = rcsi2_init_phtw_v3m_e3, .phy_post_init = rcsi2_phy_post_init_v3m_e3, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { .init_phtw = rcsi2_init_phtw_v3m_e3, .phy_post_init = rcsi2_phy_post_init_v3m_e3, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 2, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .init_phtw = rcsi2_init_phtw_v3u, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_v3u, .csi0clkfreqrange = 0x20, .clear_ulps = true, .use_isp = true, + .support_dphy = true, }; static const struct of_device_id rcar_csi2_of_table[] = { diff --git a/drivers/media/platform/renesas/rcar_fdp1.c b/drivers/media/platform/renesas/rcar_fdp1.c index f43e458590b8..ab39cd2201c8 100644 --- a/drivers/media/platform/renesas/rcar_fdp1.c +++ b/drivers/media/platform/renesas/rcar_fdp1.c @@ -254,6 +254,8 @@ MODULE_PARM_DESC(debug, "activate debug info"); /* Internal Data (HW Version) */ #define FD1_IP_INTDATA 0x0800 +/* R-Car Gen2 HW manual says zero, but actual value matches R-Car H3 ES1.x */ +#define FD1_IP_GEN2 0x02010101 #define FD1_IP_M3W 0x02010202 #define FD1_IP_H3 0x02010203 #define FD1_IP_M3N 0x02010204 @@ -2360,6 +2362,9 @@ static int fdp1_probe(struct platform_device *pdev) hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); switch (hw_version) { + case FD1_IP_GEN2: + dprintk(fdp1, "FDP1 Version R-Car Gen2\n"); + break; case FD1_IP_M3W: dprintk(fdp1, "FDP1 Version R-Car M3-W\n"); break; diff --git a/drivers/media/platform/renesas/rcar_jpu.c b/drivers/media/platform/renesas/rcar_jpu.c index e7f604807825..2b8cb50f54de 100644 --- a/drivers/media/platform/renesas/rcar_jpu.c +++ b/drivers/media/platform/renesas/rcar_jpu.c @@ -28,6 +28,7 @@ #include <linux/spinlock.h> #include <linux/string.h> #include <linux/videodev2.h> +#include <media/jpeg.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-event.h> @@ -71,19 +72,6 @@ #define JPU_JPEG_DEFAULT_422_PIX_FMT V4L2_PIX_FMT_NV16M #define JPU_JPEG_DEFAULT_420_PIX_FMT V4L2_PIX_FMT_NV12M -/* JPEG markers */ -#define TEM 0x01 -#define SOF0 0xc0 -#define RST 0xd0 -#define SOI 0xd8 -#define EOI 0xd9 -#define DHP 0xde -#define DHT 0xc4 -#define COM 0xfe -#define DQT 0xdb -#define DRI 0xdd -#define APP0 0xe0 - #define JPU_RESET_TIMEOUT 100 /* ms */ #define JPU_JOB_TIMEOUT 300 /* ms */ #define JPU_MAX_QUALITY 4 @@ -330,26 +318,32 @@ static const u8 zigzag[] = { * Huffman tables; Padding with 0xff (33.3.27 R01UH0501EJ0100 Rev.1.00) */ #define JPU_JPEG_HDR_BLOB { \ - 0xff, SOI, 0xff, DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_LUM, \ - [JPU_JPEG_QTBL_LUM_OFFSET ... \ + 0xff, JPEG_MARKER_SOI, 0xff, JPEG_MARKER_DQT, 0x00, \ + JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_LUM, \ + [JPU_JPEG_QTBL_LUM_OFFSET ... \ JPU_JPEG_QTBL_LUM_OFFSET + JPU_JPEG_QTBL_SIZE - 1] = 0x00, \ - 0xff, DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_CHR, \ + 0xff, JPEG_MARKER_DQT, 0x00, JPU_JPEG_QTBL_SIZE + 0x3, JPU_JPEG_CHR, \ [JPU_JPEG_QTBL_CHR_OFFSET ... JPU_JPEG_QTBL_CHR_OFFSET + \ - JPU_JPEG_QTBL_SIZE - 1] = 0x00, 0xff, SOF0, 0x00, 0x11, 0x08, \ + JPU_JPEG_QTBL_SIZE - 1] = 0x00, \ + 0xff, JPEG_MARKER_SOF0, 0x00, 0x11, 0x08, \ [JPU_JPEG_HEIGHT_OFFSET ... JPU_JPEG_HEIGHT_OFFSET + 1] = 0x00, \ [JPU_JPEG_WIDTH_OFFSET ... JPU_JPEG_WIDTH_OFFSET + 1] = 0x00, \ 0x03, 0x01, [JPU_JPEG_SUBS_OFFSET] = 0x00, JPU_JPEG_LUM, \ 0x02, 0x11, JPU_JPEG_CHR, 0x03, 0x11, JPU_JPEG_CHR, \ - 0xff, DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, JPU_JPEG_LUM|JPU_JPEG_DC, \ + 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, \ + JPU_JPEG_LUM | JPU_JPEG_DC, \ [JPU_JPEG_HDCTBL_LUM_OFFSET ... \ JPU_JPEG_HDCTBL_LUM_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \ - 0xff, DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, JPU_JPEG_LUM|JPU_JPEG_AC, \ + 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, \ + JPU_JPEG_LUM | JPU_JPEG_AC, \ [JPU_JPEG_HACTBL_LUM_OFFSET ... \ JPU_JPEG_HACTBL_LUM_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \ - 0xff, DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, JPU_JPEG_CHR|JPU_JPEG_DC, \ + 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HDCTBL_SIZE + 0x3, \ + JPU_JPEG_CHR | JPU_JPEG_DC, \ [JPU_JPEG_HDCTBL_CHR_OFFSET ... \ JPU_JPEG_HDCTBL_CHR_OFFSET + JPU_JPEG_HDCTBL_SIZE - 1] = 0x00, \ - 0xff, DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, JPU_JPEG_CHR|JPU_JPEG_AC, \ + 0xff, JPEG_MARKER_DHT, 0x00, JPU_JPEG_HACTBL_SIZE + 0x3, \ + JPU_JPEG_CHR | JPU_JPEG_AC, \ [JPU_JPEG_HACTBL_CHR_OFFSET ... \ JPU_JPEG_HACTBL_CHR_OFFSET + JPU_JPEG_HACTBL_SIZE - 1] = 0x00, \ [JPU_JPEG_PADDING_OFFSET ... JPU_JPEG_HDR_SIZE - 1] = 0xff \ @@ -613,7 +607,8 @@ static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width, * basic size check and EOI - we don't want to let JPU cross * buffer bounds in any case. Hope it's stopping by EOI. */ - if (size < JPU_JPEG_MIN_SIZE || *(u8 *)(buffer + size - 1) != EOI) + if (size < JPU_JPEG_MIN_SIZE || + *(u8 *)(buffer + size - 1) != JPEG_MARKER_EOI) return 0; for (;;) { @@ -624,14 +619,14 @@ static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width, c = get_byte(&jpeg_buffer); while (c == 0xff || c == 0); - if (!soi && c == SOI) { + if (!soi && c == JPEG_MARKER_SOI) { soi = true; continue; - } else if (soi != (c != SOI)) + } else if (soi != (c != JPEG_MARKER_SOI)) return 0; switch (c) { - case SOF0: /* SOF0: baseline JPEG */ + case JPEG_MARKER_SOF0: /* SOF0: baseline JPEG */ skip(&jpeg_buffer, 3); /* segment length and bpp */ if (get_word_be(&jpeg_buffer, height) || get_word_be(&jpeg_buffer, width) || @@ -640,11 +635,11 @@ static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width, skip(&jpeg_buffer, 1); return get_byte(&jpeg_buffer); - case DHT: - case DQT: - case COM: - case DRI: - case APP0 ... APP0 + 0x0f: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DQT: + case JPEG_MARKER_COM: + case JPEG_MARKER_DRI: + case JPEG_MARKER_APP0 ... JPEG_MARKER_APP0 + 0x0f: if (get_word_be(&jpeg_buffer, &word)) return 0; skip(&jpeg_buffer, (long)word - 2); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index 30dad7383654..d6489c62b081 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -81,10 +81,10 @@ #define CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(x) (((x) & 0x3) << 4) #define CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(x) (((x) & 0x3) << 8) #define CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(x) (((x) & 0x3) << 12) -#define CSIDPHYSKW0_DEFAULT_SKW CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1) +#define CSIDPHYSKW0_DEFAULT_SKW (CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1)) #define VSRSTS_RETRIES 20 diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 67dcf22e5ba3..e4b8ce9ab3c6 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -76,10 +76,7 @@ static irqreturn_t rga_isr(int irq, void *prv) WARN_ON(!src); WARN_ON(!dst); - dst->timecode = src->timecode; - dst->vb2_buf.timestamp = src->vb2_buf.timestamp; - dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; - dst->flags |= src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + v4l2_m2m_buf_copy_metadata(src, dst, true); v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/samsung/exynos4-is/Kconfig b/drivers/media/platform/samsung/exynos4-is/Kconfig index da33faa7132e..7f9ba053dd8e 100644 --- a/drivers/media/platform/samsung/exynos4-is/Kconfig +++ b/drivers/media/platform/samsung/exynos4-is/Kconfig @@ -47,7 +47,7 @@ config VIDEO_S5P_MIPI_CSIS config VIDEO_EXYNOS_FIMC_LITE tristate "EXYNOS FIMC-LITE camera interface driver" depends on I2C - depends on SOC_EXYNOS4412 || SOC_EXYNOS5250 || COMPILE_TEST + depends on SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250 || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG select VIDEO_EXYNOS4_IS_COMMON diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index a2034ade8b9e..976b4f747ad4 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -1128,7 +1128,7 @@ static const struct fimc_drvdata fimc_drvdata_exynos4210 = { .out_buf_count = 32, }; -/* EXYNOS4412 */ +/* EXYNOS4212, EXYNOS4412 */ static const struct fimc_drvdata fimc_drvdata_exynos4x12 = { .num_entities = 4, .lclk_frequency = 166000000UL, diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c index 24b3dda26714..c3146ae08447 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c @@ -1621,7 +1621,7 @@ static const struct dev_pm_ops fimc_lite_pm_ops = { NULL) }; -/* EXYNOS4412 */ +/* EXYNOS4212, EXYNOS4412 */ static struct flite_drvdata fimc_lite_drvdata_exynos4 = { .max_width = 8192, .max_height = 8192, diff --git a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h index 5570c79f122f..4b665a3b630f 100644 --- a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h @@ -11,6 +11,7 @@ #define JPEG_CORE_H_ #include <linux/interrupt.h> +#include <media/jpeg.h> #include <media/v4l2-device.h> #include <media/v4l2-fh.h> #include <media/v4l2-ctrls.h> @@ -36,17 +37,6 @@ #define EXYNOS3250_IRQ_TIMEOUT 0x10000000 -/* a selection of JPEG markers */ -#define JPEG_MARKER_TEM 0x01 -#define JPEG_MARKER_SOF0 0xc0 -#define JPEG_MARKER_DHT 0xc4 -#define JPEG_MARKER_RST 0xd0 -#define JPEG_MARKER_SOI 0xd8 -#define JPEG_MARKER_EOI 0xd9 -#define JPEG_MARKER_SOS 0xda -#define JPEG_MARKER_DQT 0xdb -#define JPEG_MARKER_DHP 0xde - /* Flags that indicate a format can be used for capture/output */ #define SJPEG_FMT_FLAG_ENC_CAPTURE (1 << 0) #define SJPEG_FMT_FLAG_ENC_OUTPUT (1 << 1) diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c index 45ade7210d26..5dc1f908b49b 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c @@ -16,8 +16,10 @@ #include <linux/dma-mapping.h> #include <linux/dvb/dmx.h> #include <linux/dvb/frontend.h> +#include <linux/err.h> #include <linux/errno.h> #include <linux/firmware.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -135,7 +137,7 @@ static void channel_swdemux_tsklet(struct tasklet_struct *t) static int c8sectpfe_start_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *demux = dvbdmxfeed->demux; - struct stdemux *stdemux = (struct stdemux *)demux->priv; + struct stdemux *stdemux = demux->priv; struct c8sectpfei *fei = stdemux->c8sectpfei; struct channel_info *channel; u32 tmp; @@ -256,7 +258,7 @@ static int c8sectpfe_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *demux = dvbdmxfeed->demux; - struct stdemux *stdemux = (struct stdemux *)demux->priv; + struct stdemux *stdemux = demux->priv; struct c8sectpfei *fei = stdemux->c8sectpfei; struct channel_info *channel; int idlereq; @@ -812,30 +814,23 @@ static int c8sectpfe_probe(struct platform_device *pdev) } of_node_put(i2c_bus); - tsin->rst_gpio = of_get_named_gpio(child, "reset-gpios", 0); - - ret = gpio_is_valid(tsin->rst_gpio); - if (!ret) { - dev_err(dev, - "reset gpio for tsin%d not valid (gpio=%d)\n", - tsin->tsin_id, tsin->rst_gpio); - ret = -EINVAL; - goto err_node_put; - } - - ret = devm_gpio_request_one(dev, tsin->rst_gpio, - GPIOF_OUT_INIT_LOW, "NIM reset"); + /* Acquire reset GPIO and activate it */ + tsin->rst_gpio = devm_fwnode_gpiod_get(dev, + of_fwnode_handle(child), + "reset", GPIOD_OUT_HIGH, + "NIM reset"); + ret = PTR_ERR_OR_ZERO(tsin->rst_gpio); if (ret && ret != -EBUSY) { - dev_err(dev, "Can't request tsin%d reset gpio\n" - , fei->channel_data[index]->tsin_id); + dev_err(dev, "Can't request tsin%d reset gpio\n", + fei->channel_data[index]->tsin_id); goto err_node_put; } if (!ret) { - /* toggle reset lines */ - gpio_direction_output(tsin->rst_gpio, 0); + /* wait for the chip to reset */ usleep_range(3500, 5000); - gpio_direction_output(tsin->rst_gpio, 1); + /* release the reset line */ + gpiod_set_value_cansleep(tsin->rst_gpio, 0); usleep_range(3000, 5000); } @@ -1173,7 +1168,7 @@ MODULE_DEVICE_TABLE(of, c8sectpfe_match); static struct platform_driver c8sectpfe_driver = { .driver = { .name = "c8sectpfe", - .of_match_table = of_match_ptr(c8sectpfe_match), + .of_match_table = c8sectpfe_match, }, .probe = c8sectpfe_probe, .remove_new = c8sectpfe_remove, diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h index c9d6021904cd..bf377cc82225 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h +++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h @@ -16,6 +16,8 @@ #define C8SECTPFE_MAX_TSIN_CHAN 8 +struct gpio_desc; + struct channel_info { int tsin_id; @@ -25,7 +27,7 @@ struct channel_info { int i2c; int dvb_card; - int rst_gpio; + struct gpio_desc *rst_gpio; struct i2c_adapter *i2c_adapter; struct i2c_adapter *tuner_i2c; diff --git a/drivers/media/platform/st/sti/hva/hva-h264.c b/drivers/media/platform/st/sti/hva/hva-h264.c index 98cb00d2d868..196e631fa4b8 100644 --- a/drivers/media/platform/st/sti/hva/hva-h264.c +++ b/drivers/media/platform/st/sti/hva/hva-h264.c @@ -591,7 +591,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx, { struct hva_dev *hva = ctx_to_hdev(pctx); struct device *dev = ctx_to_dev(pctx); - struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv; + struct hva_h264_ctx *ctx = pctx->priv; struct hva_buffer *seq_info = ctx->seq_info; struct hva_buffer *fwd_ref_frame = ctx->ref_frame; struct hva_buffer *loc_rec_frame = ctx->rec_frame; @@ -984,7 +984,7 @@ err: static int hva_h264_close(struct hva_ctx *pctx) { - struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv; + struct hva_h264_ctx *ctx = pctx->priv; struct device *dev = ctx_to_dev(pctx); if (ctx->seq_info) @@ -1007,8 +1007,8 @@ static int hva_h264_close(struct hva_ctx *pctx) static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame, struct hva_stream *stream) { - struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv; - struct hva_h264_task *task = (struct hva_h264_task *)ctx->task->vaddr; + struct hva_h264_ctx *ctx = pctx->priv; + struct hva_h264_task *task = ctx->task->vaddr; u32 stuffing_bytes = 0; int ret = 0; diff --git a/drivers/media/platform/verisilicon/hantro_hevc.c b/drivers/media/platform/verisilicon/hantro_hevc.c index 9383fb7081f6..2c14330bc562 100644 --- a/drivers/media/platform/verisilicon/hantro_hevc.c +++ b/drivers/media/platform/verisilicon/hantro_hevc.c @@ -109,7 +109,7 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx) &hevc_dec->tile_filter.dma, GFP_KERNEL); if (!hevc_dec->tile_filter.cpu) - goto err_free_tile_buffers; + return -ENOMEM; hevc_dec->tile_filter.size = size; size = (VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8; @@ -125,31 +125,26 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx) &hevc_dec->tile_bsd.dma, GFP_KERNEL); if (!hevc_dec->tile_bsd.cpu) - goto err_free_tile_buffers; + goto err_free_sao_buffers; hevc_dec->tile_bsd.size = size; hevc_dec->num_tile_cols_allocated = num_tile_cols; return 0; -err_free_tile_buffers: - if (hevc_dec->tile_filter.cpu) - dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size, - hevc_dec->tile_filter.cpu, - hevc_dec->tile_filter.dma); - hevc_dec->tile_filter.cpu = NULL; - +err_free_sao_buffers: if (hevc_dec->tile_sao.cpu) dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size, hevc_dec->tile_sao.cpu, hevc_dec->tile_sao.dma); hevc_dec->tile_sao.cpu = NULL; - if (hevc_dec->tile_bsd.cpu) - dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size, - hevc_dec->tile_bsd.cpu, - hevc_dec->tile_bsd.dma); - hevc_dec->tile_bsd.cpu = NULL; +err_free_tile_buffers: + if (hevc_dec->tile_filter.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size, + hevc_dec->tile_filter.cpu, + hevc_dec->tile_filter.dma); + hevc_dec->tile_filter.cpu = NULL; return -ENOMEM; } diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 1d9f32e5a917..6d273abfe16c 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -24,7 +24,6 @@ struct video_mux { struct v4l2_subdev subdev; struct v4l2_async_notifier notifier; struct media_pad *pads; - struct v4l2_mbus_framefmt *format_mbus; struct mux_control *mux; struct mutex lock; int active; @@ -71,6 +70,9 @@ static int video_mux_link_setup(struct media_entity *entity, mutex_lock(&vmux->lock); if (flags & MEDIA_LNK_FL_ENABLED) { + struct v4l2_subdev_state *sd_state; + struct v4l2_mbus_framefmt *source_mbusformat; + if (vmux->active == local->index) goto out; @@ -86,7 +88,12 @@ static int video_mux_link_setup(struct media_entity *entity, vmux->active = local->index; /* Propagate the active format to the source */ - vmux->format_mbus[source_pad] = vmux->format_mbus[vmux->active]; + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + source_mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, + source_pad); + *source_mbusformat = *v4l2_subdev_get_pad_format(sd, sd_state, + vmux->active); + v4l2_subdev_unlock_state(sd_state); } else { if (vmux->active != local->index) goto out; @@ -138,40 +145,6 @@ static const struct v4l2_subdev_video_ops video_mux_subdev_video_ops = { .s_stream = video_mux_s_stream, }; -static struct v4l2_mbus_framefmt * -__video_mux_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - unsigned int pad, u32 which) -{ - struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); - - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(sd, sd_state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &vmux->format_mbus[pad]; - default: - return NULL; - } -} - -static int video_mux_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *sdformat) -{ - struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); - - mutex_lock(&vmux->lock); - - sdformat->format = *__video_mux_get_pad_format(sd, sd_state, - sdformat->pad, - sdformat->which); - - mutex_unlock(&vmux->lock); - - return 0; -} - static int video_mux_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) @@ -181,14 +154,11 @@ static int video_mux_set_format(struct v4l2_subdev *sd, struct media_pad *pad = &vmux->pads[sdformat->pad]; u16 source_pad = sd->entity.num_pads - 1; - mbusformat = __video_mux_get_pad_format(sd, sd_state, sdformat->pad, - sdformat->which); + mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, sdformat->pad); if (!mbusformat) return -EINVAL; - source_mbusformat = __video_mux_get_pad_format(sd, sd_state, - source_pad, - sdformat->which); + source_mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, source_pad); if (!source_mbusformat) return -EINVAL; @@ -298,7 +268,8 @@ static int video_mux_set_format(struct v4l2_subdev *sd, /* Source pad mirrors active sink pad, no limitations on sink pads */ if ((pad->flags & MEDIA_PAD_FL_SOURCE) && vmux->active >= 0) - sdformat->format = vmux->format_mbus[vmux->active]; + sdformat->format = *v4l2_subdev_get_pad_format(sd, sd_state, + vmux->active); *mbusformat = sdformat->format; @@ -321,7 +292,7 @@ static int video_mux_init_cfg(struct v4l2_subdev *sd, mutex_lock(&vmux->lock); for (i = 0; i < sd->entity.num_pads; i++) { - mbusformat = v4l2_subdev_get_try_format(sd, sd_state, i); + mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, i); *mbusformat = video_mux_format_mbus_default; } @@ -332,7 +303,7 @@ static int video_mux_init_cfg(struct v4l2_subdev *sd, static const struct v4l2_subdev_pad_ops video_mux_pad_ops = { .init_cfg = video_mux_init_cfg, - .get_fmt = video_mux_get_format, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = video_mux_set_format, }; @@ -389,7 +360,7 @@ static int video_mux_async_register(struct video_mux *vmux, ret = PTR_ERR(asd); /* OK if asd already exists */ if (ret != -EEXIST) - return ret; + goto err_nf_cleanup; } } @@ -397,9 +368,19 @@ static int video_mux_async_register(struct video_mux *vmux, ret = v4l2_async_subdev_nf_register(&vmux->subdev, &vmux->notifier); if (ret) - return ret; + goto err_nf_cleanup; + + ret = v4l2_async_register_subdev(&vmux->subdev); + if (ret) + goto err_nf_unregister; - return v4l2_async_register_subdev(&vmux->subdev); + return 0; + +err_nf_unregister: + v4l2_async_nf_unregister(&vmux->notifier); +err_nf_cleanup: + v4l2_async_nf_cleanup(&vmux->notifier); + return ret; } static int video_mux_probe(struct platform_device *pdev) @@ -452,17 +433,9 @@ static int video_mux_probe(struct platform_device *pdev) if (!vmux->pads) return -ENOMEM; - vmux->format_mbus = devm_kcalloc(dev, num_pads, - sizeof(*vmux->format_mbus), - GFP_KERNEL); - if (!vmux->format_mbus) - return -ENOMEM; - - for (i = 0; i < num_pads; i++) { + for (i = 0; i < num_pads; i++) vmux->pads[i].flags = (i < num_pads - 1) ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; - vmux->format_mbus[i] = video_mux_format_mbus_default; - } vmux->subdev.entity.function = MEDIA_ENT_F_VID_MUX; ret = media_entity_pads_init(&vmux->subdev.entity, num_pads, @@ -472,12 +445,20 @@ static int video_mux_probe(struct platform_device *pdev) vmux->subdev.entity.ops = &video_mux_ops; + ret = v4l2_subdev_init_finalize(&vmux->subdev); + if (ret < 0) + goto err_entity_cleanup; + ret = video_mux_async_register(vmux, num_pads - 1); - if (ret) { - v4l2_async_nf_unregister(&vmux->notifier); - v4l2_async_nf_cleanup(&vmux->notifier); - } + if (ret) + goto err_subdev_cleanup; + + return 0; +err_subdev_cleanup: + v4l2_subdev_cleanup(&vmux->subdev); +err_entity_cleanup: + media_entity_cleanup(&vmux->subdev.entity); return ret; } @@ -489,6 +470,7 @@ static void video_mux_remove(struct platform_device *pdev) v4l2_async_nf_unregister(&vmux->notifier); v4l2_async_nf_cleanup(&vmux->notifier); v4l2_async_unregister_subdev(sd); + v4l2_subdev_cleanup(sd); media_entity_cleanup(&sd->entity); } diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 2cb74afba49c..14e7dd3889ff 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -511,7 +511,7 @@ static struct i2c_driver tea5764_i2c_driver = { .driver = { .name = "radio-tea5764", }, - .probe_new = tea5764_i2c_probe, + .probe = tea5764_i2c_probe, .remove = tea5764_i2c_remove, .id_table = tea5764_id, }; diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c index 3c758a983344..91345198bbf1 100644 --- a/drivers/media/radio/saa7706h.c +++ b/drivers/media/radio/saa7706h.c @@ -405,7 +405,7 @@ static struct i2c_driver saa7706h_driver = { .driver = { .name = DRIVER_NAME, }, - .probe_new = saa7706h_probe, + .probe = saa7706h_probe, .remove = saa7706h_remove, .id_table = saa7706h_id, }; diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index a6ad926c2b4e..fd449e42c191 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -532,7 +532,7 @@ static struct i2c_driver si470x_i2c_driver = { .pm = &si470x_i2c_pm, #endif }, - .probe_new = si470x_i2c_probe, + .probe = si470x_i2c_probe, .remove = si470x_i2c_remove, .id_table = si470x_i2c_id, }; diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index 93d847c294e8..ddaf7a60b7d0 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -1657,7 +1657,7 @@ static struct i2c_driver si4713_i2c_driver = { .name = "si4713", .of_match_table = of_match_ptr(si4713_of_match), }, - .probe_new = si4713_probe, + .probe = si4713_probe, .remove = si4713_remove, .id_table = si4713_id, }; diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index d14c97d79e83..215168aa1588 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c @@ -183,7 +183,7 @@ static struct i2c_driver tef6862_driver = { .driver = { .name = DRIVER_NAME, }, - .probe_new = tef6862_probe, + .probe = tef6862_probe, .remove = tef6862_remove, .id_table = tef6862_id, }; diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.c b/drivers/media/test-drivers/vidtv/vidtv_demod.c index b878db798686..7a0cd9601917 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.c +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.c @@ -449,7 +449,7 @@ static struct i2c_driver vidtv_demod_i2c_driver = { .name = "dvb_vidtv_demod", .suppress_bind_attrs = true, }, - .probe_new = vidtv_demod_i2c_probe, + .probe = vidtv_demod_i2c_probe, .remove = vidtv_demod_i2c_remove, .id_table = vidtv_demod_i2c_id_table, }; diff --git a/drivers/media/test-drivers/vidtv/vidtv_tuner.c b/drivers/media/test-drivers/vidtv/vidtv_tuner.c index 55a4387f3854..a748737d47f3 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_tuner.c +++ b/drivers/media/test-drivers/vidtv/vidtv_tuner.c @@ -425,7 +425,7 @@ static struct i2c_driver vidtv_tuner_i2c_driver = { .name = "dvb_vidtv_tuner", .suppress_bind_attrs = true, }, - .probe_new = vidtv_tuner_i2c_probe, + .probe = vidtv_tuner_i2c_probe, .remove = vidtv_tuner_i2c_remove, .id_table = vidtv_tuner_i2c_id_table, }; diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index 801286dc1448..3a06df35a2d7 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -21,13 +21,8 @@ #include "vivid-kthread-cap.h" #include "vivid-vid-cap.h" -/* The number of discrete webcam framesizes */ -#define VIVID_WEBCAM_SIZES 6 -/* The number of discrete webcam frameintervals */ -#define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2) - /* Sizes must be in increasing order */ -static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = { +static const struct v4l2_frmsize_discrete webcam_sizes[] = { { 320, 180 }, { 640, 360 }, { 640, 480 }, @@ -40,21 +35,43 @@ static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = { * Intervals must be in increasing order and there must be twice as many * elements in this array as there are in webcam_sizes. */ -static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = { +static const struct v4l2_fract webcam_intervals[] = { { 1, 1 }, { 1, 2 }, { 1, 4 }, { 1, 5 }, { 1, 10 }, { 2, 25 }, - { 1, 15 }, + { 1, 15 }, /* 7 - maximum for 2160p */ { 1, 25 }, - { 1, 30 }, + { 1, 30 }, /* 9 - maximum for 1080p */ { 1, 40 }, { 1, 50 }, - { 1, 60 }, + { 1, 60 }, /* 12 - maximum for 720p */ + { 1, 120 }, }; +/* Limit maximum FPS rates for high resolutions */ +#define IVAL_COUNT_720P 12 /* 720p and up is limited to 60 fps */ +#define IVAL_COUNT_1080P 9 /* 1080p and up is limited to 30 fps */ +#define IVAL_COUNT_2160P 7 /* 2160p and up is limited to 15 fps */ + +static inline unsigned int webcam_ival_count(const struct vivid_dev *dev, + unsigned int frmsize_idx) +{ + if (webcam_sizes[frmsize_idx].height >= 2160) + return IVAL_COUNT_2160P; + + if (webcam_sizes[frmsize_idx].height >= 1080) + return IVAL_COUNT_1080P; + + if (webcam_sizes[frmsize_idx].height >= 720) + return IVAL_COUNT_720P; + + /* For low resolutions, allow all FPS rates */ + return ARRAY_SIZE(webcam_intervals); +} + static int vid_cap_queue_setup(struct vb2_queue *vq, unsigned *nbuffers, unsigned *nplanes, unsigned sizes[], struct device *alloc_devs[]) @@ -560,7 +577,7 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, if (vivid_is_webcam(dev)) { const struct v4l2_frmsize_discrete *sz = v4l2_find_nearest_size(webcam_sizes, - VIVID_WEBCAM_SIZES, width, + ARRAY_SIZE(webcam_sizes), width, height, mp->width, mp->height); w = sz->width; @@ -736,14 +753,16 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, compose->height /= factor; } } else if (vivid_is_webcam(dev)) { + unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx); + /* Guaranteed to be a match */ for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++) if (webcam_sizes[i].width == mp->width && webcam_sizes[i].height == mp->height) break; dev->webcam_size_idx = i; - if (dev->webcam_ival_idx >= 2 * (VIVID_WEBCAM_SIZES - i)) - dev->webcam_ival_idx = 2 * (VIVID_WEBCAM_SIZES - i) - 1; + if (dev->webcam_ival_idx >= ival_sz) + dev->webcam_ival_idx = ival_sz - 1; vivid_update_format_cap(dev, false); } else { struct v4l2_rect r = { 0, 0, mp->width, mp->height }; @@ -1636,7 +1655,7 @@ int vidioc_enum_frameintervals(struct file *file, void *priv, break; if (i == ARRAY_SIZE(webcam_sizes)) return -EINVAL; - if (fival->index >= 2 * (VIVID_WEBCAM_SIZES - i)) + if (fival->index >= webcam_ival_count(dev, i)) return -EINVAL; fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; fival->discrete = webcam_intervals[fival->index]; @@ -1663,7 +1682,7 @@ int vivid_vid_cap_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) { struct vivid_dev *dev = video_drvdata(file); - unsigned ival_sz = 2 * (VIVID_WEBCAM_SIZES - dev->webcam_size_idx); + unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx); struct v4l2_fract tpf; unsigned i; diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 7c269f3159ef..3893a00c18ce 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -729,7 +729,7 @@ static struct i2c_driver e4000_driver = { .name = "e4000", .suppress_bind_attrs = true, }, - .probe_new = e4000_probe, + .probe = e4000_probe, .remove = e4000_remove, .id_table = e4000_id_table, }; diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 3cd8279f4f2e..f6613dcf40a3 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -610,7 +610,7 @@ static struct i2c_driver fc2580_driver = { .name = "fc2580", .suppress_bind_attrs = true, }, - .probe_new = fc2580_probe, + .probe = fc2580_probe, .remove = fc2580_remove, .id_table = fc2580_id_table, }; diff --git a/drivers/media/tuners/m88rs6000t.c b/drivers/media/tuners/m88rs6000t.c index 7d172a5a66d9..2cd7f0e0c70d 100644 --- a/drivers/media/tuners/m88rs6000t.c +++ b/drivers/media/tuners/m88rs6000t.c @@ -718,7 +718,7 @@ static struct i2c_driver m88rs6000t_driver = { .driver = { .name = "m88rs6000t", }, - .probe_new = m88rs6000t_probe, + .probe = m88rs6000t_probe, .remove = m88rs6000t_remove, .id_table = m88rs6000t_id, }; diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c index e5d86874adb3..0278a9f0aeef 100644 --- a/drivers/media/tuners/mt2060.c +++ b/drivers/media/tuners/mt2060.c @@ -524,7 +524,7 @@ static struct i2c_driver mt2060_driver = { .name = "mt2060", .suppress_bind_attrs = true, }, - .probe_new = mt2060_probe, + .probe = mt2060_probe, .remove = mt2060_remove, .id_table = mt2060_id_table, }; diff --git a/drivers/media/tuners/mxl301rf.c b/drivers/media/tuners/mxl301rf.c index c35442a77ae5..9b2b237745ae 100644 --- a/drivers/media/tuners/mxl301rf.c +++ b/drivers/media/tuners/mxl301rf.c @@ -326,7 +326,7 @@ static struct i2c_driver mxl301rf_driver = { .driver = { .name = "mxl301rf", }, - .probe_new = mxl301rf_probe, + .probe = mxl301rf_probe, .remove = mxl301rf_remove, .id_table = mxl301rf_id, }; diff --git a/drivers/media/tuners/qm1d1b0004.c b/drivers/media/tuners/qm1d1b0004.c index 0b6f750c54ad..af2d3618b9d5 100644 --- a/drivers/media/tuners/qm1d1b0004.c +++ b/drivers/media/tuners/qm1d1b0004.c @@ -253,7 +253,7 @@ static struct i2c_driver qm1d1b0004_driver = { .driver = { .name = "qm1d1b0004", }, - .probe_new = qm1d1b0004_probe, + .probe = qm1d1b0004_probe, .remove = qm1d1b0004_remove, .id_table = qm1d1b0004_id, }; diff --git a/drivers/media/tuners/qm1d1c0042.c b/drivers/media/tuners/qm1d1c0042.c index f9be7a721d2c..ce7223315b0c 100644 --- a/drivers/media/tuners/qm1d1c0042.c +++ b/drivers/media/tuners/qm1d1c0042.c @@ -443,7 +443,7 @@ static struct i2c_driver qm1d1c0042_driver = { .driver = { .name = "qm1d1c0042", }, - .probe_new = qm1d1c0042_probe, + .probe = qm1d1c0042_probe, .remove = qm1d1c0042_remove, .id_table = qm1d1c0042_id, }; diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index 3fa3dcda917a..def06c262ea2 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -990,7 +990,7 @@ static struct i2c_driver si2157_driver = { .name = "si2157", .suppress_bind_attrs = true, }, - .probe_new = si2157_probe, + .probe = si2157_probe, .remove = si2157_remove, .id_table = si2157_id_table, }; diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c index 5fdf05a97415..8d742bd61df0 100644 --- a/drivers/media/tuners/tda18212.c +++ b/drivers/media/tuners/tda18212.c @@ -263,7 +263,7 @@ static struct i2c_driver tda18212_driver = { .driver = { .name = "tda18212", }, - .probe_new = tda18212_probe, + .probe = tda18212_probe, .remove = tda18212_remove, .id_table = tda18212_id, }; diff --git a/drivers/media/tuners/tda18250.c b/drivers/media/tuners/tda18250.c index 66ff2d035de7..32ea473f3f49 100644 --- a/drivers/media/tuners/tda18250.c +++ b/drivers/media/tuners/tda18250.c @@ -877,7 +877,7 @@ static struct i2c_driver tda18250_driver = { .driver = { .name = "tda18250", }, - .probe_new = tda18250_probe, + .probe = tda18250_probe, .remove = tda18250_remove, .id_table = tda18250_id_table, }; diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index ac38afd3441a..03a3a022b0a8 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -255,7 +255,7 @@ static struct i2c_driver tua9001_driver = { .name = "tua9001", .suppress_bind_attrs = true, }, - .probe_new = tua9001_probe, + .probe = tua9001_probe, .remove = tua9001_remove, .id_table = tua9001_id_table, }; diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index b3a09d3ac7d2..1e246b47766d 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -250,7 +250,7 @@ static void au0828_media_graph_notify(struct media_entity *new, create_link: if (decoder && mixer) { - ret = media_get_pad_index(decoder, false, + ret = media_get_pad_index(decoder, MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_AUDIO); if (ret >= 0) ret = media_create_pad_link(decoder, ret, diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 62ee09f28a0b..2dcbb49d66da 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -202,7 +202,8 @@ static int az6007_rc_query(struct dvb_usb_device *d) unsigned code; enum rc_proto proto; - az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); + if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0) + return -EIO; if (st->data[1] == 0x44) return 0; @@ -248,7 +249,7 @@ static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -290,7 +291,7 @@ static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -321,7 +322,7 @@ static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -367,7 +368,7 @@ static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca, u8 address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -398,7 +399,7 @@ failed: static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; int ret; u8 req; @@ -429,7 +430,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret, i; @@ -485,7 +486,7 @@ static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -514,7 +515,7 @@ failed: static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; u8 req; diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 9d6fa0556d7b..404e56b32145 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -1412,8 +1412,7 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, static void af9005_fe_release(struct dvb_frontend *fe) { - struct af9005_fe_state *state = - (struct af9005_fe_state *)fe->demodulator_priv; + struct af9005_fe_state *state = fe->demodulator_priv; kfree(state); } diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index a31c6f82f4e9..2bc27710427d 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -407,8 +407,8 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -449,8 +449,8 @@ static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -480,8 +480,8 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -526,8 +526,8 @@ static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca, u8 address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -557,7 +557,7 @@ failed: static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; int ret; u8 req; @@ -588,8 +588,8 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret, i; u8 req; @@ -644,8 +644,8 @@ static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -673,8 +673,8 @@ failed: static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; u16 value; @@ -719,7 +719,7 @@ static void az6027_ci_uninit(struct dvb_usb_device *d) if (NULL == d) return; - state = (struct az6027_device_state *)d->priv; + state = d->priv; if (NULL == state) return; @@ -735,7 +735,7 @@ static void az6027_ci_uninit(struct dvb_usb_device *d) static int az6027_ci_init(struct dvb_usb_adapter *a) { struct dvb_usb_device *d = a->dev; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct az6027_device_state *state = d->priv; int ret; deb_info("%s", __func__); diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c index 9f83560ba63d..586afe22d817 100644 --- a/drivers/media/usb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c @@ -195,7 +195,7 @@ static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, static void dtt200u_fe_release(struct dvb_frontend* fe) { - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; + struct dtt200u_fe_state *state = fe->demodulator_priv; kfree(state); } diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 8747960e6146..970b84c3f0b5 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -830,7 +830,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) for (i = 0; i < 256; i++) { if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { err("read eeprom failed."); - return -1; + return -EIO; } else { eepromline[i%16] = ibuf[0]; eeprom[i] = ibuf[0]; @@ -869,7 +869,7 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); if (ret != 2) { err("read eeprom failed."); - return -1; + return -EIO; } else { eepromline[i % 16] = ibuf[0]; eeprom[i] = ibuf[0]; @@ -903,7 +903,7 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) static int su3000_power_ctrl(struct dvb_usb_device *d, int i) { - struct dw2102_state *state = (struct dw2102_state *)d->priv; + struct dw2102_state *state = d->priv; int ret = 0; info("%s: %d, initialized %d", __func__, i, state->initialized); @@ -946,7 +946,7 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) for (i = 0; i < 6; i++) { obuf[1] = 0xf0 + i; if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) - return -1; + return -EIO; else mac[i] = ibuf[0]; } @@ -978,8 +978,7 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, .len = 2, }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (voltage == SEC_VOLTAGE_18) msg.buf = command_18v; else if (voltage == SEC_VOLTAGE_13) @@ -993,9 +992,8 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, static int s660_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { - struct dvb_usb_adapter *d = - (struct dvb_usb_adapter *)(fe->dvb->priv); - struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; + struct dvb_usb_adapter *d = fe->dvb->priv; + struct dw2102_state *st = d->dev->priv; dw210x_set_voltage(fe, voltage); if (st->old_set_voltage) @@ -1014,8 +1012,7 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) .buf = led_off, .len = 1 }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (offon) msg.buf = led_on; @@ -1025,9 +1022,8 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) static int tt_s2_4600_read_status(struct dvb_frontend *fe, enum fe_status *status) { - struct dvb_usb_adapter *d = - (struct dvb_usb_adapter *)(fe->dvb->priv); - struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; + struct dvb_usb_adapter *d = fe->dvb->priv; + struct dw2102_state *st = d->dev->priv; int ret; ret = st->fe_read_status(fe, status); @@ -2576,7 +2572,7 @@ static int dw2102_probe(struct usb_interface *intf, static void dw2102_disconnect(struct usb_interface *intf) { struct dvb_usb_device *d = usb_get_intfdata(intf); - struct dw2102_state *st = (struct dw2102_state *)d->priv; + struct dw2102_state *st = d->priv; struct i2c_client *client; /* remove I2C client for tuner */ diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c index 0da86f58aff6..98b2177667d2 100644 --- a/drivers/media/usb/dvb-usb/opera1.c +++ b/drivers/media/usb/dvb-usb/opera1.c @@ -172,8 +172,7 @@ static int opera1_set_voltage(struct dvb_frontend *fe, struct i2c_msg msg[] = { {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1}, }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (voltage == SEC_VOLTAGE_18) { msg[0].addr = ADDR_B601_VOLTAGE_18V; msg[0].buf = command_18v; diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index da42c989e071..2aab49003493 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -108,7 +108,7 @@ struct pctv452e_state { static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *buf; u8 id; unsigned int rlen; @@ -159,8 +159,8 @@ static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct pctv452e_state *state = d->priv; int ret; mutex_lock(&state->ca_mutex); @@ -292,8 +292,8 @@ static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct pctv452e_state *state = d->priv; u8 buf[1]; int ret; @@ -361,7 +361,7 @@ static void tt3650_ci_uninit(struct dvb_usb_device *d) if (NULL == d) return; - state = (struct pctv452e_state *)d->priv; + state = d->priv; if (NULL == state) return; @@ -379,7 +379,7 @@ static void tt3650_ci_uninit(struct dvb_usb_device *d) static int tt3650_ci_init(struct dvb_usb_adapter *a) { struct dvb_usb_device *d = a->dev; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; int ret; ci_dbg("%s", __func__); @@ -417,7 +417,7 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr, const u8 *snd_buf, u8 snd_len, u8 *rcv_buf, u8 rcv_len) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *buf; u8 id; int ret; @@ -516,7 +516,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter *adapter) static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *b0, *rx; int ret; @@ -567,7 +567,7 @@ ret: static int pctv452e_rc_query(struct dvb_usb_device *d) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *b, *rx; int ret, i; u8 id; diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index 29dfcc6d0b0a..db1fab96d529 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -620,7 +620,7 @@ static struct i2c_driver s2250_driver = { .driver = { .name = "s2250", }, - .probe_new = s2250_probe, + .probe = s2250_probe, .remove = s2250_remove, .id_table = s2250_id, }; diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 6f443c542c6d..640737d3b8ae 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -179,7 +179,8 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); - cancel_work_sync(&dev->surbs[i].wq); + if (dev->surbs[i].wq.func) + cancel_work_sync(&dev->surbs[i].wq); if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb); diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig index 4f50fb7db7b9..bf7c16baa9f8 100644 --- a/drivers/media/usb/stk1160/Kconfig +++ b/drivers/media/usb/stk1160/Kconfig @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only -config VIDEO_STK1160_COMMON +config VIDEO_STK1160 tristate "STK1160 USB video capture support" depends on VIDEO_DEV && I2C - + select VIDEOBUF2_VMALLOC + select VIDEO_SAA711X help This is a video4linux driver for STK1160 based video capture devices. @@ -12,10 +13,3 @@ config VIDEO_STK1160_COMMON This driver only provides support for video capture. For audio capture, you need to select the snd-usb-audio driver (i.e. CONFIG_SND_USB_AUDIO). - -config VIDEO_STK1160 - tristate - depends on VIDEO_STK1160_COMMON - default y - select VIDEOBUF2_VMALLOC - select VIDEO_SAA711X diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index c4474d4c44e2..79faa2560613 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1128,7 +1128,7 @@ static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) { struct ttusb_dec *dec = dvbdmxfeed->demux->priv; u8 b0[] = { 0x00, 0x00 }; - struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; + struct filter_info *finfo = dvbdmxfeed->priv; unsigned long flags; b0[1] = finfo->stream_id; diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 1c0d23c52203..5687089bea6e 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -1411,7 +1411,7 @@ static struct i2c_driver tuner_driver = { .name = "tuner", .pm = &tuner_pm_ops, }, - .probe_new = tuner_probe, + .probe = tuner_probe, .remove = tuner_remove, .command = tuner_command, .id_table = tuner_id, diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 22fe08fce0a9..52d349e72b8c 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -105,9 +105,11 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) /* Link the tuner and IF video output pads */ if (tuner) { if (if_vid) { - pad_source = media_get_pad_index(tuner, false, + pad_source = media_get_pad_index(tuner, + MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_ANALOG); - pad_sink = media_get_pad_index(if_vid, true, + pad_sink = media_get_pad_index(if_vid, + MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_source < 0 || pad_sink < 0) { dev_warn(mdev->dev, "Couldn't get tuner and/or PLL pad(s): (%d, %d)\n", @@ -122,9 +124,11 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) return ret; } - pad_source = media_get_pad_index(if_vid, false, + pad_source = media_get_pad_index(if_vid, + MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_ANALOG); - pad_sink = media_get_pad_index(decoder, true, + pad_sink = media_get_pad_index(decoder, + MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_source < 0 || pad_sink < 0) { dev_warn(mdev->dev, "get decoder and/or PLL pad(s): (%d, %d)\n", @@ -139,9 +143,11 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) return ret; } } else { - pad_source = media_get_pad_index(tuner, false, + pad_source = media_get_pad_index(tuner, + MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_ANALOG); - pad_sink = media_get_pad_index(decoder, true, + pad_sink = media_get_pad_index(decoder, + MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_source < 0 || pad_sink < 0) { dev_warn(mdev->dev, "couldn't get tuner and/or decoder pad(s): (%d, %d)\n", @@ -156,9 +162,11 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) } if (if_aud) { - pad_source = media_get_pad_index(tuner, false, + pad_source = media_get_pad_index(tuner, + MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_AUDIO); - pad_sink = media_get_pad_index(if_aud, true, + pad_sink = media_get_pad_index(if_aud, + MEDIA_PAD_FL_SINK, PAD_SIGNAL_AUDIO); if (pad_source < 0 || pad_sink < 0) { dev_warn(mdev->dev, "couldn't get tuner and/or decoder pad(s) for audio: (%d, %d)\n", @@ -180,7 +188,8 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) /* Create demod to V4L, VBI and SDR radio links */ if (io_v4l) { - pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + pad_source = media_get_pad_index(decoder, MEDIA_PAD_FL_SOURCE, + PAD_SIGNAL_DV); if (pad_source < 0) { dev_warn(mdev->dev, "couldn't get decoder output pad for V4L I/O\n"); return -EINVAL; @@ -195,7 +204,8 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) } if (io_swradio) { - pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + pad_source = media_get_pad_index(decoder, MEDIA_PAD_FL_SOURCE, + PAD_SIGNAL_DV); if (pad_source < 0) { dev_warn(mdev->dev, "couldn't get decoder output pad for SDR\n"); return -EINVAL; @@ -210,7 +220,8 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) } if (io_vbi) { - pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + pad_source = media_get_pad_index(decoder, MEDIA_PAD_FL_SOURCE, + PAD_SIGNAL_DV); if (pad_source < 0) { dev_warn(mdev->dev, "couldn't get decoder output pad for VBI\n"); return -EINVAL; @@ -231,7 +242,7 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) case MEDIA_ENT_F_CONN_RF: if (!tuner) continue; - pad_sink = media_get_pad_index(tuner, true, + pad_sink = media_get_pad_index(tuner, MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_sink < 0) { dev_warn(mdev->dev, "couldn't get tuner analog pad sink\n"); @@ -243,7 +254,8 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) break; case MEDIA_ENT_F_CONN_SVIDEO: case MEDIA_ENT_F_CONN_COMPOSITE: - pad_sink = media_get_pad_index(decoder, true, + pad_sink = media_get_pad_index(decoder, + MEDIA_PAD_FL_SINK, PAD_SIGNAL_ANALOG); if (pad_sink < 0) { dev_warn(mdev->dev, "couldn't get decoder analog pad sink\n"); |