From 11a1e0ed7908f04c896e69d0eb65e478c12f8519 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Oct 2016 11:41:13 -0300 Subject: [media] dvb-usb: warn if return value for USB read/write routines is not checked the return values for dvb_usb_generic_rw() and dvb_usb_generic_write() should be checked, as otherwise the drivers won't be doing the right thing in the case of errors. So, add __must_check to both declarations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dvb-usb.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h index 639c4678c65b..1448c3d27ea2 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -462,8 +462,10 @@ extern int dvb_usb_device_init(struct usb_interface *, extern void dvb_usb_device_exit(struct usb_interface *); /* the generic read/write method for device control */ -extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int); -extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); +extern int __must_check +dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16, int); +extern int __must_check +dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); /* commonly used remote control parsing */ extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); -- cgit v1.2.3 From 43ea43b9d8b27b7acd443ec59319faa3cdb8a616 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 08:21:43 -0300 Subject: [media] radio-bcm2048: don't ignore errors Remove this warning: drivers/staging/media/bcm2048/radio-bcm2048.c: In function 'bcm2048_set_rds_no_lock': drivers/staging/media/bcm2048/radio-bcm2048.c:467:6: warning: variable 'err' set but not used [-Wunused-but-set-variable] int err; ^~~ By returning the error code. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index ea15cc638097..4d9bd02ede47 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -482,6 +482,8 @@ static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on) flags); memset(&bdev->rds_info, 0, sizeof(bdev->rds_info)); } + if (err) + return err; return bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, bdev->cache_fm_rds_system); -- cgit v1.2.3 From 15c8ffc41a1559e37e3ec7106b261f5706490f1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 06:50:34 -0300 Subject: [media] tuner-xc2028: mark printk continuation lines as such This driver has a lot of printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tuner-xc2028.c | 93 +++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 317ef63ee789..55f6c858b9c3 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -179,67 +179,67 @@ static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) { if (type & BASE) - printk("BASE "); + printk(KERN_CONT "BASE "); if (type & INIT1) - printk("INIT1 "); + printk(KERN_CONT "INIT1 "); if (type & F8MHZ) - printk("F8MHZ "); + printk(KERN_CONT "F8MHZ "); if (type & MTS) - printk("MTS "); + printk(KERN_CONT "MTS "); if (type & D2620) - printk("D2620 "); + printk(KERN_CONT "D2620 "); if (type & D2633) - printk("D2633 "); + printk(KERN_CONT "D2633 "); if (type & DTV6) - printk("DTV6 "); + printk(KERN_CONT "DTV6 "); if (type & QAM) - printk("QAM "); + printk(KERN_CONT "QAM "); if (type & DTV7) - printk("DTV7 "); + printk(KERN_CONT "DTV7 "); if (type & DTV78) - printk("DTV78 "); + printk(KERN_CONT "DTV78 "); if (type & DTV8) - printk("DTV8 "); + printk(KERN_CONT "DTV8 "); if (type & FM) - printk("FM "); + printk(KERN_CONT "FM "); if (type & INPUT1) - printk("INPUT1 "); + printk(KERN_CONT "INPUT1 "); if (type & LCD) - printk("LCD "); + printk(KERN_CONT "LCD "); if (type & NOGD) - printk("NOGD "); + printk(KERN_CONT "NOGD "); if (type & MONO) - printk("MONO "); + printk(KERN_CONT "MONO "); if (type & ATSC) - printk("ATSC "); + printk(KERN_CONT "ATSC "); if (type & IF) - printk("IF "); + printk(KERN_CONT "IF "); if (type & LG60) - printk("LG60 "); + printk(KERN_CONT "LG60 "); if (type & ATI638) - printk("ATI638 "); + printk(KERN_CONT "ATI638 "); if (type & OREN538) - printk("OREN538 "); + printk(KERN_CONT "OREN538 "); if (type & OREN36) - printk("OREN36 "); + printk(KERN_CONT "OREN36 "); if (type & TOYOTA388) - printk("TOYOTA388 "); + printk(KERN_CONT "TOYOTA388 "); if (type & TOYOTA794) - printk("TOYOTA794 "); + printk(KERN_CONT "TOYOTA794 "); if (type & DIBCOM52) - printk("DIBCOM52 "); + printk(KERN_CONT "DIBCOM52 "); if (type & ZARLINK456) - printk("ZARLINK456 "); + printk(KERN_CONT "ZARLINK456 "); if (type & CHINA) - printk("CHINA "); + printk(KERN_CONT "CHINA "); if (type & F6MHZ) - printk("F6MHZ "); + printk(KERN_CONT "F6MHZ "); if (type & INPUT2) - printk("INPUT2 "); + printk(KERN_CONT "INPUT2 "); if (type & SCODE) - printk("SCODE "); + printk(KERN_CONT "SCODE "); if (type & HAS_IF) - printk("HAS_IF_%d ", int_freq); + printk(KERN_CONT "HAS_IF_%d ", int_freq); } static v4l2_std_id parse_audio_std_option(void) @@ -374,8 +374,8 @@ static int load_all_firmwares(struct dvb_frontend *fe, if (!size || size > endp - p) { tuner_err("Firmware type "); dump_firm_type(type); - printk("(%x), id %llx is corrupted " - "(size=%d, expected %d)\n", + printk(KERN_CONT + "(%x), id %llx is corrupted (size=%d, expected %d)\n", type, (unsigned long long)id, (unsigned)(endp - p), size); goto corrupt; @@ -390,7 +390,7 @@ static int load_all_firmwares(struct dvb_frontend *fe, tuner_dbg("Reading firmware type "); if (debug) { dump_firm_type_and_int_freq(type, int_freq); - printk("(%x), id %llx, size=%d.\n", + printk(KERN_CONT "(%x), id %llx, size=%d.\n", type, (unsigned long long)id, size); } @@ -439,7 +439,8 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, tuner_dbg("%s called, want type=", __func__); if (debug) { dump_firm_type(type); - printk("(%x), id %016llx.\n", type, (unsigned long long)*id); + printk(KERN_CONT "(%x), id %016llx.\n", + type, (unsigned long long)*id); } if (!priv->firm) { @@ -498,7 +499,8 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, tuner_dbg("Selecting best matching firmware (%d bits) for " "type=", best_nr_matches); dump_firm_type(type); - printk("(%x), id %016llx:\n", type, (unsigned long long)*id); + printk(KERN_CONT + "(%x), id %016llx:\n", type, (unsigned long long)*id); i = best_i; goto found; } @@ -515,7 +517,8 @@ ret: tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found"); if (debug) { dump_firm_type(type); - printk("(%x), id %016llx.\n", type, (unsigned long long)*id); + printk(KERN_CONT "(%x), id %016llx.\n", + type, (unsigned long long)*id); } return i; } @@ -555,8 +558,8 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, tuner_info("Loading firmware for type="); dump_firm_type(priv->firm[pos].type); - printk("(%x), id %016llx.\n", priv->firm[pos].type, - (unsigned long long)*id); + printk(KERN_CONT "(%x), id %016llx.\n", + priv->firm[pos].type, (unsigned long long)*id); p = priv->firm[pos].ptr; endp = p + priv->firm[pos].size; @@ -689,7 +692,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, tuner_info("Loading SCODE for type="); dump_firm_type_and_int_freq(priv->firm[pos].type, priv->firm[pos].int_freq); - printk("(%x), id %016llx.\n", priv->firm[pos].type, + printk(KERN_CONT "(%x), id %016llx.\n", priv->firm[pos].type, (unsigned long long)*id); if (priv->firm_version < 0x0202) @@ -741,15 +744,15 @@ retry: tuner_dbg("checking firmware, user requested type="); if (debug) { dump_firm_type(new_fw.type); - printk("(%x), id %016llx, ", new_fw.type, + printk(KERN_CONT "(%x), id %016llx, ", new_fw.type, (unsigned long long)new_fw.std_req); if (!int_freq) { - printk("scode_tbl "); + printk(KERN_CONT "scode_tbl "); dump_firm_type(priv->ctrl.scode_table); - printk("(%x), ", priv->ctrl.scode_table); + printk(KERN_CONT "(%x), ", priv->ctrl.scode_table); } else - printk("int_freq %d, ", new_fw.int_freq); - printk("scode_nr %d\n", new_fw.scode_nr); + printk(KERN_CONT "int_freq %d, ", new_fw.int_freq); + printk(KERN_CONT "scode_nr %d\n", new_fw.scode_nr); } /* -- cgit v1.2.3 From 2af3eb647e9b90f679265a45a8fbb78048ba8889 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 06:59:16 -0300 Subject: [media] tuner-xc2028: don't break long lines Due to the 80-cols checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. So, join those continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tuner-xc2028.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 55f6c858b9c3..e07c5fb59cc6 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -56,8 +56,7 @@ MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" static char audio_std[8]; module_param_string(audio_std, audio_std, sizeof(audio_std), 0); MODULE_PARM_DESC(audio_std, - "Audio standard. XC3028 audio decoder explicitly " - "needs to know what audio\n" + "Audio standard. XC3028 audio decoder explicitly needs to know what audio\n" "standard is needed for some video standards with audio A2 or NICAM.\n" "The valid values are:\n" "A2\n" @@ -69,8 +68,8 @@ MODULE_PARM_DESC(audio_std, static char firmware_name[30]; module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); -MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " - "default firmware name\n"); +MODULE_PARM_DESC(firmware_name, + "Firmware file name. Allows overriding the default firmware name\n"); static LIST_HEAD(hybrid_tuner_instance_list); static DEFINE_MUTEX(xc2028_list_mutex); @@ -346,8 +345,7 @@ static int load_all_firmwares(struct dvb_frontend *fe, n++; if (n >= n_array) { - tuner_err("More firmware images in file than " - "were expected!\n"); + tuner_err("More firmware images in file than were expected!\n"); goto corrupt; } @@ -496,8 +494,8 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, } if (best_nr_matches > 0) { - tuner_dbg("Selecting best matching firmware (%d bits) for " - "type=", best_nr_matches); + tuner_dbg("Selecting best matching firmware (%d bits) for type=", + best_nr_matches); dump_firm_type(type); printk(KERN_CONT "(%x), id %016llx:\n", type, (unsigned long long)*id); @@ -840,8 +838,7 @@ check_device: goto fail; } - tuner_dbg("Device is Xceive %d version %d.%d, " - "firmware version %d.%d\n", + tuner_dbg("Device is Xceive %d version %d.%d, firmware version %d.%d\n", hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, (version & 0xf0) >> 4, version & 0xf); @@ -855,8 +852,7 @@ check_device: tuner_err("Incorrect readback of firmware version.\n"); goto fail; } else { - tuner_err("Returned an incorrect version. However, " - "read is not reliable enough. Ignoring it.\n"); + tuner_err("Returned an incorrect version. However, read is not reliable enough. Ignoring it.\n"); hwmodel = 3028; } } @@ -867,8 +863,7 @@ check_device: priv->hwvers = version & 0xff00; } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel || priv->hwvers != (version & 0xff00)) { - tuner_err("Read invalid device hardware information - tuner " - "hung?\n"); + tuner_err("Read invalid device hardware information - tuner hung?\n"); goto fail; } -- cgit v1.2.3 From 5ccb197de29269ba854066c4f1a92eb71974e126 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 07:05:48 -0300 Subject: [media] em28xx: don't break long lines Due to the 80-cols checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. So, join those continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 10 +++---- drivers/media/usb/em28xx/em28xx-cards.c | 51 ++++++++++++--------------------- drivers/media/usb/em28xx/em28xx-core.c | 11 ++++--- drivers/media/usb/em28xx/em28xx-dvb.c | 6 ++-- drivers/media/usb/em28xx/em28xx-input.c | 3 +- drivers/media/usb/em28xx/em28xx-video.c | 6 ++-- 6 files changed, 33 insertions(+), 54 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index e11fe46a547c..2a3975b1aea5 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -3,7 +3,7 @@ * * Copyright (C) 2006 Markus Rechberger * - * Copyright (C) 2007-2014 Mauro Carvalho Chehab + * Copyright (C) 2007-2016 Mauro Carvalho Chehab * - Port to work with the in-kernel driver * - Cleanups, fixes, alsa-controls, etc. * @@ -254,8 +254,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) int nonblock, ret = 0; if (!dev) { - em28xx_err("BUG: em28xx can't find device struct." - " Can't proceed with open\n"); + em28xx_err("BUG: em28xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -902,10 +901,9 @@ static int em28xx_audio_init(struct em28xx *dev) kref_get(&dev->ref); - printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " - "Rechberger\n"); + printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); printk(KERN_INFO - "em28xx-audio.c: Copyright (C) 2007-2014 Mauro Carvalho Chehab\n"); + "em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Em28xx Audio", THIS_MODULE, 0, &card); diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index e397f544f108..bed41c1b4817 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2832,13 +2832,10 @@ static int em28xx_hint_board(struct em28xx *dev) dev->tuner_type = em28xx_eeprom_hash[i].tuner; em28xx_errdev("Your board has no unique USB ID.\n"); - em28xx_errdev("A hint were successfully done, " - "based on eeprom hash.\n"); + em28xx_errdev("A hint were successfully done, based on eeprom hash.\n"); em28xx_errdev("This method is not 100%% failproof.\n"); - em28xx_errdev("If the board were missdetected, " - "please email this log to:\n"); - em28xx_errdev("\tV4L Mailing List " - " \n"); + em28xx_errdev("If the board were missdetected, please email this log to:\n"); + em28xx_errdev("\tV4L Mailing List \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -2864,13 +2861,10 @@ static int em28xx_hint_board(struct em28xx *dev) dev->model = em28xx_i2c_hash[i].model; dev->tuner_type = em28xx_i2c_hash[i].tuner; em28xx_errdev("Your board has no unique USB ID.\n"); - em28xx_errdev("A hint were successfully done, " - "based on i2c devicelist hash.\n"); + em28xx_errdev("A hint were successfully done, based on i2c devicelist hash.\n"); em28xx_errdev("This method is not 100%% failproof.\n"); - em28xx_errdev("If the board were missdetected, " - "please email this log to:\n"); - em28xx_errdev("\tV4L Mailing List " - " \n"); + em28xx_errdev("If the board were missdetected, please email this log to:\n"); + em28xx_errdev("\tV4L Mailing List \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -2878,17 +2872,14 @@ static int em28xx_hint_board(struct em28xx *dev) } } - em28xx_errdev("Your board has no unique USB ID and thus need a " - "hint to be detected.\n"); - em28xx_errdev("You may try to use card= insmod option to " - "workaround that.\n"); + em28xx_errdev("Your board has no unique USB ID and thus need a hint to be detected.\n"); + em28xx_errdev("You may try to use card= insmod option to workaround that.\n"); em28xx_errdev("Please send an email with this log to:\n"); em28xx_errdev("\tV4L Mailing List \n"); em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); - em28xx_errdev("Here is a list of valid choices for the card=" - " insmod option:\n"); + em28xx_errdev("Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { em28xx_errdev(" card=%d -> %s\n", i, em28xx_boards[i].name); @@ -3035,11 +3026,9 @@ static void em28xx_card_setup(struct em28xx *dev) if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { em28xx_errdev("\n\n"); - em28xx_errdev("The support for this board weren't " - "valid yet.\n"); + em28xx_errdev("The support for this board weren't valid yet.\n"); em28xx_errdev("Please send a report of having this working\n"); - em28xx_errdev("not to V4L mailing list (and/or to other " - "addresses)\n\n"); + em28xx_errdev("not to V4L mailing list (and/or to other addresses)\n\n"); } /* Free eeprom data memory */ @@ -3360,8 +3349,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, /* Resets I2C speed */ retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); if (retval < 0) { - em28xx_errdev("%s: em28xx_write_reg failed!" - " retval [%d]\n", + em28xx_errdev("%s: em28xx_write_reg failed! retval [%d]\n", __func__, retval); return retval; } @@ -3429,7 +3417,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ - printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", + printk(DRIVER_NAME + ": Supports only %i em28xx boards.\n", EM28XX_MAXBOARDS); retval = -ENOMEM; goto err_no_slot; @@ -3438,8 +3427,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - em28xx_err(DRIVER_NAME " audio device (%04x:%04x): " - "interface %i, class %i\n", + em28xx_err(DRIVER_NAME + " audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), ifnum, @@ -3502,7 +3491,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, has_vendor_audio = true; } else { printk(KERN_INFO DRIVER_NAME - ": error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); + ": error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); } break; case 0x84: @@ -3576,8 +3565,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, } printk(KERN_INFO DRIVER_NAME - ": New device %s %s @ %s Mbps " - "(%04x:%04x, interface %d, class %d)\n", + ": New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", speed, @@ -3593,8 +3581,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, */ if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { printk(DRIVER_NAME ": Device initialization failed.\n"); - printk(DRIVER_NAME ": Device must be connected to a high-speed" - " USB 2.0 port.\n"); + printk(DRIVER_NAME ": Device must be connected to a high-speed USB 2.0 port.\n"); retval = -ENODEV; goto err_free; } diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index eebd5d7088d0..a73e853e876e 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -87,8 +87,8 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, return -EINVAL; if (reg_debug) { - printk(KERN_DEBUG "(pipe 0x%08x): " - "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", + printk(KERN_DEBUG + "(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x ", pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, req, 0, 0, @@ -165,8 +165,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if (reg_debug) { int byte; - printk(KERN_DEBUG "(pipe 0x%08x): " - "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", + printk(KERN_DEBUG + "(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", pipe, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, req, 0, 0, @@ -942,8 +942,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { - em28xx_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", + em28xx_err("unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); em28xx_uninit_usb_xfer(dev, mode); diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 8cedef0daae4..488c70e5ebde 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -934,8 +934,7 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) cfg.ctrl = &ctl; if (!dev->dvb->fe[0]) { - em28xx_errdev("/2: dvb frontend not attached. " - "Can't attach xc3028\n"); + em28xx_errdev("/2: dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } @@ -1937,8 +1936,7 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; default: - em28xx_errdev("/2: The frontend of your DVB/ATSC card" - " isn't supported yet\n"); + em28xx_errdev("/2: The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 4007356d991d..580f3853505d 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -703,8 +703,7 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { /* No remote control support */ - em28xx_warn("Remote control support is not available for " - "this card.\n"); + em28xx_warn("Remote control support is not available for this card.\n"); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 1f7fa059eb34..119877bb8a1e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -505,8 +505,7 @@ static void em28xx_copy_video(struct em28xx *dev, if ((char *)startwrite + lencopy > (char *)buf->vb_buf + buf->length) { - em28xx_isocdbg("Overflow of %zu bytes past buffer end" - "(2)\n", + em28xx_isocdbg("Overflow of %zu bytes past buffer end(2)\n", ((char *)startwrite + lencopy) - ((char *)buf->vb_buf + buf->length)); lencopy = remain = (char *)buf->vb_buf + buf->length - @@ -2204,8 +2203,7 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_videodbg("setting alternate 0\n"); errCode = usb_set_interface(dev->udev, 0, 0); if (errCode < 0) { - em28xx_errdev("cannot change alternate number to " - "0 (error=%i)\n", errCode); + em28xx_errdev("cannot change alternate number to 0 (error=%i)\n", errCode); } } -- cgit v1.2.3 From 3e7974169a826fe20381302bddd7d531b30646ef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 07:10:10 -0300 Subject: [media] em28xx: mark printk continuation lines as such This driver has a lot of printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index a73e853e876e..06bee2d67273 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -102,7 +102,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, 0x0000, reg, dev->urb_buf, len, HZ); if (ret < 0) { if (reg_debug) - printk(" failed!\n"); + printk(KERN_CONT " failed!\n"); mutex_unlock(&dev->ctrl_urb_lock); return usb_translate_errors(ret); } @@ -115,10 +115,10 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (reg_debug) { int byte; - printk("<<<"); + printk(KERN_CONT "<<<"); for (byte = 0; byte < len; byte++) - printk(" %02x", (unsigned char)buf[byte]); - printk("\n"); + printk(KERN_CONT " %02x", (unsigned char)buf[byte]); + printk(KERN_CONT "\n"); } return ret; @@ -174,8 +174,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, len & 0xff, len >> 8); for (byte = 0; byte < len; byte++) - printk(" %02x", (unsigned char)buf[byte]); - printk("\n"); + printk(KERN_CONT " %02x", (unsigned char)buf[byte]); + printk(KERN_CONT "\n"); } mutex_lock(&dev->ctrl_urb_lock); -- cgit v1.2.3 From 8314d40233f3790e4cfa704087bb2a43c18144d7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 07:26:47 -0300 Subject: [media] em28xx: use pr_foo instead of em28xx-specific printk macros There's no reason to keep using em28xx-specific printk macros here. Just use pr_foo(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 31 ++++----- drivers/media/usb/em28xx/em28xx-camera.c | 34 +++++----- drivers/media/usb/em28xx/em28xx-cards.c | 77 +++++++++++----------- drivers/media/usb/em28xx/em28xx-core.c | 51 +++++++-------- drivers/media/usb/em28xx/em28xx-dvb.c | 42 ++++++------ drivers/media/usb/em28xx/em28xx-i2c.c | 109 ++++++++++++++++--------------- drivers/media/usb/em28xx/em28xx-input.c | 26 ++++---- drivers/media/usb/em28xx/em28xx-video.c | 57 ++++++++-------- drivers/media/usb/em28xx/em28xx.h | 18 +---- 9 files changed, 215 insertions(+), 230 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 2a3975b1aea5..b5f35a25d870 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -25,6 +25,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include @@ -44,7 +46,6 @@ #include #include #include -#include "em28xx.h" static int debug; module_param(debug, int, 0644); @@ -164,7 +165,7 @@ static void em28xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) - em28xx_errdev("resubmit of audio urb failed (error=%i)\n", + pr_err("resubmit of audio urb failed (error=%i)\n", status); return; } @@ -182,7 +183,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - em28xx_errdev("submit of audio urb failed (error=%i)\n", + pr_err("submit of audio urb failed (error=%i)\n", errCode); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); @@ -254,7 +255,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) int nonblock, ret = 0; if (!dev) { - em28xx_err("BUG: em28xx can't find device struct. Can't proceed with open\n"); + pr_err("BUG: em28xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -317,7 +318,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) err: mutex_unlock(&dev->lock); - em28xx_err("Error while configuring em28xx mixer\n"); + pr_err("Error while configuring em28xx mixer\n"); return ret; } @@ -755,7 +756,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) intf = usb_ifnum_to_if(dev->udev, dev->ifnum); if (intf->num_altsetting <= alt) { - em28xx_errdev("alt %d doesn't exist on interface %d\n", + pr_err("alt %d doesn't exist on interface %d\n", dev->ifnum, alt); return -ENODEV; } @@ -771,14 +772,14 @@ static int em28xx_audio_urb_init(struct em28xx *dev) } if (!ep) { - em28xx_errdev("Couldn't find an audio endpoint"); + pr_err("Couldn't find an audio endpoint"); return -ENODEV; } ep_size = em28xx_audio_ep_packet_size(dev->udev, ep); interval = 1 << (ep->bInterval - 1); - em28xx_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", + pr_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), dev->ifnum, alt, interval, @@ -819,7 +820,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) if (urb_size > ep_size * npackets) npackets = DIV_ROUND_UP(urb_size, ep_size); - em28xx_info("Number of URBs: %d, with %d packets and %d size\n", + pr_info("Number of URBs: %d, with %d packets and %d size\n", num_urb, npackets, urb_size); /* Estimate the bytes per period */ @@ -857,7 +858,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - em28xx_errdev("usb_alloc_coherent failed!\n"); + pr_err("usb_alloc_coherent failed!\n"); em28xx_audio_free_urb(dev); return -ENOMEM; } @@ -897,7 +898,7 @@ static int em28xx_audio_init(struct em28xx *dev) return 0; } - em28xx_info("Binding audio extension\n"); + pr_info("Binding audio extension\n"); kref_get(&dev->ref); @@ -953,7 +954,7 @@ static int em28xx_audio_init(struct em28xx *dev) if (err < 0) goto urb_free; - em28xx_info("Audio extension successfully initialized\n"); + pr_info("Audio extension successfully initialized\n"); return 0; urb_free: @@ -978,7 +979,7 @@ static int em28xx_audio_fini(struct em28xx *dev) return 0; } - em28xx_info("Closing audio extension\n"); + pr_info("Closing audio extension\n"); if (dev->adev.sndcard) { snd_card_disconnect(dev->adev.sndcard); @@ -1002,7 +1003,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - em28xx_info("Suspending audio extension\n"); + pr_info("Suspending audio extension\n"); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); return 0; @@ -1016,7 +1017,7 @@ static int em28xx_audio_resume(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - em28xx_info("Resuming audio extension\n"); + pr_info("Resuming audio extension\n"); /* Nothing to do other than schedule_work() ?? */ schedule_work(&dev->adev.wq_trigger); return 0; diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 72f3f4d50253..bc07166e7df0 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -19,14 +19,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include #include #include -#include "em28xx.h" - /* Possible i2c addresses of Micron sensors */ static unsigned short micron_sensor_addrs[] = { 0xb8 >> 1, /* MT9V111, MT9V403 */ @@ -120,13 +120,13 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) ret = i2c_master_send(&client, ®, 1); if (ret < 0) { if (ret != -ENXIO) - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -135,13 +135,13 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) reg = 0xff; ret = i2c_master_send(&client, ®, 1); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -180,15 +180,15 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_MT9M001; break; default: - em28xx_info("unknown Micron sensor detected: 0x%04x\n", + pr_info("unknown Micron sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - em28xx_info("unsupported sensor detected: %s\n", name); + pr_info("unsupported sensor detected: %s\n", name); else - em28xx_info("sensor %s detected\n", name); + pr_info("sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; return 0; @@ -218,7 +218,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { if (ret != -ENXIO) - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -226,7 +226,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x1d; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -238,7 +238,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x0a; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -246,7 +246,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x0b; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", + pr_err("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } @@ -285,15 +285,15 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) name = "OV9655"; break; default: - em28xx_info("unknown OmniVision sensor detected: 0x%04x\n", + pr_info("unknown OmniVision sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - em28xx_info("unsupported sensor detected: %s\n", name); + pr_info("unsupported sensor detected: %s\n", name); else - em28xx_info("sensor %s detected\n", name); + pr_info("sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; return 0; @@ -317,7 +317,7 @@ int em28xx_detect_sensor(struct em28xx *dev) */ if (dev->em28xx_sensor == EM28XX_NOSENSOR && ret < 0) { - em28xx_info("No sensor detected\n"); + pr_info("No sensor detected\n"); return -ENODEV; } diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index bed41c1b4817..c73cf2012bf5 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -23,6 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include @@ -39,7 +41,6 @@ #include #include -#include "em28xx.h" #define DRIVER_NAME "em28xx" @@ -2677,7 +2678,7 @@ static int em28xx_wait_until_ac97_features_equals(struct em28xx *dev, msleep(50); } - em28xx_warn("AC97 registers access is not reliable !\n"); + pr_warn("AC97 registers access is not reliable !\n"); return -ETIMEDOUT; } @@ -2831,12 +2832,12 @@ static int em28xx_hint_board(struct em28xx *dev) dev->model = em28xx_eeprom_hash[i].model; dev->tuner_type = em28xx_eeprom_hash[i].tuner; - em28xx_errdev("Your board has no unique USB ID.\n"); - em28xx_errdev("A hint were successfully done, based on eeprom hash.\n"); - em28xx_errdev("This method is not 100%% failproof.\n"); - em28xx_errdev("If the board were missdetected, please email this log to:\n"); - em28xx_errdev("\tV4L Mailing List \n"); - em28xx_errdev("Board detected as %s\n", + pr_err("Your board has no unique USB ID.\n"); + pr_err("A hint were successfully done, based on eeprom hash.\n"); + pr_err("This method is not 100%% failproof.\n"); + pr_err("If the board were missdetected, please email this log to:\n"); + pr_err("\tV4L Mailing List \n"); + pr_err("Board detected as %s\n", em28xx_boards[dev->model].name); return 0; @@ -2860,28 +2861,28 @@ static int em28xx_hint_board(struct em28xx *dev) if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { dev->model = em28xx_i2c_hash[i].model; dev->tuner_type = em28xx_i2c_hash[i].tuner; - em28xx_errdev("Your board has no unique USB ID.\n"); - em28xx_errdev("A hint were successfully done, based on i2c devicelist hash.\n"); - em28xx_errdev("This method is not 100%% failproof.\n"); - em28xx_errdev("If the board were missdetected, please email this log to:\n"); - em28xx_errdev("\tV4L Mailing List \n"); - em28xx_errdev("Board detected as %s\n", + pr_err("Your board has no unique USB ID.\n"); + pr_err("A hint were successfully done, based on i2c devicelist hash.\n"); + pr_err("This method is not 100%% failproof.\n"); + pr_err("If the board were missdetected, please email this log to:\n"); + pr_err("\tV4L Mailing List \n"); + pr_err("Board detected as %s\n", em28xx_boards[dev->model].name); return 0; } } - em28xx_errdev("Your board has no unique USB ID and thus need a hint to be detected.\n"); - em28xx_errdev("You may try to use card= insmod option to workaround that.\n"); - em28xx_errdev("Please send an email with this log to:\n"); - em28xx_errdev("\tV4L Mailing List \n"); - em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); - em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); + pr_err("Your board has no unique USB ID and thus need a hint to be detected.\n"); + pr_err("You may try to use card= insmod option to workaround that.\n"); + pr_err("Please send an email with this log to:\n"); + pr_err("\tV4L Mailing List \n"); + pr_err("Board eeprom hash is 0x%08lx\n", dev->hash); + pr_err("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); - em28xx_errdev("Here is a list of valid choices for the card= insmod option:\n"); + pr_err("Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { - em28xx_errdev(" card=%d -> %s\n", + pr_err(" card=%d -> %s\n", i, em28xx_boards[i].name); } return -1; @@ -2916,7 +2917,7 @@ static void em28xx_card_setup(struct em28xx *dev) * hash identities which has not been determined as yet. */ if (em28xx_hint_board(dev) < 0) - em28xx_errdev("Board not discovered\n"); + pr_err("Board not discovered\n"); else { em28xx_set_model(dev); em28xx_pre_card_setup(dev); @@ -2926,7 +2927,7 @@ static void em28xx_card_setup(struct em28xx *dev) em28xx_set_model(dev); } - em28xx_info("Identified as %s (card=%d)\n", + pr_info("Identified as %s (card=%d)\n", dev->board.name, dev->model); dev->tuner_type = em28xx_boards[dev->model].tuner_type; @@ -3025,10 +3026,10 @@ static void em28xx_card_setup(struct em28xx *dev) } if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { - em28xx_errdev("\n\n"); - em28xx_errdev("The support for this board weren't valid yet.\n"); - em28xx_errdev("Please send a report of having this working\n"); - em28xx_errdev("not to V4L mailing list (and/or to other addresses)\n\n"); + pr_err("\n\n"); + pr_err("The support for this board weren't valid yet.\n"); + pr_err("Please send a report of having this working\n"); + pr_err("not to V4L mailing list (and/or to other addresses)\n\n"); } /* Free eeprom data memory */ @@ -3211,7 +3212,7 @@ void em28xx_free_device(struct kref *ref) { struct em28xx *dev = kref_to_dev(ref); - em28xx_info("Freeing device\n"); + pr_info("Freeing device\n"); if (!dev->disconnected) em28xx_release_resources(dev); @@ -3349,7 +3350,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, /* Resets I2C speed */ retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); if (retval < 0) { - em28xx_errdev("%s: em28xx_write_reg failed! retval [%d]\n", + pr_err("%s: em28xx_write_reg failed! retval [%d]\n", __func__, retval); return retval; } @@ -3363,7 +3364,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, else retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n", + pr_err("%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); return retval; } @@ -3377,7 +3378,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_i2c_register(dev, 1, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n", + pr_err("%s: em28xx_i2c_register bus 1 - error [%d]!\n", __func__, retval); em28xx_i2c_unregister(dev, 0); @@ -3427,7 +3428,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - em28xx_err(DRIVER_NAME + pr_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), @@ -3441,7 +3442,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - em28xx_err(DRIVER_NAME ": out of memory!\n"); retval = -ENOMEM; goto err; } @@ -3451,7 +3451,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, kmalloc(sizeof(dev->alt_max_pkt_size_isoc[0]) * interface->num_altsetting, GFP_KERNEL); if (dev->alt_max_pkt_size_isoc == NULL) { - em28xx_errdev("out of memory!\n"); kfree(dev); retval = -ENOMEM; goto err; @@ -3604,7 +3603,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) - em28xx_err("em28xx: device seems to have vendor AND usb audio class interfaces !\n" + pr_err("em28xx: device seems to have vendor AND usb audio class interfaces !\n" "\t\tThe vendor interface will be ignored. Please contact the developers \n"); dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; break; @@ -3661,13 +3660,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (has_video) { if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) dev->analog_xfer_bulk = 1; - em28xx_info("analog set to %s mode.\n", + pr_info("analog set to %s mode.\n", dev->analog_xfer_bulk ? "bulk" : "isoc"); } if (has_dvb) { if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) dev->dvb_xfer_bulk = 1; - em28xx_info("dvb set to %s mode.\n", + pr_info("dvb set to %s mode.\n", dev->dvb_xfer_bulk ? "bulk" : "isoc"); } @@ -3715,7 +3714,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) dev->disconnected = 1; - em28xx_info("Disconnecting %s\n", dev->name); + pr_info("Disconnecting %s\n", dev->name); flush_request_modules(dev); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 06bee2d67273..8897cde9894b 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -22,6 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include @@ -32,8 +34,6 @@ #include #include -#include "em28xx.h" - #define DRIVER_AUTHOR "Ludovico Cavedon , " \ "Markus Rechberger , " \ "Mauro Carvalho Chehab , " \ @@ -267,7 +267,7 @@ static int em28xx_is_ac97_ready(struct em28xx *dev) msleep(5); } - em28xx_warn("AC97 command still being executed: not handled properly!\n"); + pr_warn("AC97 command still being executed: not handled properly!\n"); return -EBUSY; } @@ -360,7 +360,7 @@ static int set_ac97_input(struct em28xx *dev) ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); if (ret < 0) - em28xx_warn("couldn't setup AC97 register %d\n", + pr_warn("couldn't setup AC97 register %d\n", inputs[i].reg); } return 0; @@ -444,7 +444,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) for (i = 0; i < ARRAY_SIZE(outputs); i++) { ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); if (ret < 0) - em28xx_warn("couldn't setup AC97 register %d\n", + pr_warn("couldn't setup AC97 register %d\n", outputs[i].reg); } } @@ -482,7 +482,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_write_ac97(dev, outputs[i].reg, vol); if (ret < 0) - em28xx_warn("couldn't setup AC97 register %d\n", + pr_warn("couldn't setup AC97 register %d\n", outputs[i].reg); } @@ -519,7 +519,7 @@ int em28xx_audio_setup(struct em28xx *dev) /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); - em28xx_info("Config register raw data: 0x%02x\n", cfg); + pr_info("Config register raw data: 0x%02x\n", cfg); if (cfg < 0) { /* Register read error */ /* Be conservative */ dev->int_audio_type = EM28XX_INT_AUDIO_AC97; @@ -540,7 +540,7 @@ int em28xx_audio_setup(struct em28xx *dev) i2s_samplerates = 5; else i2s_samplerates = 3; - em28xx_info("I2S Audio (%d sample rate(s))\n", + pr_info("I2S Audio (%d sample rate(s))\n", i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; @@ -558,7 +558,7 @@ int em28xx_audio_setup(struct em28xx *dev) * Note: (some) em2800 devices without eeprom reports 0x91 on * CHIPCFG register, even not having an AC97 chip */ - em28xx_warn("AC97 chip type couldn't be determined\n"); + pr_warn("AC97 chip type couldn't be determined\n"); dev->audio_mode.ac97 = EM28XX_NO_AC97; if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR) dev->usb_audio_type = EM28XX_USB_AUDIO_NONE; @@ -571,13 +571,13 @@ int em28xx_audio_setup(struct em28xx *dev) goto init_audio; vid = vid1 << 16 | vid2; - em28xx_warn("AC97 vendor ID = 0x%08x\n", vid); + pr_warn("AC97 vendor ID = 0x%08x\n", vid); feat = em28xx_read_ac97(dev, AC97_RESET); if (feat < 0) goto init_audio; - em28xx_warn("AC97 features = 0x%04x\n", feat); + pr_warn("AC97 features = 0x%04x\n", feat); /* Try to identify what audio processor we have */ if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) @@ -589,17 +589,17 @@ init_audio: /* Reports detected AC97 processor */ switch (dev->audio_mode.ac97) { case EM28XX_NO_AC97: - em28xx_info("No AC97 audio processor\n"); + pr_info("No AC97 audio processor\n"); break; case EM28XX_AC97_EM202: - em28xx_info("Empia 202 AC97 audio processor detected\n"); + pr_info("Empia 202 AC97 audio processor detected\n"); break; case EM28XX_AC97_SIGMATEL: - em28xx_info("Sigmatel audio processor detected (stac 97%02x)\n", + pr_info("Sigmatel audio processor detected (stac 97%02x)\n", vid & 0xff); break; case EM28XX_AC97_OTHER: - em28xx_warn("Unknown AC97 audio processor detected!\n"); + pr_warn("Unknown AC97 audio processor detected!\n"); break; default: break; @@ -883,7 +883,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if (mode == EM28XX_DIGITAL_MODE) { if ((xfer_bulk && !dev->dvb_ep_bulk) || (!xfer_bulk && !dev->dvb_ep_isoc)) { - em28xx_errdev("no endpoint for DVB mode and transfer type %d\n", + pr_err("no endpoint for DVB mode and transfer type %d\n", xfer_bulk > 0); return -EINVAL; } @@ -891,13 +891,13 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, } else if (mode == EM28XX_ANALOG_MODE) { if ((xfer_bulk && !dev->analog_ep_bulk) || (!xfer_bulk && !dev->analog_ep_isoc)) { - em28xx_errdev("no endpoint for analog mode and transfer type %d\n", + pr_err("no endpoint for analog mode and transfer type %d\n", xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.analog_bufs; } else { - em28xx_errdev("invalid mode selected\n"); + pr_err("invalid mode selected\n"); return -EINVAL; } @@ -907,15 +907,12 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->num_bufs = num_bufs; usb_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!usb_bufs->urb) { - em28xx_errdev("cannot alloc memory for usb buffers\n"); + if (!usb_bufs->urb) return -ENOMEM; - } usb_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); if (!usb_bufs->transfer_buffer) { - em28xx_errdev("cannot allocate memory for usb transfer\n"); kfree(usb_bufs->urb); return -ENOMEM; } @@ -942,7 +939,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { - em28xx_err("unable to allocate %i bytes for transfer buffer %i%s\n", + pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); em28xx_uninit_usb_xfer(dev, mode); @@ -1024,7 +1021,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, if (xfer_bulk) { rc = usb_clear_halt(dev->udev, usb_bufs->urb[0]->pipe); if (rc < 0) { - em28xx_err("failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", + pr_err("failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", rc); em28xx_uninit_usb_xfer(dev, mode); return rc; @@ -1040,7 +1037,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, for (i = 0; i < usb_bufs->num_bufs; i++) { rc = usb_submit_urb(usb_bufs->urb[i], GFP_ATOMIC); if (rc) { - em28xx_err("submit of urb %i failed (error=%i)\n", i, + pr_err("submit of urb %i failed (error=%i)\n", i, rc); em28xx_uninit_usb_xfer(dev, mode); return rc; @@ -1123,7 +1120,7 @@ int em28xx_suspend_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - em28xx_info("Suspending extensions\n"); + pr_info("Suspending extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->suspend) @@ -1137,7 +1134,7 @@ int em28xx_resume_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - em28xx_info("Resuming extensions\n"); + pr_info("Resuming extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->resume) diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 488c70e5ebde..cbece65899b5 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -21,11 +21,12 @@ the Free Software Foundation; either version 2 of the License. */ +#include "em28xx.h" + #include #include #include -#include "em28xx.h" #include #include #include @@ -734,7 +735,7 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) ret = gpio_request_one(dvb->lna_gpio, flags, NULL); if (ret) - em28xx_errdev("gpio request failed %d\n", ret); + pr_err("gpio request failed %d\n", ret); else gpio_free(dvb->lna_gpio); @@ -934,19 +935,19 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) cfg.ctrl = &ctl; if (!dev->dvb->fe[0]) { - em28xx_errdev("/2: dvb frontend not attached. Can't attach xc3028\n"); + pr_err("/2: dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); if (!fe) { - em28xx_errdev("/2: xc3028 attach failed\n"); + pr_err("/2: xc3028 attach failed\n"); dvb_frontend_detach(dev->dvb->fe[0]); dev->dvb->fe[0] = NULL; return -EINVAL; } - em28xx_info("%s/2: xc3028 attached\n", dev->name); + pr_info("%s/2: xc3028 attached\n", dev->name); return 0; } @@ -1116,13 +1117,12 @@ static int em28xx_dvb_init(struct em28xx *dev) return 0; } - em28xx_info("Binding DVB extension\n"); + pr_info("Binding DVB extension\n"); dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); - if (dvb == NULL) { - em28xx_info("em28xx_dvb: memory allocation failed\n"); + if (!dvb) return -ENOMEM; - } + dev->dvb = dvb; dvb->fe[0] = dvb->fe[1] = NULL; @@ -1141,7 +1141,7 @@ static int em28xx_dvb_init(struct em28xx *dev) EM28XX_DVB_NUM_ISOC_PACKETS); } if (result) { - em28xx_errdev("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n"); + pr_err("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n"); kfree(dvb); dev->dvb = NULL; return result; @@ -1320,7 +1320,7 @@ static int em28xx_dvb_init(struct em28xx *dev) result = gpio_request_one(dvb->lna_gpio, GPIOF_OUT_INIT_LOW, NULL); if (result) - em28xx_errdev("gpio request failed %d\n", + pr_err("gpio request failed %d\n", result); else gpio_free(dvb->lna_gpio); @@ -1936,11 +1936,11 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; default: - em28xx_errdev("/2: The frontend of your DVB/ATSC card isn't supported yet\n"); + pr_err("/2: The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { - em28xx_errdev("/2: frontend initialization failed\n"); + pr_err("/2: frontend initialization failed\n"); result = -EINVAL; goto out_free; } @@ -1955,7 +1955,7 @@ static int em28xx_dvb_init(struct em28xx *dev) if (result < 0) goto out_free; - em28xx_info("DVB extension successfully initialized\n"); + pr_info("DVB extension successfully initialized\n"); kref_get(&dev->ref); @@ -1995,7 +1995,7 @@ static int em28xx_dvb_fini(struct em28xx *dev) if (!dev->dvb) return 0; - em28xx_info("Closing DVB extension\n"); + pr_info("Closing DVB extension\n"); dvb = dev->dvb; @@ -2053,17 +2053,17 @@ static int em28xx_dvb_suspend(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - em28xx_info("Suspending DVB extension\n"); + pr_info("Suspending DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_suspend(dvb->fe[0]); - em28xx_info("fe0 suspend %d\n", ret); + pr_info("fe0 suspend %d\n", ret); } if (dvb->fe[1]) { dvb_frontend_suspend(dvb->fe[1]); - em28xx_info("fe1 suspend %d\n", ret); + pr_info("fe1 suspend %d\n", ret); } } @@ -2080,18 +2080,18 @@ static int em28xx_dvb_resume(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - em28xx_info("Resuming DVB extension\n"); + pr_info("Resuming DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_resume(dvb->fe[0]); - em28xx_info("fe0 resume %d\n", ret); + pr_info("fe0 resume %d\n", ret); } if (dvb->fe[1]) { ret = dvb_frontend_resume(dvb->fe[1]); - em28xx_info("fe1 resume %d\n", ret); + pr_info("fe1 resume %d\n", ret); } } diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 8b690ac908a4..5185fed9fbf0 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -22,13 +22,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include #include #include -#include "em28xx.h" #include "tuner-xc2028.h" #include #include @@ -70,7 +71,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) /* trigger write */ ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); if (ret != 2 + len) { - em28xx_warn("failed to trigger write to i2c address 0x%x (error=%i)\n", + pr_warn("failed to trigger write to i2c address 0x%x (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; } @@ -81,19 +82,19 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) return len; if (ret == 0x94 + len - 1) { if (i2c_debug == 1) - em28xx_warn("R05 returned 0x%02x: I2C ACK error\n", + pr_warn("R05 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } if (ret < 0) { - em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", + pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; } msleep(5); } if (i2c_debug) - em28xx_warn("write to i2c device at 0x%x timed out\n", addr); + pr_warn("write to i2c device at 0x%x timed out\n", addr); return -ETIMEDOUT; } @@ -116,7 +117,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) buf2[0] = addr; ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); if (ret != 2) { - em28xx_warn("failed to trigger read from i2c address 0x%x (error=%i)\n", + pr_warn("failed to trigger read from i2c address 0x%x (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; } @@ -128,12 +129,12 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) break; if (ret == 0x94 + len - 1) { if (i2c_debug == 1) - em28xx_warn("R05 returned 0x%02x: I2C ACK error\n", + pr_warn("R05 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } if (ret < 0) { - em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", + pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; } @@ -141,14 +142,14 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) } if (ret != 0x84 + len - 1) { if (i2c_debug) - em28xx_warn("read from i2c device at 0x%x timed out\n", + pr_warn("read from i2c device at 0x%x timed out\n", addr); } /* get the received message */ ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); if (ret != len) { - em28xx_warn("reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", + pr_warn("reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; } @@ -193,11 +194,11 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); if (ret != len) { if (ret < 0) { - em28xx_warn("writing to i2c device at 0x%x failed (error=%i)\n", + pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } else { - em28xx_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", len, addr, ret); return -EIO; } @@ -210,12 +211,12 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, return len; if (ret == 0x10) { if (i2c_debug == 1) - em28xx_warn("I2C ACK error on writing to addr 0x%02x\n", + pr_warn("I2C ACK error on writing to addr 0x%02x\n", addr); return -ENXIO; } if (ret < 0) { - em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", + pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; } @@ -230,12 +231,12 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret == 0x02 || ret == 0x04) { /* NOTE: these errors seem to be related to clock stretching */ if (i2c_debug) - em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n", + pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", addr, ret); return -ETIMEDOUT; } - em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", + pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", addr, ret); return -EIO; } @@ -258,7 +259,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) /* Read data from i2c device */ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); if (ret < 0) { - em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", + pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } @@ -276,13 +277,13 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) if (ret == 0) /* success */ return len; if (ret < 0) { - em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", + pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; } if (ret == 0x10) { if (i2c_debug == 1) - em28xx_warn("I2C ACK error on writing to addr 0x%02x\n", + pr_warn("I2C ACK error on writing to addr 0x%02x\n", addr); return -ENXIO; } @@ -290,12 +291,12 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) if (ret == 0x02 || ret == 0x04) { /* NOTE: these errors seem to be related to clock stretching */ if (i2c_debug) - em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n", + pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", addr, ret); return -ETIMEDOUT; } - em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", + pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", addr, ret); return -EIO; } @@ -335,11 +336,11 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len); if (ret != len) { if (ret < 0) { - em28xx_warn("writing to i2c device at 0x%x failed (error=%i)\n", + pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } else { - em28xx_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", len, addr, ret); return -EIO; } @@ -354,7 +355,7 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, return len; else if (ret > 0) { if (i2c_debug == 1) - em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", + pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -386,7 +387,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, /* Read value */ ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); if (ret < 0) { - em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", + pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } @@ -409,7 +410,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, return len; else if (ret > 0) { if (i2c_debug == 1) - em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", + pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -672,7 +673,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); if (err < 0) { - em28xx_info("board has no eeprom\n"); + pr_info("board has no eeprom\n"); return -ENODEV; } @@ -685,7 +686,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->eeprom_addrwidth_16bit, len, data); if (err != len) { - em28xx_errdev("failed to read eeprom (err=%d)\n", err); + pr_err("failed to read eeprom (err=%d)\n", err); goto error; } @@ -695,7 +696,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, 16, 1, data, len, true); if (dev->eeprom_addrwidth_16bit) - em28xx_info("eeprom %06x: ... (skipped)\n", 256); + pr_info("eeprom %06x: ... (skipped)\n", 256); } if (dev->eeprom_addrwidth_16bit && @@ -707,10 +708,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->hash = em28xx_hash_mem(data, len, 32); mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ - em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", + pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", data[0], data[1], data[2], data[3], dev->hash); - em28xx_info("EEPROM info:\n"); - em28xx_info("\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", + pr_info("EEPROM info:\n"); + pr_info("\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", mc_start, data[2]); /* * boot configuration (address 0x0002): @@ -729,7 +730,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, data); if (err != 2) { - em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", + pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", err); goto error; } @@ -747,7 +748,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, data); if (err != len) { - em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", + pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", err); goto error; } @@ -756,7 +757,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* NOTE: not all devices provide this type of dataset */ if (data[0] != 0x1a || data[1] != 0xeb || data[2] != 0x67 || data[3] != 0x95) { - em28xx_info("\tno hardware configuration dataset found in eeprom\n"); + pr_info("\tno hardware configuration dataset found in eeprom\n"); kfree(data); return 0; } @@ -767,11 +768,11 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data[0] == 0x1a && data[1] == 0xeb && data[2] == 0x67 && data[3] == 0x95) { dev->hash = em28xx_hash_mem(data, len, 32); - em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", + pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", data[0], data[1], data[2], data[3], dev->hash); - em28xx_info("EEPROM info:\n"); + pr_info("EEPROM info:\n"); } else { - em28xx_info("unknown eeprom format or eeprom corrupted !\n"); + pr_info("unknown eeprom format or eeprom corrupted !\n"); err = -ENODEV; goto error; } @@ -782,46 +783,46 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { case 0: - em28xx_info("\tNo audio on board.\n"); + pr_info("\tNo audio on board.\n"); break; case 1: - em28xx_info("\tAC97 audio (5 sample rates)\n"); + pr_info("\tAC97 audio (5 sample rates)\n"); break; case 2: if (dev->chip_id < CHIP_ID_EM2860) - em28xx_info("\tI2S audio, sample rate=32k\n"); + pr_info("\tI2S audio, sample rate=32k\n"); else - em28xx_info("\tI2S audio, 3 sample rates\n"); + pr_info("\tI2S audio, 3 sample rates\n"); break; case 3: if (dev->chip_id < CHIP_ID_EM2860) - em28xx_info("\tI2S audio, 3 sample rates\n"); + pr_info("\tI2S audio, 3 sample rates\n"); else - em28xx_info("\tI2S audio, 5 sample rates\n"); + pr_info("\tI2S audio, 5 sample rates\n"); break; } if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) - em28xx_info("\tUSB Remote wakeup capable\n"); + pr_info("\tUSB Remote wakeup capable\n"); if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) - em28xx_info("\tUSB Self power capable\n"); + pr_info("\tUSB Self power capable\n"); switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { case 0: - em28xx_info("\t500mA max power\n"); + pr_info("\t500mA max power\n"); break; case 1: - em28xx_info("\t400mA max power\n"); + pr_info("\t400mA max power\n"); break; case 2: - em28xx_info("\t300mA max power\n"); + pr_info("\t300mA max power\n"); break; case 3: - em28xx_info("\t200mA max power\n"); + pr_info("\t200mA max power\n"); break; } - em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", + pr_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", dev_config->string_idx_table, le16_to_cpu(dev_config->string1), le16_to_cpu(dev_config->string2), @@ -914,7 +915,7 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) if (rc < 0) continue; i2c_devicelist[i] = i; - em28xx_info("found i2c device @ 0x%x on bus %d [%s]\n", + pr_info("found i2c device @ 0x%x on bus %d [%s]\n", i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); } @@ -949,7 +950,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { - em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", + pr_err("%s: i2c_add_adapter failed! retval [%d]\n", __func__, retval); return retval; } @@ -961,7 +962,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, if (!bus) { retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { - em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", + pr_err("%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); return retval; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 580f3853505d..e8e1f768d45e 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "em28xx.h" + #include #include #include @@ -29,8 +31,6 @@ #include #include -#include "em28xx.h" - #define EM28XX_SNAPSHOT_KEY KEY_CAMERA #define EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL 500 /* [ms] */ #define EM28XX_BUTTONS_VOLATILE_QUERY_INTERVAL 100 /* [ms] */ @@ -567,7 +567,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) struct input_dev *input_dev; int err; - em28xx_info("Registering snapshot button...\n"); + pr_info("Registering snapshot button...\n"); input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; @@ -591,7 +591,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) err = input_register_device(input_dev); if (err) { - em28xx_errdev("input_register_device failed\n"); + pr_err("input_register_device failed\n"); input_free_device(input_dev); return err; } @@ -631,7 +631,7 @@ static void em28xx_init_buttons(struct em28xx *dev) } else if (button->role == EM28XX_BUTTON_ILLUMINATION) { /* Check sanity */ if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) { - em28xx_errdev("BUG: illumination button defined, but no illumination LED.\n"); + pr_err("BUG: illumination button defined, but no illumination LED.\n"); goto next_button; } } @@ -667,7 +667,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) dev->num_button_polling_addresses = 0; /* Deregister input devices */ if (dev->sbutton_input_dev != NULL) { - em28xx_info("Deregistering snapshot button\n"); + pr_info("Deregistering snapshot button\n"); input_unregister_device(dev->sbutton_input_dev); dev->sbutton_input_dev = NULL; } @@ -696,18 +696,18 @@ static int em28xx_ir_init(struct em28xx *dev) i2c_rc_dev_addr = em28xx_probe_i2c_ir(dev); if (!i2c_rc_dev_addr) { dev->board.has_ir_i2c = 0; - em28xx_warn("No i2c IR remote control device found.\n"); + pr_warn("No i2c IR remote control device found.\n"); return -ENODEV; } } if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { /* No remote control support */ - em28xx_warn("Remote control support is not available for this card.\n"); + pr_warn("Remote control support is not available for this card.\n"); return 0; } - em28xx_info("Registering input extension\n"); + pr_info("Registering input extension\n"); ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) @@ -810,7 +810,7 @@ static int em28xx_ir_init(struct em28xx *dev) if (err) goto error; - em28xx_info("Input extension successfully initalized\n"); + pr_info("Input extension successfully initalized\n"); return 0; @@ -831,7 +831,7 @@ static int em28xx_ir_fini(struct em28xx *dev) return 0; } - em28xx_info("Closing input extension\n"); + pr_info("Closing input extension\n"); em28xx_shutdown_buttons(dev); @@ -860,7 +860,7 @@ static int em28xx_ir_suspend(struct em28xx *dev) if (dev->is_audio_only) return 0; - em28xx_info("Suspending input extension\n"); + pr_info("Suspending input extension\n"); if (ir) cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&dev->buttons_query_work); @@ -877,7 +877,7 @@ static int em28xx_ir_resume(struct em28xx *dev) if (dev->is_audio_only) return 0; - em28xx_info("Resuming input extension\n"); + pr_info("Resuming input extension\n"); /* if suspend calls ir_raw_event_unregister(), the should call ir_raw_event_register() */ if (ir) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 119877bb8a1e..3efabc19bfe9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "em28xx.h" + #include #include #include @@ -37,7 +39,6 @@ #include #include -#include "em28xx.h" #include "em28xx-v4l.h" #include #include @@ -413,7 +414,7 @@ set_alt: dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); if (errCode < 0) { - em28xx_errdev("cannot change alternate number to %d (error=%i)\n", + pr_err("cannot change alternate number to %d (error=%i)\n", dev->alt, errCode); return errCode; } @@ -2047,7 +2048,7 @@ static int em28xx_v4l2_open(struct file *filp) ret = v4l2_fh_open(filp); if (ret) { - em28xx_errdev("%s: v4l2_fh_open() returned error %d\n", + pr_err("%s: v4l2_fh_open() returned error %d\n", __func__, ret); mutex_unlock(&dev->lock); return ret; @@ -2102,7 +2103,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) if (v4l2 == NULL) return 0; - em28xx_info("Closing video extension\n"); + pr_info("Closing video extension\n"); mutex_lock(&dev->lock); @@ -2113,17 +2114,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) em28xx_v4l2_media_release(dev); if (video_is_registered(&v4l2->radio_dev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } @@ -2153,7 +2154,7 @@ static int em28xx_v4l2_suspend(struct em28xx *dev) if (!dev->has_video) return 0; - em28xx_info("Suspending video extension\n"); + pr_info("Suspending video extension\n"); em28xx_stop_urbs(dev); return 0; } @@ -2166,7 +2167,7 @@ static int em28xx_v4l2_resume(struct em28xx *dev) if (!dev->has_video) return 0; - em28xx_info("Resuming video extension\n"); + pr_info("Resuming video extension\n"); /* what do we do here */ return 0; } @@ -2203,7 +2204,8 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_videodbg("setting alternate 0\n"); errCode = usb_set_interface(dev->udev, 0, 0); if (errCode < 0) { - em28xx_errdev("cannot change alternate number to 0 (error=%i)\n", errCode); + pr_err("cannot change alternate number to 0 (error=%i)\n", + errCode); } } @@ -2420,13 +2422,12 @@ static int em28xx_v4l2_init(struct em28xx *dev) return 0; } - em28xx_info("Registering V4L2 extension\n"); + pr_info("Registering V4L2 extension\n"); mutex_lock(&dev->lock); v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL); - if (v4l2 == NULL) { - em28xx_info("em28xx_v4l: memory allocation failed\n"); + if (!v4l2) { mutex_unlock(&dev->lock); return -ENOMEM; } @@ -2439,7 +2440,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) #endif ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev); if (ret < 0) { - em28xx_errdev("Call to v4l2_device_register() failed!\n"); + pr_err("Call to v4l2_device_register() failed!\n"); goto err; } @@ -2523,7 +2524,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Configure audio */ ret = em28xx_audio_setup(dev); if (ret < 0) { - em28xx_errdev("%s: Error while setting audio - error [%d]!\n", + pr_err("%s: Error while setting audio - error [%d]!\n", __func__, ret); goto unregister_dev; } @@ -2551,7 +2552,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Send a reset to other chips via gpio */ ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); if (ret < 0) { - em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", + pr_err("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", __func__, ret); goto unregister_dev; } @@ -2559,7 +2560,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); if (ret < 0) { - em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", + pr_err("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", __func__, ret); goto unregister_dev; } @@ -2661,7 +2662,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - em28xx_errdev("unable to register video device (error=%i).\n", + pr_err("unable to register video device (error=%i).\n", ret); goto unregister_dev; } @@ -2691,7 +2692,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - em28xx_errdev("unable to register vbi device\n"); + pr_err("unable to register vbi device\n"); goto unregister_dev; } } @@ -2702,10 +2703,10 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - em28xx_errdev("can't register radio device\n"); + pr_err("can't register radio device\n"); goto unregister_dev; } - em28xx_info("Registered radio device as %s\n", + pr_info("Registered radio device as %s\n", video_device_node_name(&v4l2->radio_dev)); } @@ -2715,17 +2716,17 @@ static int em28xx_v4l2_init(struct em28xx *dev) #ifdef CONFIG_MEDIA_CONTROLLER ret = v4l2_mc_create_media_graph(dev->media_dev); if (ret) { - em28xx_errdev("failed to create media graph\n"); + pr_err("failed to create media graph\n"); em28xx_v4l2_media_release(dev); goto unregister_dev; } #endif - em28xx_info("V4L2 video device registered as %s\n", + pr_info("V4L2 video device registered as %s\n", video_device_node_name(&v4l2->vdev)); if (video_is_registered(&v4l2->vbi_dev)) - em28xx_info("V4L2 VBI device registered as %s\n", + pr_info("V4L2 VBI device registered as %s\n", video_device_node_name(&v4l2->vbi_dev)); /* Save some power by putting tuner to sleep */ @@ -2734,7 +2735,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* initialize videobuf2 stuff */ em28xx_vb2_setup(dev); - em28xx_info("V4L2 extension successfully initialized\n"); + pr_info("V4L2 extension successfully initialized\n"); kref_get(&dev->ref); @@ -2743,17 +2744,17 @@ static int em28xx_v4l2_init(struct em28xx *dev) unregister_dev: if (video_is_registered(&v4l2->radio_dev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - em28xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index d148463b22c1..0f6830f5078b 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -29,6 +29,8 @@ #define EM28XX_VERSION "0.2.2" #define DRIVER_DESC "Empia em28xx device driver" +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -797,20 +799,4 @@ void em28xx_free_device(struct kref *ref); int em28xx_detect_sensor(struct em28xx *dev); int em28xx_init_camera(struct em28xx *dev); -/* printk macros */ - -#define em28xx_err(fmt, arg...) do {\ - printk(KERN_ERR fmt , ##arg); } while (0) - -#define em28xx_errdev(fmt, arg...) do {\ - printk(KERN_ERR "%s: "fmt,\ - dev->name , ##arg); } while (0) - -#define em28xx_info(fmt, arg...) do {\ - printk(KERN_INFO "%s: "fmt,\ - dev->name , ##arg); } while (0) -#define em28xx_warn(fmt, arg...) do {\ - printk(KERN_WARNING "%s: "fmt,\ - dev->name , ##arg); } while (0) - #endif -- cgit v1.2.3 From 2a96f60e89b9af8396fe06dc361909b5e3a9b4f0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 07:32:23 -0300 Subject: [media] em28xx: convert the remaining printks to pr_foo There are still several places with printk's called directly. Convert them to pr_foo() macros, except for the debug printk's, as those are enabled via modprobe vars. While here, realign the pr_foo() arguments to match the recommended CodingStyle. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 10 ++--- drivers/media/usb/em28xx/em28xx-camera.c | 21 +++++---- drivers/media/usb/em28xx/em28xx-cards.c | 67 ++++++++++++----------------- drivers/media/usb/em28xx/em28xx-core.c | 47 ++++++++++---------- drivers/media/usb/em28xx/em28xx-dvb.c | 39 ++++++++--------- drivers/media/usb/em28xx/em28xx-i2c.c | 74 ++++++++++++++++---------------- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/em28xx/em28xx-vbi.c | 7 +-- drivers/media/usb/em28xx/em28xx-video.c | 46 +++++++++----------- 9 files changed, 146 insertions(+), 167 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index b5f35a25d870..06e495615296 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -56,9 +56,8 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define dprintk(fmt, arg...) do { \ if (debug) \ - printk(KERN_INFO "em28xx-audio %s: " fmt, \ - __func__, ##arg); \ - } while (0) + printk(KERN_DEBUG pr_fmt("audio: %s: " fmt), \ + __func__, ##arg); } while (0) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; @@ -902,9 +901,8 @@ static int em28xx_audio_init(struct em28xx *dev) kref_get(&dev->ref); - printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); - printk(KERN_INFO - "em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); + pr_info("em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); + pr_info("em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Em28xx Audio", THIS_MODULE, 0, &card); diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index bc07166e7df0..a24695474212 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -121,13 +121,13 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) if (ret < 0) { if (ret != -ENXIO) pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } id = be16_to_cpu(id_be); @@ -136,13 +136,13 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) ret = i2c_master_send(&client, ®, 1); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } /* Validate chip ID to be sure we have a Micron device */ @@ -180,8 +180,7 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_MT9M001; break; default: - pr_info("unknown Micron sensor detected: 0x%04x\n", - id); + pr_info("unknown Micron sensor detected: 0x%04x\n", id); return 0; } @@ -219,7 +218,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) if (ret < 0) { if (ret != -ENXIO) pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } id = ret << 8; @@ -227,7 +226,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } id += ret; @@ -239,7 +238,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } id = ret << 8; @@ -247,7 +246,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client.addr << 1, ret); continue; } id += ret; @@ -286,7 +285,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) break; default: pr_info("unknown OmniVision sensor detected: 0x%04x\n", - id); + id); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index c73cf2012bf5..bcd6ac61d9f8 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2838,7 +2838,7 @@ static int em28xx_hint_board(struct em28xx *dev) pr_err("If the board were missdetected, please email this log to:\n"); pr_err("\tV4L Mailing List \n"); pr_err("Board detected as %s\n", - em28xx_boards[dev->model].name); + em28xx_boards[dev->model].name); return 0; } @@ -2867,7 +2867,7 @@ static int em28xx_hint_board(struct em28xx *dev) pr_err("If the board were missdetected, please email this log to:\n"); pr_err("\tV4L Mailing List \n"); pr_err("Board detected as %s\n", - em28xx_boards[dev->model].name); + em28xx_boards[dev->model].name); return 0; } @@ -2882,8 +2882,7 @@ static int em28xx_hint_board(struct em28xx *dev) pr_err("Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { - pr_err(" card=%d -> %s\n", - i, em28xx_boards[i].name); + pr_err(" card=%d -> %s\n", i, em28xx_boards[i].name); } return -1; } @@ -2928,7 +2927,7 @@ static void em28xx_card_setup(struct em28xx *dev) } pr_info("Identified as %s (card=%d)\n", - dev->board.name, dev->model); + dev->board.name, dev->model); dev->tuner_type = em28xx_boards[dev->model].tuner_type; @@ -3318,14 +3317,12 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, dev->eeprom_addrwidth_16bit = 1; break; default: - printk(KERN_INFO DRIVER_NAME - ": unknown em28xx chip ID (%d)\n", dev->chip_id); + pr_info("unknown em28xx chip ID (%d)\n", dev->chip_id); } } if (chip_name != default_chip_name) - printk(KERN_INFO DRIVER_NAME - ": chip ID is %s\n", chip_name); + pr_info("chip ID is %s\n", chip_name); /* * For em2820/em2710, the name may change latter, after checking @@ -3351,7 +3348,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); if (retval < 0) { pr_err("%s: em28xx_write_reg failed! retval [%d]\n", - __func__, retval); + __func__, retval); return retval; } } @@ -3365,7 +3362,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { pr_err("%s: em28xx_i2c_register bus 0 - error [%d]!\n", - __func__, retval); + __func__, retval); return retval; } @@ -3379,7 +3376,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { pr_err("%s: em28xx_i2c_register bus 1 - error [%d]!\n", - __func__, retval); + __func__, retval); em28xx_i2c_unregister(dev, 0); @@ -3418,8 +3415,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ - printk(DRIVER_NAME - ": Supports only %i em28xx boards.\n", + pr_err("Driver supports up to %i em28xx boards.\n", EM28XX_MAXBOARDS); retval = -ENOMEM; goto err_no_slot; @@ -3428,8 +3424,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - pr_err(DRIVER_NAME - " audio device (%04x:%04x): interface %i, class %i\n", + pr_err("audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), ifnum, @@ -3489,8 +3484,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (usb_endpoint_xfer_isoc(e)) { has_vendor_audio = true; } else { - printk(KERN_INFO DRIVER_NAME - ": error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); + pr_err("error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); } break; case 0x84: @@ -3563,8 +3557,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - printk(KERN_INFO DRIVER_NAME - ": New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", + pr_info("New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", speed, @@ -3579,8 +3572,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, * not enough even for most Digital TV streams. */ if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { - printk(DRIVER_NAME ": Device initialization failed.\n"); - printk(DRIVER_NAME ": Device must be connected to a high-speed USB 2.0 port.\n"); + pr_err("Device initialization failed.\n"); + pr_err("Device must be connected to a high-speed USB 2.0 port.\n"); retval = -ENODEV; goto err_free; } @@ -3593,8 +3586,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev->ifnum = ifnum; if (has_vendor_audio) { - printk(KERN_INFO DRIVER_NAME ": Audio interface %i found %s\n", - ifnum, "(Vendor Class)"); + pr_info("Audio interface %i found (Vendor Class)\n", ifnum); dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; } /* Checks if audio is provided by a USB Audio Class interface */ @@ -3604,24 +3596,22 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) pr_err("em28xx: device seems to have vendor AND usb audio class interfaces !\n" - "\t\tThe vendor interface will be ignored. Please contact the developers \n"); + "\t\tThe vendor interface will be ignored. Please contact the developers \n"); dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; break; } } if (has_video) - printk(KERN_INFO DRIVER_NAME - ": Video interface %i found:%s%s\n", - ifnum, - dev->analog_ep_bulk ? " bulk" : "", - dev->analog_ep_isoc ? " isoc" : ""); + pr_info("Video interface %i found:%s%s\n", + ifnum, + dev->analog_ep_bulk ? " bulk" : "", + dev->analog_ep_isoc ? " isoc" : ""); if (has_dvb) - printk(KERN_INFO DRIVER_NAME - ": DVB interface %i found:%s%s\n", - ifnum, - dev->dvb_ep_bulk ? " bulk" : "", - dev->dvb_ep_isoc ? " isoc" : ""); + pr_info("DVB interface %i found:%s%s\n", + ifnum, + dev->dvb_ep_bulk ? " bulk" : "", + dev->dvb_ep_isoc ? " isoc" : ""); dev->num_alt = interface->num_altsetting; @@ -3650,8 +3640,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Disable V4L2 if the device doesn't have a decoder */ if (has_video && dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) { - printk(DRIVER_NAME - ": Currently, V4L2 is not supported on this model\n"); + pr_err("Currently, V4L2 is not supported on this model\n"); has_video = false; dev->has_video = false; } @@ -3661,13 +3650,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) dev->analog_xfer_bulk = 1; pr_info("analog set to %s mode.\n", - dev->analog_xfer_bulk ? "bulk" : "isoc"); + dev->analog_xfer_bulk ? "bulk" : "isoc"); } if (has_dvb) { if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) dev->dvb_xfer_bulk = 1; pr_info("dvb set to %s mode.\n", - dev->dvb_xfer_bulk ? "bulk" : "isoc"); + dev->dvb_xfer_bulk ? "bulk" : "isoc"); } kref_init(&dev->ref); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 8897cde9894b..a413ff7c30d7 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -48,12 +48,12 @@ MODULE_VERSION(EM28XX_VERSION); static unsigned int core_debug; module_param(core_debug, int, 0644); -MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); +MODULE_PARM_DESC(core_debug, "enable debug messages [core and isoc]"); #define em28xx_coredbg(fmt, arg...) do {\ if (core_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __func__ , ##arg); } while (0) + printk(KERN_DEBUG pr_fmt("core: %s: " fmt), \ + __func__, ##arg); } while (0) static unsigned int reg_debug; module_param(reg_debug, int, 0644); @@ -61,14 +61,14 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); #define em28xx_regdbg(fmt, arg...) do {\ if (reg_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __func__ , ##arg); } while (0) + printk(KERN_DEBUG pr_fmt("reg: %s: " fmt), \ + __func__, ##arg); } while (0) /* FIXME */ #define em28xx_isocdbg(fmt, arg...) do {\ if (core_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __func__ , ##arg); } while (0) + printk(KERN_DEBUG pr_fmt("isoc: %s: " fmt), \ + __func__, ##arg); } while (0) /* * em28xx_read_reg_req() @@ -102,7 +102,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, 0x0000, reg, dev->urb_buf, len, HZ); if (ret < 0) { if (reg_debug) - printk(KERN_CONT " failed!\n"); + pr_cont(" failed!\n"); mutex_unlock(&dev->ctrl_urb_lock); return usb_translate_errors(ret); } @@ -115,10 +115,10 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (reg_debug) { int byte; - printk(KERN_CONT "<<<"); + pr_cont("<<<"); for (byte = 0; byte < len; byte++) - printk(KERN_CONT " %02x", (unsigned char)buf[byte]); - printk(KERN_CONT "\n"); + pr_cont(" %02x", (unsigned char)buf[byte]); + pr_cont("\n"); } return ret; @@ -174,8 +174,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, len & 0xff, len >> 8); for (byte = 0; byte < len; byte++) - printk(KERN_CONT " %02x", (unsigned char)buf[byte]); - printk(KERN_CONT "\n"); + pr_cont(" %02x", (unsigned char)buf[byte]); + pr_cont("\n"); } mutex_lock(&dev->ctrl_urb_lock); @@ -541,7 +541,7 @@ int em28xx_audio_setup(struct em28xx *dev) else i2s_samplerates = 3; pr_info("I2S Audio (%d sample rate(s))\n", - i2s_samplerates); + i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; goto init_audio; @@ -596,7 +596,7 @@ init_audio: break; case EM28XX_AC97_SIGMATEL: pr_info("Sigmatel audio processor detected (stac 97%02x)\n", - vid & 0xff); + vid & 0xff); break; case EM28XX_AC97_OTHER: pr_warn("Unknown AC97 audio processor detected!\n"); @@ -884,7 +884,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if ((xfer_bulk && !dev->dvb_ep_bulk) || (!xfer_bulk && !dev->dvb_ep_isoc)) { pr_err("no endpoint for DVB mode and transfer type %d\n", - xfer_bulk > 0); + xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.digital_bufs; @@ -892,7 +892,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if ((xfer_bulk && !dev->analog_ep_bulk) || (!xfer_bulk && !dev->analog_ep_isoc)) { pr_err("no endpoint for analog mode and transfer type %d\n", - xfer_bulk > 0); + xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.analog_bufs; @@ -940,8 +940,8 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + sb_size, i, + in_interrupt() ? " while in int" : ""); em28xx_uninit_usb_xfer(dev, mode); return -ENOMEM; } @@ -1022,7 +1022,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, rc = usb_clear_halt(dev->udev, usb_bufs->urb[0]->pipe); if (rc < 0) { pr_err("failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", - rc); + rc); em28xx_uninit_usb_xfer(dev, mode); return rc; } @@ -1037,8 +1037,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, for (i = 0; i < usb_bufs->num_bufs; i++) { rc = usb_submit_urb(usb_bufs->urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, - rc); + pr_err("submit of urb %i failed (error=%i)\n", i, rc); em28xx_uninit_usb_xfer(dev, mode); return rc; } @@ -1071,7 +1070,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) ops->init(dev); } mutex_unlock(&em28xx_devlist_mutex); - printk(KERN_INFO "em28xx: Registered (%s) extension\n", ops->name); + pr_info("em28xx: Registered (%s) extension\n", ops->name); return 0; } EXPORT_SYMBOL(em28xx_register_extension); @@ -1086,7 +1085,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) } list_del(&ops->next); mutex_unlock(&em28xx_devlist_mutex); - printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); + pr_info("Em28xx: Removed (%s) extension\n", ops->name); } EXPORT_SYMBOL(em28xx_unregister_extension); diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index cbece65899b5..6feb0e416eac 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -935,19 +935,19 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) cfg.ctrl = &ctl; if (!dev->dvb->fe[0]) { - pr_err("/2: dvb frontend not attached. Can't attach xc3028\n"); + pr_err("dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); if (!fe) { - pr_err("/2: xc3028 attach failed\n"); + pr_err("xc3028 attach failed\n"); dvb_frontend_detach(dev->dvb->fe[0]); dev->dvb->fe[0] = NULL; return -EINVAL; } - pr_info("%s/2: xc3028 attached\n", dev->name); + pr_info("xc3028 attached\n"); return 0; } @@ -966,8 +966,8 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, adapter_nr); if (result < 0) { - printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", - dev->name, result); + pr_warn("dvb_register_adapter failed (errno = %d)\n", + result); goto fail_adapter; } #ifdef CONFIG_MEDIA_CONTROLLER_DVB @@ -984,8 +984,8 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]); if (result < 0) { - printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", - dev->name, result); + pr_warn("dvb_register_frontend failed (errno = %d)\n", + result); goto fail_frontend0; } @@ -993,8 +993,8 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, if (dvb->fe[1]) { result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); if (result < 0) { - printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n", - dev->name, result); + pr_warn("2nd dvb_register_frontend failed (errno = %d)\n", + result); goto fail_frontend1; } } @@ -1011,8 +1011,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", - dev->name, result); + pr_warn("dvb_dmx_init failed (errno = %d)\n", result); goto fail_dmx; } @@ -1021,31 +1020,29 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", - dev->name, result); + pr_warn("dvb_dmxdev_init failed (errno = %d)\n", result); goto fail_dmxdev; } dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", - dev->name, result); + pr_warn("add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", + result); goto fail_fe_hw; } dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", - dev->name, result); + pr_warn("add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + result); goto fail_fe_mem; } result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", - dev->name, result); + pr_warn("connect_frontend failed (errno = %d)\n", result); goto fail_fe_conn; } @@ -1936,11 +1933,11 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; default: - pr_err("/2: The frontend of your DVB/ATSC card isn't supported yet\n"); + pr_err("The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { - pr_err("/2: frontend initialization failed\n"); + pr_err("frontend initialization failed\n"); result = -EINVAL; goto out_free; } diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 5185fed9fbf0..b7a5b4c5ceff 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -83,12 +83,12 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) if (ret == 0x94 + len - 1) { if (i2c_debug == 1) pr_warn("R05 returned 0x%02x: I2C ACK error\n", - ret); + ret); return -ENXIO; } if (ret < 0) { pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + ret); return ret; } msleep(5); @@ -118,7 +118,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); if (ret != 2) { pr_warn("failed to trigger read from i2c address 0x%x (error=%i)\n", - addr, ret); + addr, ret); return (ret < 0) ? ret : -EIO; } @@ -130,12 +130,12 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) if (ret == 0x94 + len - 1) { if (i2c_debug == 1) pr_warn("R05 returned 0x%02x: I2C ACK error\n", - ret); + ret); return -ENXIO; } if (ret < 0) { pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + ret); return ret; } msleep(5); @@ -143,14 +143,14 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) if (ret != 0x84 + len - 1) { if (i2c_debug) pr_warn("read from i2c device at 0x%x timed out\n", - addr); + addr); } /* get the received message */ ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); if (ret != len) { pr_warn("reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", - addr, ret); + addr, ret); return (ret < 0) ? ret : -EIO; } for (i = 0; i < len; i++) @@ -195,11 +195,11 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret != len) { if (ret < 0) { pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", - addr, ret); + addr, ret); return ret; } else { pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); + len, addr, ret); return -EIO; } } @@ -212,12 +212,12 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret == 0x10) { if (i2c_debug == 1) pr_warn("I2C ACK error on writing to addr 0x%02x\n", - addr); + addr); return -ENXIO; } if (ret < 0) { pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + ret); return ret; } msleep(5); @@ -232,12 +232,12 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, /* NOTE: these errors seem to be related to clock stretching */ if (i2c_debug) pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", - addr, ret); + addr, ret); return -ETIMEDOUT; } pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", - addr, ret); + addr, ret); return -EIO; } @@ -260,7 +260,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); if (ret < 0) { pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", - addr, ret); + addr, ret); return ret; } /* @@ -278,13 +278,13 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) return len; if (ret < 0) { pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + ret); return ret; } if (ret == 0x10) { if (i2c_debug == 1) pr_warn("I2C ACK error on writing to addr 0x%02x\n", - addr); + addr); return -ENXIO; } @@ -292,12 +292,12 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) /* NOTE: these errors seem to be related to clock stretching */ if (i2c_debug) pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", - addr, ret); + addr, ret); return -ETIMEDOUT; } pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", - addr, ret); + addr, ret); return -EIO; } @@ -337,11 +337,11 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret != len) { if (ret < 0) { pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", - addr, ret); + addr, ret); return ret; } else { pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); + len, addr, ret); return -EIO; } } @@ -356,7 +356,7 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, else if (ret > 0) { if (i2c_debug == 1) pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", - ret); + ret); return -ENXIO; } @@ -388,7 +388,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); if (ret < 0) { pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", - addr, ret); + addr, ret); return ret; } /* @@ -411,7 +411,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, else if (ret > 0) { if (i2c_debug == 1) pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", - ret); + ret); return -ENXIO; } @@ -544,11 +544,11 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, if (rc < 0) { if (rc == -ENXIO) { if (i2c_debug > 1) - printk(KERN_CONT " no device\n"); + pr_cont(" no device\n"); rc = -ENODEV; } else { if (i2c_debug > 1) - printk(KERN_CONT " ERROR: %i\n", rc); + pr_cont(" ERROR: %i\n", rc); } rt_mutex_unlock(&dev->i2c_bus_lock); return rc; @@ -558,11 +558,11 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, rc = i2c_recv_bytes(i2c_bus, msgs[i]); if (i2c_debug > 1 && rc >= 0) - printk(KERN_CONT " %*ph", + pr_cont(" %*ph", msgs[i].len, msgs[i].buf); } else { if (i2c_debug > 1) - printk(KERN_CONT " %*ph", + pr_cont(" %*ph", msgs[i].len, msgs[i].buf); /* write bytes */ @@ -570,12 +570,12 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, } if (rc < 0) { if (i2c_debug > 1) - printk(KERN_CONT " ERROR: %i\n", rc); + pr_cont(" ERROR: %i\n", rc); rt_mutex_unlock(&dev->i2c_bus_lock); return rc; } if (i2c_debug > 1) - printk(KERN_CONT "\n"); + pr_cont("\n"); } rt_mutex_unlock(&dev->i2c_bus_lock); @@ -709,10 +709,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); + data[0], data[1], data[2], data[3], dev->hash); pr_info("EEPROM info:\n"); pr_info("\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", - mc_start, data[2]); + mc_start, data[2]); /* * boot configuration (address 0x0002): * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz @@ -731,7 +731,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data); if (err != 2) { pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", - err); + err); goto error; } @@ -749,7 +749,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data); if (err != len) { pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", - err); + err); goto error; } @@ -769,7 +769,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data[2] == 0x67 && data[3] == 0x95) { dev->hash = em28xx_hash_mem(data, len, 32); pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); + data[0], data[1], data[2], data[3], dev->hash); pr_info("EEPROM info:\n"); } else { pr_info("unknown eeprom format or eeprom corrupted !\n"); @@ -916,7 +916,7 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) continue; i2c_devicelist[i] = i; pr_info("found i2c device @ 0x%x on bus %d [%s]\n", - i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); + i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); } if (bus == dev->def_i2c_bus) @@ -951,7 +951,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { pr_err("%s: i2c_add_adapter failed! retval [%d]\n", - __func__, retval); + __func__, retval); return retval; } @@ -963,7 +963,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { pr_err("%s: em28xx_i2_eeprom failed! retval [%d]\n", - __func__, retval); + __func__, retval); return retval; } diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index e8e1f768d45e..0e23e65eff15 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -458,7 +458,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) case CHIP_ID_EM28178: return em2874_ir_change_protocol(rc_dev, rc_type); default: - printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", + pr_err("Unrecognized em28xx chip id 0x%02x: IR not supported\n", dev->chip_id); return -EINVAL; } diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 836c6b53b16c..744b3300b153 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -21,12 +21,13 @@ 02110-1301, USA. */ +#include "em28xx.h" + #include #include #include #include -#include "em28xx.h" #include "em28xx-v4l.h" /* ------------------------------------------------------------------ */ @@ -63,8 +64,8 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb) size = v4l2->vbi_width * v4l2->vbi_height * 2; if (vb2_plane_size(vb, 0) < size) { - printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n", - __func__, vb2_plane_size(vb, 0), size); + pr_info("%s data will not fit into plane (%lu < %lu)\n", + __func__, vb2_plane_size(vb, 0), size); return -EINVAL; } vb2_set_plane_payload(vb, 0, size); diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3efabc19bfe9..8b5e13bbfb07 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -66,16 +66,13 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); #define em28xx_videodbg(fmt, arg...) do {\ if (video_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __func__ , ##arg); } while (0) + printk(KERN_DEBUG pr_fmt("video: %s: " fmt), \ + __func__, ##arg); } while (0) -#define em28xx_isocdbg(fmt, arg...) \ -do {\ - if (isoc_debug) { \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __func__ , ##arg); \ - } \ - } while (0) +#define em28xx_isocdbg(fmt, arg...) do {\ + if (isoc_debug) \ + printk(KERN_DEBUG pr_fmt("isoc: %s: " fmt), \ + __func__, ##arg); } while (0) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); @@ -415,7 +412,7 @@ set_alt: errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); if (errCode < 0) { pr_err("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); + dev->alt, errCode); return errCode; } return 0; @@ -2049,7 +2046,7 @@ static int em28xx_v4l2_open(struct file *filp) ret = v4l2_fh_open(filp); if (ret) { pr_err("%s: v4l2_fh_open() returned error %d\n", - __func__, ret); + __func__, ret); mutex_unlock(&dev->lock); return ret; } @@ -2115,17 +2112,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) if (video_is_registered(&v4l2->radio_dev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->radio_dev)); + video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vbi_dev)); + video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vdev)); + video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } @@ -2525,7 +2522,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_audio_setup(dev); if (ret < 0) { pr_err("%s: Error while setting audio - error [%d]!\n", - __func__, ret); + __func__, ret); goto unregister_dev; } if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { @@ -2553,7 +2550,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); if (ret < 0) { pr_err("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", - __func__, ret); + __func__, ret); goto unregister_dev; } msleep(3); @@ -2561,7 +2558,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); if (ret < 0) { pr_err("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", - __func__, ret); + __func__, ret); goto unregister_dev; } msleep(3); @@ -2662,8 +2659,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - pr_err("unable to register video device (error=%i).\n", - ret); + pr_err("unable to register video device (error=%i).\n", ret); goto unregister_dev; } @@ -2707,7 +2703,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) goto unregister_dev; } pr_info("Registered radio device as %s\n", - video_device_node_name(&v4l2->radio_dev)); + video_device_node_name(&v4l2->radio_dev)); } /* Init entities at the Media Controller */ @@ -2723,11 +2719,11 @@ static int em28xx_v4l2_init(struct em28xx *dev) #endif pr_info("V4L2 video device registered as %s\n", - video_device_node_name(&v4l2->vdev)); + video_device_node_name(&v4l2->vdev)); if (video_is_registered(&v4l2->vbi_dev)) pr_info("V4L2 VBI device registered as %s\n", - video_device_node_name(&v4l2->vbi_dev)); + video_device_node_name(&v4l2->vbi_dev)); /* Save some power by putting tuner to sleep */ v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); @@ -2745,17 +2741,17 @@ static int em28xx_v4l2_init(struct em28xx *dev) unregister_dev: if (video_is_registered(&v4l2->radio_dev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->radio_dev)); + video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vbi_dev)); + video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vdev)); + video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } -- cgit v1.2.3 From 0a93dc1c18fd86f936bcb44f72dc044c0ea826a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 08:11:16 -0300 Subject: [media] dvb-core: don't break long lines Due to the 80-cols checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. So, join those continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_demux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index a0cf7b0d03e8..280716f1cc46 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -426,8 +426,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) } if (buf[1] & 0x80) { - dprintk_tscheck("TEI detected. " - "PID=0x%x data1=0x%x\n", + dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", pid, buf[1]); /* data in this packet can't be trusted - drop it unless * module option dvb_demux_feed_err_pkts is set */ -- cgit v1.2.3 From 0919f3a04b5e7ea019ef393dee892454f054fe16 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 08:18:35 -0300 Subject: [media] tuner-core: don't break long lines Due to the 80-cols checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. So, join those continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/tuner-core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 731487be5baa..e2613ecb7605 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -503,8 +503,7 @@ static int tuner_s_type_addr(struct v4l2_subdev *sd, set_type(c, tun_setup->type, tun_setup->mode_mask, tun_setup->config, tun_setup->tuner_callback); } else - tuner_dbg("set addr discarded for type %i, mask %x. " - "Asked to change tuner at addr 0x%02x, with mask %x\n", + tuner_dbg("set addr discarded for type %i, mask %x. Asked to change tuner at addr 0x%02x, with mask %x\n", t->type, t->mode_mask, tun_setup->addr, tun_setup->mode_mask); @@ -809,8 +808,8 @@ static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) if (mode != t->mode) { if (check_mode(t, mode) == -EINVAL) { - tuner_dbg("Tuner doesn't support mode %d. " - "Putting tuner to sleep\n", mode); + tuner_dbg("Tuner doesn't support mode %d. Putting tuner to sleep\n", + mode); t->standby = true; if (analog_ops->standby) analog_ops->standby(&t->fe); -- cgit v1.2.3 From e428744a9fa18a3e114fcd420d8263f8a3e274b3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Oct 2016 08:19:27 -0300 Subject: [media] tuner-core: use %&ph for small buffer dumps This driver has a printk with a continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work anymore. We might be using KERNEL_CONT, but it is better to just use a single printk line using %*ph for buffer dump. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/tuner-core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index e2613ecb7605..d3a6236b6b02 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -617,14 +617,12 @@ static int tuner_probe(struct i2c_client *client, if (show_i2c) { unsigned char buffer[16]; - int i, rc; + int rc; memset(buffer, 0, sizeof(buffer)); rc = i2c_master_recv(client, buffer, sizeof(buffer)); - tuner_info("I2C RECV = "); - for (i = 0; i < rc; i++) - printk(KERN_CONT "%02x ", buffer[i]); - printk("\n"); + if (rc >= 0) + tuner_info("I2C RECV = %*ph\n", rc, buffer); } /* autodetection code based on the i2c addr */ -- cgit v1.2.3 From b3ad24d2e0b039834db28d06727dc9a675aa0396 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 06:47:54 -0300 Subject: [media] dvb-core: use pr_foo() instead of printk() The dvb-core directly calls printk() without using the modern printk macros, or using the proper printk levels. Change it to use pr_foo(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 24 ++++++---- drivers/media/dvb-core/dvb_ca_en50221.c | 57 ++++++++++++++--------- drivers/media/dvb-core/dvb_demux.c | 46 ++++++++++-------- drivers/media/dvb-core/dvb_frontend.c | 12 +++-- drivers/media/dvb-core/dvb_net.c | 82 ++++++++++++++++++--------------- drivers/media/dvb-core/dvbdev.c | 25 ++++++---- 6 files changed, 146 insertions(+), 100 deletions(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 7b67e1dd97fd..1e96a6f1b6f0 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -20,6 +20,8 @@ * */ +#define pr_fmt(fmt) "dmxdev: " fmt + #include #include #include @@ -36,7 +38,11 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); -#define dprintk if (debug) printk +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, const u8 *src, size_t len) @@ -50,7 +56,7 @@ static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, free = dvb_ringbuffer_free(buf); if (len > free) { - dprintk("dmxdev: buffer overflow\n"); + dprintk("buffer overflow\n"); return -EOVERFLOW; } @@ -126,7 +132,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; - dprintk("function : %s\n", __func__); + dprintk("%s\n", __func__); if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -258,7 +264,7 @@ static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, void *newmem; void *oldmem; - dprintk("function : %s\n", __func__); + dprintk("%s\n", __func__); if (buf->size == size) return 0; @@ -367,7 +373,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, return 0; } del_timer(&dmxdevfilter->timer); - dprintk("dmxdev: section callback %*ph\n", 6, buffer1); + dprintk("section callback %*ph\n", 6, buffer1); ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len); if (ret == buffer1_len) { @@ -655,7 +661,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) secfeed, dvb_dmxdev_section_callback); if (ret < 0) { - printk("DVB (%s): could not alloc feed\n", + pr_err("DVB (%s): could not alloc feed\n", __func__); return ret; } @@ -663,7 +669,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) ret = (*secfeed)->set(*secfeed, para->pid, 32768, (para->flags & DMX_CHECK_CRC) ? 1 : 0); if (ret < 0) { - printk("DVB (%s): could not set feed\n", + pr_err("DVB (%s): could not set feed\n", __func__); dvb_dmxdev_feed_restart(filter); return ret; @@ -844,7 +850,7 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter, struct dmx_sct_filter_params *params) { - dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n", + dprintk("%s: PID=0x%04x, flags=%02x, timeout=%d\n", __func__, params->pid, params->flags, params->timeout); dvb_dmxdev_filter_stop(dmxdevfilter); @@ -1184,7 +1190,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) struct dmxdev *dmxdev = dvbdev->priv; unsigned int mask = 0; - dprintk("function : %s\n", __func__); + dprintk("%s\n", __func__); if (dmxdev->exit) return POLLERR; diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index b5b5b195ea7f..262a492e7c08 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -28,6 +28,8 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ +#define pr_fmt(fmt) "dvb_ca_en50221: " fmt + #include #include #include @@ -46,7 +48,10 @@ static int dvb_ca_en50221_debug; module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644); MODULE_PARM_DESC(cam_debug, "enable verbose debug messages"); -#define dprintk if (dvb_ca_en50221_debug) printk +#define dprintk(fmt, arg...) do { \ + if (dvb_ca_en50221_debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg);\ +} while (0) #define INIT_TIMEOUT_SECS 10 @@ -298,7 +303,8 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, /* if we got the flags, it was successful! */ if (res & waitfor) { - dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start); + dprintk("%s succeeded timeout:%lu\n", + __func__, jiffies - start); return 0; } @@ -519,8 +525,9 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) /* is it a version we support? */ if (strncmp(dvb_str + 8, "1.00", 4)) { - printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n", - ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]); + pr_err("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n", + ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], + dvb_str[10], dvb_str[11]); return -EINVAL; } @@ -557,8 +564,8 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) break; default: /* Unknown tuple type - just skip this tuple and move to the next one */ - dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType, - tupleLength); + dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", + tupleType, tupleLength); break; } } @@ -567,7 +574,8 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) return -EINVAL; dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n", - manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option); + manfid, devid, ca->slot_info[slot].config_base, + ca->slot_info[slot].config_option); // success! return 0; @@ -661,14 +669,15 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb /* check it will fit */ if (ebuf == NULL) { if (bytes_read > ca->slot_info[slot].link_buf_size) { - printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n", - ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size); + pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n", + ca->dvbdev->adapter->num, bytes_read, + ca->slot_info[slot].link_buf_size); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } if (bytes_read < 2) { - printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n", + pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; @@ -676,7 +685,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb } } else { if (bytes_read > ecount) { - printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n", + pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n", ca->dvbdev->adapter->num); status = -EIO; goto exit; @@ -1062,7 +1071,7 @@ static int dvb_ca_en50221_thread(void *data) case DVB_CA_SLOTSTATE_WAITREADY: if (time_after(jiffies, ca->slot_info[slot].timeout)) { - printk("dvb_ca adaptor %d: PC card did not respond :(\n", + pr_err("dvb_ca adaptor %d: PC card did not respond :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); @@ -1084,14 +1093,14 @@ static int dvb_ca_en50221_thread(void *data) } } - printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", + pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); break; } if (dvb_ca_en50221_set_configoption(ca, slot) != 0) { - printk("dvb_ca adapter %d: Unable to initialise CAM :(\n", + pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); @@ -1099,7 +1108,7 @@ static int dvb_ca_en50221_thread(void *data) } if (ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, CMDREG_RS) != 0) { - printk("dvb_ca adapter %d: Unable to reset CAM IF\n", + pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); @@ -1114,7 +1123,7 @@ static int dvb_ca_en50221_thread(void *data) case DVB_CA_SLOTSTATE_WAITFR: if (time_after(jiffies, ca->slot_info[slot].timeout)) { - printk("dvb_ca adapter %d: DVB CAM did not respond :(\n", + pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); @@ -1141,7 +1150,8 @@ static int dvb_ca_en50221_thread(void *data) } } - printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); + pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", + ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); break; @@ -1150,7 +1160,8 @@ static int dvb_ca_en50221_thread(void *data) if (ca->slot_info[slot].rx_buffer.data == NULL) { rxbuf = vmalloc(RX_BUFFER_SIZE); if (rxbuf == NULL) { - printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num); + pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", + ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); break; @@ -1161,7 +1172,8 @@ static int dvb_ca_en50221_thread(void *data) ca->pub->slot_ts_enable(ca->pub, slot); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING; dvb_ca_en50221_thread_update_delay(ca); - printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num); + pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", + ca->dvbdev->adapter->num); break; case DVB_CA_SLOTSTATE_RUNNING: @@ -1497,7 +1509,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, pktlen = 2; do { if (idx == -1) { - printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num); + pr_err("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", + ca->dvbdev->adapter->num); status = -EIO; goto exit; } @@ -1755,8 +1768,8 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ca->dvbdev->adapter->num, ca->dvbdev->id); if (IS_ERR(ca->thread)) { ret = PTR_ERR(ca->thread); - printk("dvb_ca_init: failed to start kernel_thread (%d)\n", - ret); + pr_err("dvb_ca_init: failed to start kernel_thread (%d)\n", + ret); goto unregister_device; } return 0; diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 280716f1cc46..a0a1f8456c54 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -21,6 +21,8 @@ * */ +#define pr_fmt(fmt) "dvb_demux: " fmt + #include #include #include @@ -55,10 +57,13 @@ module_param(dvb_demux_feed_err_pkts, int, 0644); MODULE_PARM_DESC(dvb_demux_feed_err_pkts, "when set to 0, drop packets with the TEI bit set (1 by default)"); -#define dprintk_tscheck(x...) do { \ - if (dvb_demux_tscheck && printk_ratelimit()) \ - printk(x); \ - } while (0) +#define dprintk(fmt, arg...) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg) + +#define dprintk_tscheck(x...) do { \ + if (dvb_demux_tscheck && printk_ratelimit()) \ + dprintk(x); \ +} while (0) /****************************************************************************** * static inlined helper functions @@ -122,7 +127,7 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, ccok = ((feed->cc + 1) & 0x0f) == cc; feed->cc = cc; if (!ccok) - printk("missed packet!\n"); + dprintk("missed packet!\n"); */ if (buf[1] & 0x40) // PUSI ? @@ -199,12 +204,12 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) * but just first and last. */ if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { - printk("dvb_demux.c section ts padding loss: %d/%d\n", + dprintk("dvb_demux.c section ts padding loss: %d/%d\n", n, sec->tsfeedp); - printk("dvb_demux.c pad data:"); + dprintk("dvb_demux.c pad data:"); for (i = 0; i < n; i++) - printk(" %02x", sec->secbuf[i]); - printk("\n"); + pr_cont(" %02x", sec->secbuf[i]); + pr_cont("\n"); } } #endif @@ -243,7 +248,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { #ifdef DVB_DEMUX_SECTION_LOSS_LOG - printk("dvb_demux.c section buffer full loss: %d/%d\n", + dprintk("dvb_demux.c section buffer full loss: %d/%d\n", sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE); #endif @@ -278,7 +283,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, dvb_dmx_swfilter_section_feed(feed); #ifdef DVB_DEMUX_SECTION_LOSS_LOG else - printk("dvb_demux.c pusi not seen, discarding section data\n"); + dprintk("dvb_demux.c pusi not seen, discarding section data\n"); #endif sec->secbufp += seclen; /* secbufp and secbuf moving together is */ sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ @@ -313,8 +318,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, if (!ccok || dc_i) { #ifdef DVB_DEMUX_SECTION_LOSS_LOG - printk("dvb_demux.c discontinuity detected %d bytes lost\n", - count); + dprintk("dvb_demux.c discontinuity detected %d bytes lost\n", + count); /* * those bytes under sume circumstances will again be reported * in the following dvb_dmx_swfilter_section_new @@ -346,7 +351,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, } #ifdef DVB_DEMUX_SECTION_LOSS_LOG else if (count > 0) - printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count); + dprintk("dvb_demux.c PUSI=1 but %d bytes lost\n", + count); #endif } else { /* PUSI=0 (is not set), no section boundary */ @@ -415,9 +421,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) 1024); speed_timedelta = ktime_ms_delta(cur_time, demux->speed_last_time); - printk(KERN_INFO "TS speed %llu Kbits/sec \n", - div64_u64(speed_bytes, - speed_timedelta)); + dprintk("TS speed %llu Kbits/sec \n", + div64_u64(speed_bytes, + speed_timedelta)); } demux->speed_last_time = cur_time; @@ -634,7 +640,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed) { spin_lock_irq(&feed->demux->lock); if (dvb_demux_feed_find(feed)) { - printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n", + pr_err("%s: feed already in list (type=%x state=%x pid=%x)\n", __func__, feed->type, feed->state, feed->pid); goto out; } @@ -648,7 +654,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed) { spin_lock_irq(&feed->demux->lock); if (!(dvb_demux_feed_find(feed))) { - printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n", + pr_err("%s: feed not in list (type=%x state=%x pid=%x)\n", __func__, feed->type, feed->state, feed->pid); goto out; } @@ -1267,7 +1273,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) dvbdemux->cnt_storage = vmalloc(MAX_PID + 1); if (!dvbdemux->cnt_storage) - printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); + pr_warn("Couldn't allocate memory for TS/TEI check. Disabling it\n"); INIT_LIST_HEAD(&dvbdemux->frontend_list); diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 01511e5a5566..98edf46b22d0 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -28,6 +28,8 @@ /* Enables DVBv3 compatibility bits at the headers */ #define __DVB_CORE__ +#define pr_fmt(fmt) "dvb_frontend: " fmt + #include #include #include @@ -67,6 +69,9 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volt module_param(dvb_mfe_wait_time, int, 0644); MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to seconds on open() for multi-frontend to become available (default:5 seconds)"); +#define dprintk(fmt, arg...) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg) + #define FESTATE_IDLE 1 #define FESTATE_RETUNE 2 #define FESTATE_TUNING_FAST 4 @@ -2356,7 +2361,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file, int i; u8 last = 1; if (dvb_frontend_debug) - printk("%s switch command: 0x%04lx\n", __func__, swcmd); + dprintk("%s switch command: 0x%04lx\n", + __func__, swcmd); nexttime = ktime_get_boottime(); if (dvb_frontend_debug) tv[0] = nexttime; @@ -2379,10 +2385,10 @@ static int dvb_frontend_ioctl_legacy(struct file *file, dvb_frontend_sleep_until(&nexttime, 8000); } if (dvb_frontend_debug) { - printk("%s(%d): switch delay (should be 32k followed by all 8k\n", + dprintk("%s(%d): switch delay (should be 32k followed by all 8k)\n", __func__, fe->dvb->num); for (i = 1; i < 10; i++) - printk("%d: %d\n", i, + pr_info("%d: %d\n", i, (int) ktime_us_delta(tv[i], tv[i-1])); } err = 0; diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 9914f69a4a02..063f63563919 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -54,6 +54,8 @@ * */ +#define pr_fmt(fmt) "dvb_net: " fmt + #include #include #include @@ -344,7 +346,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */ if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) { - printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", + pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", priv->ts_count, ts[0], (ts[1] & TS_TEI) >> 7, (ts[3] & TS_SC) >> 6); @@ -376,8 +378,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) priv->tscc = ts[3] & 0x0F; /* There is a pointer field here. */ if (ts[4] > ts_remain) { - printk(KERN_ERR "%lu: Invalid ULE packet " - "(pointer field %d)\n", priv->ts_count, ts[4]); + pr_err("%lu: Invalid ULE packet (pointer field %d)\n", + priv->ts_count, ts[4]); ts += TS_SZ; priv->ts_count++; continue; @@ -400,8 +402,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) priv->tscc = (priv->tscc + 1) & 0x0F; else { /* TS discontinuity handling: */ - printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " - "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); + pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n", + priv->ts_count, ts[3] & 0x0F, + priv->tscc); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { dev_kfree_skb( priv->ule_skb ); @@ -423,8 +426,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (! priv->need_pusi) { if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ - printk(KERN_WARNING "%lu: Invalid pointer " - "field: %u.\n", priv->ts_count, *from_where); + pr_warn("%lu: Invalid pointer field: %u.\n", + priv->ts_count, + *from_where); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { @@ -454,9 +458,10 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * current TS cell. */ dev->stats.rx_errors++; dev->stats.rx_length_errors++; - printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " - "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", - priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); + pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", + priv->ts_count, + priv->ule_sndu_remain, + ts[4], ts_remain); dev_kfree_skb(priv->ule_skb); /* Prepare for next SNDU. */ reset_ule(priv); @@ -475,8 +480,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * TS. * Check ts_remain has to be >= 2 here. */ if (ts_remain < 2) { - printk(KERN_WARNING "Invalid payload packing: only %d " - "bytes left in TS. Resyncing.\n", ts_remain); + pr_warn("Invalid payload packing: only %d bytes left in TS. Resyncing.\n", + ts_remain); priv->ule_sndu_len = 0; priv->need_pusi = 1; ts += TS_SZ; @@ -494,8 +499,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) priv->ule_dbit = 0; if (priv->ule_sndu_len < 5) { - printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " - "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); + pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n", + priv->ts_count, + priv->ule_sndu_len); dev->stats.rx_errors++; dev->stats.rx_length_errors++; priv->ule_sndu_len = 0; @@ -550,8 +556,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */ priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN ); if (priv->ule_skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", - dev->name); + pr_notice("%s: Memory squeeze, dropping packet.\n", + dev->name); dev->stats.rx_dropped++; return; } @@ -595,8 +601,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) *(tail - 2) << 8 | *(tail - 1); if (ule_crc != expected_crc) { - printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", - priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0); + pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", + priv->ts_count, ule_crc, expected_crc, + priv->ule_sndu_len, priv->ule_sndu_type, + ts_remain, + ts_remain > 2 ? *(unsigned short *)from_where : 0); #ifdef ULE_DEBUG hexdump( iov[0].iov_base, iov[0].iov_len ); @@ -687,7 +696,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) int l = handle_ule_extensions(priv); if (l < 0) { /* Mandatory extension header unknown or TEST SNDU. Drop it. */ - // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); + // pr_warn("Dropping SNDU, extension headers.\n" ); dev_kfree_skb(priv->ule_skb); goto sndu_done; } @@ -741,10 +750,10 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) priv->ule_skb = NULL; priv->ule_sndu_type_1 = 0; priv->ule_sndu_len = 0; - // printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n", + // pr_warn("More data in current TS: [%#x %#x %#x %#x]\n", // *(from_where + 0), *(from_where + 1), // *(from_where + 2), *(from_where + 3)); - // printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0); + // pr_warn("ts @ %p, stopped @ %p:\n", ts, from_where + 0); // hexdump(ts, 188); } else { new_ts = 1; @@ -766,10 +775,10 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, struct net_device *dev = feed->priv; if (buffer2) - printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2); + pr_warn("buffer2 not NULL: %p.\n", buffer2); if (buffer1_len > 32768) - printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len); - /* printk("TS callback: %u bytes, %u TS cells @ %p.\n", + pr_warn("length > 32k: %zu.\n", buffer1_len); + /* pr_info("TS callback: %u bytes, %u TS cells @ %p.\n", buffer1_len, buffer1_len / TS_SZ, buffer1); */ dvb_net_ule(dev, buffer1, buffer1_len); return 0; @@ -786,7 +795,7 @@ static void dvb_net_sec(struct net_device *dev, /* note: pkt_len includes a 32bit checksum */ if (pkt_len < 16) { - printk("%s: IP/MPE packet length = %d too small.\n", + pr_warn("%s: IP/MPE packet length = %d too small.\n", dev->name, pkt_len); stats->rx_errors++; stats->rx_length_errors++; @@ -824,7 +833,7 @@ static void dvb_net_sec(struct net_device *dev, * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP */ if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) { - //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); + //pr_notice("%s: Memory squeeze, dropping packet.\n", dev->name); stats->rx_dropped++; return; } @@ -903,7 +912,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev, *secfilter=NULL; ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter); if (ret<0) { - printk("%s: could not get filter\n", dev->name); + pr_err("%s: could not get filter\n", dev->name); return ret; } @@ -944,7 +953,7 @@ static int dvb_net_feed_start(struct net_device *dev) netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode); mutex_lock(&priv->mutex); if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) - printk("%s: BUG %d\n", __func__, __LINE__); + pr_err("%s: BUG %d\n", __func__, __LINE__); priv->secfeed=NULL; priv->secfilter=NULL; @@ -955,14 +964,15 @@ static int dvb_net_feed_start(struct net_device *dev) ret=demux->allocate_section_feed(demux, &priv->secfeed, dvb_net_sec_callback); if (ret<0) { - printk("%s: could not allocate section feed\n", dev->name); + pr_err("%s: could not allocate section feed\n", + dev->name); goto error; } ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1); if (ret<0) { - printk("%s: could not set section feed\n", dev->name); + pr_err("%s: could not set section feed\n", dev->name); priv->demux->release_section_feed(priv->demux, priv->secfeed); priv->secfeed=NULL; goto error; @@ -1003,7 +1013,7 @@ static int dvb_net_feed_start(struct net_device *dev) netdev_dbg(dev, "alloc tsfeed\n"); ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback); if (ret < 0) { - printk("%s: could not allocate ts feed\n", dev->name); + pr_err("%s: could not allocate ts feed\n", dev->name); goto error; } @@ -1018,7 +1028,7 @@ static int dvb_net_feed_start(struct net_device *dev) ); if (ret < 0) { - printk("%s: could not set ts feed\n", dev->name); + pr_err("%s: could not set ts feed\n", dev->name); priv->demux->release_ts_feed(priv->demux, priv->tsfeed); priv->tsfeed = NULL; goto error; @@ -1067,7 +1077,7 @@ static int dvb_net_feed_stop(struct net_device *dev) priv->demux->release_section_feed(priv->demux, priv->secfeed); priv->secfeed = NULL; } else - printk("%s: no feed to stop\n", dev->name); + pr_err("%s: no feed to stop\n", dev->name); } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { if (priv->tsfeed) { if (priv->tsfeed->is_filtering) { @@ -1078,7 +1088,7 @@ static int dvb_net_feed_stop(struct net_device *dev) priv->tsfeed = NULL; } else - printk("%s: no ts feed to stop\n", dev->name); + pr_err("%s: no ts feed to stop\n", dev->name); } else ret = -EINVAL; mutex_unlock(&priv->mutex); @@ -1279,7 +1289,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) free_netdev(net); return result; } - printk("dvb_net: created network interface %s\n", net->name); + pr_info("created network interface %s\n", net->name); return if_num; } @@ -1298,7 +1308,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) dvb_net_stop(net); flush_work(&priv->set_multicast_list_wq); flush_work(&priv->restart_net_feed_wq); - printk("dvb_net: removed network interface %s\n", net->name); + pr_info("removed network interface %s\n", net->name); unregister_netdev(net); dvbnet->state[num]=0; dvbnet->device[num] = NULL; diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 75a3f4b57fd4..0694d1d53c67 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -21,6 +21,8 @@ * */ +#define pr_fmt(fmt) "dvbdev: " fmt + #include #include #include @@ -43,7 +45,11 @@ static int dvbdev_debug; module_param(dvbdev_debug, int, 0644); MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off)."); -#define dprintk if (dvbdev_debug) printk +#define dprintk(fmt, arg...) do { \ + if (dvbdev_debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) static LIST_HEAD(dvb_adapter_list); static DEFINE_MUTEX(dvbdev_register_lock); @@ -354,7 +360,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, if (ret) return ret; - printk(KERN_DEBUG "%s: media entity '%s' registered.\n", + pr_info("%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); return 0; @@ -438,7 +444,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; - printk(KERN_ERR "%s: couldn't find free device id\n", __func__); + pr_err("%s: couldn't find free device id\n", __func__); return -ENFILE; } @@ -493,8 +499,7 @@ 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) { - printk(KERN_ERR - "%s: dvb_register_media_device failed to create the mediagraph\n", + pr_err("%s: dvb_register_media_device failed to create the mediagraph\n", __func__); dvb_media_device_free(dvbdev); @@ -511,11 +516,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, MKDEV(DVB_MAJOR, minor), dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); if (IS_ERR(clsdev)) { - printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", + pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); return PTR_ERR(clsdev); } - dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", + dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, minor, minor); return 0; @@ -808,7 +813,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, memset (adap, 0, sizeof(struct dvb_adapter)); INIT_LIST_HEAD (&adap->device_list); - printk(KERN_INFO "DVB: registering new adapter (%s)\n", name); + pr_info("DVB: registering new adapter (%s)\n", name); adap->num = num; adap->name = name; @@ -926,13 +931,13 @@ static int __init init_dvbdev(void) dev_t dev = MKDEV(DVB_MAJOR, 0); if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { - printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR); + 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) { - printk(KERN_ERR "dvb-core: unable register character device\n"); + pr_err("dvb-core: unable register character device\n"); goto error; } -- cgit v1.2.3 From bbd02f6aa9fb4c1c951fe52629b722f79c70883f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 06:57:47 -0300 Subject: [media] dvb_demux: convert an internal ifdef into a Kconfig option There are some ifdefs inside the dvb_demux that are meant to enable advanced debug capabilities, at the cost of being very verbose. Keeping those as internal ifdefs is a very bad idea, as it doesn't make easy to check if the code there was broken by some patch. So, let's add an explicit Kconfig option for it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/Kconfig | 13 +++++++++++++ drivers/media/dvb-core/dvb_demux.c | 14 +++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig index fa7a2490ed5f..8964f1d3cf57 100644 --- a/drivers/media/dvb-core/Kconfig +++ b/drivers/media/dvb-core/Kconfig @@ -27,3 +27,16 @@ config DVB_DYNAMIC_MINORS will be required to manage the device nodes. If you are unsure about this, say N here. + +config DVB_DEMUX_SECTION_LOSS_LOG + bool "Enable DVB demux section packet loss log" + depends on DVB_CORE + default n + help + Enable extra log messages meant to detect packet loss + inside the Kernel. + + Should not be enabled on normal cases, as logs can + be very verbose. + + If you are unsure about this, say N here. diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index a0a1f8456c54..5a69b0bda4bb 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -37,10 +37,6 @@ #include "dvb_demux.h" #define NOBUFS -/* -** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog -*/ -// #define DVB_DEMUX_SECTION_LOSS_LOG static int dvb_demux_tscheck; module_param(dvb_demux_tscheck, int, 0644); @@ -194,7 +190,7 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) { struct dmx_section_feed *sec = &feed->feed.sec; -#ifdef DVB_DEMUX_SECTION_LOSS_LOG +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG if (sec->secbufp < sec->tsfeedp) { int i, n = sec->tsfeedp - sec->secbufp; @@ -247,7 +243,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, return 0; if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { -#ifdef DVB_DEMUX_SECTION_LOSS_LOG +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG dprintk("dvb_demux.c section buffer full loss: %d/%d\n", sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE); @@ -281,7 +277,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, /* dump [secbuf .. secbuf+seclen) */ if (feed->pusi_seen) dvb_dmx_swfilter_section_feed(feed); -#ifdef DVB_DEMUX_SECTION_LOSS_LOG +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG else dprintk("dvb_demux.c pusi not seen, discarding section data\n"); #endif @@ -317,7 +313,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, } if (!ccok || dc_i) { -#ifdef DVB_DEMUX_SECTION_LOSS_LOG +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG dprintk("dvb_demux.c discontinuity detected %d bytes lost\n", count); /* @@ -349,7 +345,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, dvb_dmx_swfilter_section_copy_dump(feed, after, after_len); } -#ifdef DVB_DEMUX_SECTION_LOSS_LOG +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG else if (count > 0) dprintk("dvb_demux.c PUSI=1 but %d bytes lost\n", count); -- cgit v1.2.3 From 801edd6bb9b223390028dc7f565904a2833d20e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 07:19:55 -0300 Subject: [media] dvb_demux: uncomment a packet loss check code There is a commented code that also detects packet loss. Uncomment it and put into the DVB_DEMUX_SECTION_LOSS_LOG debug Kconfig option. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_demux.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 5a69b0bda4bb..51bf5eb2df49 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -110,21 +110,23 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, { int count = payload(buf); int p; - //int ccok; - //u8 cc; +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG + int ccok; + u8 cc; +#endif if (count == 0) return -1; p = 188 - count; - /* +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG cc = buf[3] & 0x0f; ccok = ((feed->cc + 1) & 0x0f) == cc; feed->cc = cc; if (!ccok) dprintk("missed packet!\n"); - */ +#endif if (buf[1] & 0x40) // PUSI ? feed->peslen = 0xfffa; -- cgit v1.2.3 From dd79d27e1bbded7366ade6d25fbfde305e33fad8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 07:14:38 -0300 Subject: [media] dvb-core: get rid of demux optional circular buffer There is a provision at the dvb_demux.c to use a vmalloc'ed circular buffer, enabled via an extra #ifdef option that it is not at Kconfig. Enabling it will only make the Kernel to allocate/deallocate such buffer, but no code would actually use it. So, no practical effect, except for sparing some memory without any good reason. So, get rid of such dead code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/demux.h | 5 +---- drivers/media/dvb-core/dmxdev.c | 4 ++-- drivers/media/dvb-core/dvb_demux.c | 42 ++------------------------------------ drivers/media/dvb-core/dvb_demux.h | 2 -- drivers/media/dvb-core/dvb_net.c | 3 +-- 5 files changed, 6 insertions(+), 50 deletions(-) diff --git a/drivers/media/dvb-core/demux.h b/drivers/media/dvb-core/demux.h index aeda2b64931c..f8adf4506a45 100644 --- a/drivers/media/dvb-core/demux.h +++ b/drivers/media/dvb-core/demux.h @@ -103,7 +103,6 @@ struct dmx_ts_feed { u16 pid, int type, enum dmx_ts_pes pes_type, - size_t circular_buffer_size, ktime_t timeout); int (*start_filtering)(struct dmx_ts_feed *feed); int (*stop_filtering)(struct dmx_ts_feed *feed); @@ -181,7 +180,6 @@ struct dmx_section_feed { /* public: */ int (*set)(struct dmx_section_feed *feed, u16 pid, - size_t circular_buffer_size, int check_crc); int (*allocate_filter)(struct dmx_section_feed *feed, struct dmx_section_filter **filter); @@ -206,8 +204,7 @@ struct dmx_section_feed { * the &dmx_demux. * Any TS packets that match the filter settings are copied to a circular * buffer. The filtered TS packets are delivered to the client using this - * callback function. The size of the circular buffer is controlled by the - * circular_buffer_size parameter of the &dmx_ts_feed.@set function. + * callback function. * It is expected that the @buffer1 and @buffer2 callback parameters point to * addresses within the circular buffer, but other implementations are also * possible. Note that the called party should not try to free the memory diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 1e96a6f1b6f0..efe55a3e80d0 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -595,7 +595,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev, tsfeed = feed->ts; tsfeed->priv = filter; - ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout); + ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, timeout); if (ret < 0) { dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed); return ret; @@ -666,7 +666,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) return ret; } - ret = (*secfeed)->set(*secfeed, para->pid, 32768, + ret = (*secfeed)->set(*secfeed, para->pid, (para->flags & DMX_CHECK_CRC) ? 1 : 0); if (ret < 0) { pr_err("DVB (%s): could not set feed\n", diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 51bf5eb2df49..3ad0b2cd26b1 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -36,8 +36,6 @@ #include "dvb_demux.h" -#define NOBUFS - static int dvb_demux_tscheck; module_param(dvb_demux_tscheck, int, 0644); MODULE_PARM_DESC(dvb_demux_tscheck, @@ -663,8 +661,7 @@ out: } static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, - enum dmx_ts_pes pes_type, - size_t circular_buffer_size, ktime_t timeout) + enum dmx_ts_pes pes_type, ktime_t timeout) { struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; struct dvb_demux *demux = feed->demux; @@ -694,23 +691,10 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, dvb_demux_feed_add(feed); feed->pid = pid; - feed->buffer_size = circular_buffer_size; feed->timeout = timeout; feed->ts_type = ts_type; feed->pes_type = pes_type; - if (feed->buffer_size) { -#ifdef NOBUFS - feed->buffer = NULL; -#else - feed->buffer = vmalloc(feed->buffer_size); - if (!feed->buffer) { - mutex_unlock(&demux->mutex); - return -ENOMEM; - } -#endif - } - feed->state = DMX_STATE_READY; mutex_unlock(&demux->mutex); @@ -799,7 +783,6 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, feed->demux = demux; feed->pid = 0xffff; feed->peslen = 0xfffa; - feed->buffer = NULL; (*ts_feed) = &feed->feed.ts; (*ts_feed)->parent = dmx; @@ -836,10 +819,6 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, mutex_unlock(&demux->mutex); return -EINVAL; } -#ifndef NOBUFS - vfree(feed->buffer); - feed->buffer = NULL; -#endif feed->state = DMX_STATE_FREE; feed->filter->state = DMX_STATE_FREE; @@ -891,8 +870,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, } static int dmx_section_feed_set(struct dmx_section_feed *feed, - u16 pid, size_t circular_buffer_size, - int check_crc) + u16 pid, int check_crc) { struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = dvbdmxfeed->demux; @@ -906,19 +884,8 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed, dvb_demux_feed_add(dvbdmxfeed); dvbdmxfeed->pid = pid; - dvbdmxfeed->buffer_size = circular_buffer_size; dvbdmxfeed->feed.sec.check_crc = check_crc; -#ifdef NOBUFS - dvbdmxfeed->buffer = NULL; -#else - dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size); - if (!dvbdmxfeed->buffer) { - mutex_unlock(&dvbdmx->mutex); - return -ENOMEM; - } -#endif - dvbdmxfeed->state = DMX_STATE_READY; mutex_unlock(&dvbdmx->mutex); return 0; @@ -1077,7 +1044,6 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; dvbdmxfeed->feed.sec.tsfeedp = 0; dvbdmxfeed->filter = NULL; - dvbdmxfeed->buffer = NULL; (*feed) = &dvbdmxfeed->feed.sec; (*feed)->is_filtering = 0; @@ -1106,10 +1072,6 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, mutex_unlock(&dvbdmx->mutex); return -EINVAL; } -#ifndef NOBUFS - vfree(dvbdmxfeed->buffer); - dvbdmxfeed->buffer = NULL; -#endif dvbdmxfeed->state = DMX_STATE_FREE; dvb_demux_feed_del(dvbdmxfeed); diff --git a/drivers/media/dvb-core/dvb_demux.h b/drivers/media/dvb-core/dvb_demux.h index 5ed3cab4ad28..9235b008ea0a 100644 --- a/drivers/media/dvb-core/dvb_demux.h +++ b/drivers/media/dvb-core/dvb_demux.h @@ -80,8 +80,6 @@ struct dvb_demux_feed { int type; int state; u16 pid; - u8 *buffer; - int buffer_size; ktime_t timeout; struct dvb_demux_filter *filter; diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 063f63563919..b9a46d5a1bb5 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -969,7 +969,7 @@ static int dvb_net_feed_start(struct net_device *dev) goto error; } - ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1); + ret = priv->secfeed->set(priv->secfeed, priv->pid, 1); if (ret<0) { pr_err("%s: could not set section feed\n", dev->name); @@ -1023,7 +1023,6 @@ static int dvb_net_feed_start(struct net_device *dev) priv->pid, /* pid */ TS_PACKET, /* type */ DMX_PES_OTHER, /* pes type */ - 32768, /* circular buffer size */ timeout /* timeout */ ); -- cgit v1.2.3 From b676e7316ae9b4e6424dc0beb16dbaf71c659a18 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 07:41:38 -0300 Subject: [media] dvb-core: move dvb_filter out of the DVB core The dvb_filter.c can hardly be considered as part of the DVB core. More than half of the code there is commented out by av7110 and ttusb_dec. On the latter, just two small helper functions and a struct definition is used. Being part of the core means that it would require an amount of work to fix issues in it, like bad printk's on it, and to document it on some future, like other kAPI headers. It simply not worth the effort for something that seems to be deprecated, as no new drivers use it. So, move it out of the core, by moving it to pci/ttpci directory, where av7110 driver is kept, and copy the two routines used by ttyusb_dec directly into its code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-common.h | 1 - drivers/media/dvb-core/Makefile | 2 +- drivers/media/dvb-core/dvb_filter.c | 603 ----------------------------- drivers/media/dvb-core/dvb_filter.h | 246 ------------ drivers/media/pci/ttpci/Makefile | 2 +- drivers/media/pci/ttpci/dvb_filter.c | 600 ++++++++++++++++++++++++++++ drivers/media/pci/ttpci/dvb_filter.h | 246 ++++++++++++ drivers/media/usb/ttusb-dec/ttusb_dec.c | 58 ++- 8 files changed, 905 insertions(+), 853 deletions(-) delete mode 100644 drivers/media/dvb-core/dvb_filter.c delete mode 100644 drivers/media/dvb-core/dvb_filter.h create mode 100644 drivers/media/pci/ttpci/dvb_filter.c create mode 100644 drivers/media/pci/ttpci/dvb_filter.h diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h index 2b2460e9e6b4..2533574c0cf4 100644 --- a/drivers/media/common/b2c2/flexcop-common.h +++ b/drivers/media/common/b2c2/flexcop-common.h @@ -14,7 +14,6 @@ #include "dmxdev.h" #include "dvb_demux.h" -#include "dvb_filter.h" #include "dvb_net.h" #include "dvb_frontend.h" diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile index 8f22bcd7c1f9..281bc89576e6 100644 --- a/drivers/media/dvb-core/Makefile +++ b/drivers/media/dvb-core/Makefile @@ -4,7 +4,7 @@ dvb-net-$(CONFIG_DVB_NET) := dvb_net.o -dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ +dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ dvb_ca_en50221.o dvb_frontend.o \ $(dvb-net-y) dvb_ringbuffer.o dvb_math.o diff --git a/drivers/media/dvb-core/dvb_filter.c b/drivers/media/dvb-core/dvb_filter.c deleted file mode 100644 index 772003fb1821..000000000000 --- a/drivers/media/dvb-core/dvb_filter.c +++ /dev/null @@ -1,603 +0,0 @@ -#include -#include -#include -#include "dvb_filter.h" - -#if 0 -static unsigned int bitrates[3][16] = -{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, - {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, - {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; -#endif - -static u32 freq[4] = {480, 441, 320, 0}; - -static unsigned int ac3_bitrates[32] = - {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, - 0,0,0,0,0,0,0,0,0,0,0,0,0}; - -static u32 ac3_frames[3][32] = - {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, - 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, - 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, - 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - - - -#if 0 -static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, - void (*pes_write)(u8 *buf, int count, void *data), - void *priv) -{ - dvb_filter_ipack_init(pa, IPACKS, pes_write); - dvb_filter_ipack_init(pv, IPACKS, pes_write); - pa->pid = pida; - pv->pid = pidv; - pa->data = priv; - pv->data = priv; -} -#endif - -#if 0 -static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) -{ - u8 off = 0; - - if (!buf || !p ){ - printk("NULL POINTER IDIOT\n"); - return; - } - if (buf[1]&PAY_START) { - if (p->plength == MMAX_PLENGTH-6 && p->found>6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - dvb_filter_ipack_reset(p); - } - } - if (buf[3] & ADAPT_FIELD) { // adaptation field? - off = buf[4] + 1; - if (off+4 > 187) return; - } - dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p); -} -#endif - -#if 0 -/* needs 5 byte input, returns picture coding type*/ -static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) -{ - u8 pct; - - if (pr) printk( "Pic header: "); - pic->temporal_reference[field] = (( headr[0] << 2 ) | - (headr[1] & 0x03) )& 0x03ff; - if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]); - - pct = ( headr[1] >> 2 ) & 0x07; - pic->picture_coding_type[field] = pct; - if (pr) { - switch(pct){ - case I_FRAME: - printk( " I-FRAME"); - break; - case B_FRAME: - printk( " B-FRAME"); - break; - case P_FRAME: - printk( " P-FRAME"); - break; - } - } - - - pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) | - ( (headr[3] & 0x1F) << 11) ) & 0xffff; - - if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay); - - pic->picture_header_parameter = ( headr[3] & 0xe0 ) | - ((headr[4] & 0x80) >> 3); - - if ( pct == B_FRAME ){ - pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f; - } - if (pr) printk( " pic head param: 0x%x", - pic->picture_header_parameter); - - return pct; -} -#endif - -#if 0 -/* needs 4 byte input */ -static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) -{ - if (pr) printk("GOP header: "); - - pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) | - ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff; - - if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F, - ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F), - ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F)); - - if ( ( headr[3] & 0x40 ) != 0 ){ - pic->closed_gop = 1; - } else { - pic->closed_gop = 0; - } - if (pr) printk("closed: %d", pic->closed_gop); - - if ( ( headr[3] & 0x20 ) != 0 ){ - pic->broken_link = 1; - } else { - pic->broken_link = 0; - } - if (pr) printk(" broken: %d\n", pic->broken_link); - - return 0; -} -#endif - -#if 0 -/* needs 8 byte input */ -static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) -{ - int sw; - int form = -1; - - if (pr) printk("Reading sequence header\n"); - - vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); - - sw = (int)((headr[3]&0xF0) >> 4) ; - - switch( sw ){ - case 1: - if (pr) - printk("Videostream: ASPECT: 1:1"); - vi->aspect_ratio = 100; - break; - case 2: - if (pr) - printk("Videostream: ASPECT: 4:3"); - vi->aspect_ratio = 133; - break; - case 3: - if (pr) - printk("Videostream: ASPECT: 16:9"); - vi->aspect_ratio = 177; - break; - case 4: - if (pr) - printk("Videostream: ASPECT: 2.21:1"); - vi->aspect_ratio = 221; - break; - - case 5 ... 15: - if (pr) - printk("Videostream: ASPECT: reserved"); - vi->aspect_ratio = 0; - break; - - default: - vi->aspect_ratio = 0; - return -1; - } - - if (pr) - printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size); - - sw = (int)(headr[3]&0x0F); - - switch ( sw ) { - case 1: - if (pr) - printk(" FRate: 23.976 fps"); - vi->framerate = 23976; - form = -1; - break; - case 2: - if (pr) - printk(" FRate: 24 fps"); - vi->framerate = 24000; - form = -1; - break; - case 3: - if (pr) - printk(" FRate: 25 fps"); - vi->framerate = 25000; - form = VIDEO_MODE_PAL; - break; - case 4: - if (pr) - printk(" FRate: 29.97 fps"); - vi->framerate = 29970; - form = VIDEO_MODE_NTSC; - break; - case 5: - if (pr) - printk(" FRate: 30 fps"); - vi->framerate = 30000; - form = VIDEO_MODE_NTSC; - break; - case 6: - if (pr) - printk(" FRate: 50 fps"); - vi->framerate = 50000; - form = VIDEO_MODE_PAL; - break; - case 7: - if (pr) - printk(" FRate: 60 fps"); - vi->framerate = 60000; - form = VIDEO_MODE_NTSC; - break; - } - - vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03); - - vi->vbv_buffer_size - = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5); - - if (pr){ - printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000); - printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size)); - printk("\n"); - } - - vi->video_format = form; - - return 0; -} -#endif - - -#if 0 -static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - - while (found < 4 && c+4 < count){ - u8 *b; - - b = mbuf+c; - if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 - && b[3] == 0xb3) found = 4; - else { - c++; - } - } - - if (! found) return -1; - c += 4; - if (c+12 >= count) return -1; - headr = mbuf+c; - if (read_sequence_header(headr, vi, pr) < 0) return -1; - vi->off = c-4; - return 0; -} -#endif - - -#if 0 -static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - int fr = 0; - - while (found < 2 && c < count){ - u8 b[2]; - memcpy( b, mbuf+c, 2); - - if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) - found = 2; - else { - c++; - } - } - - if (!found) return -1; - - if (c+3 >= count) return -1; - headr = mbuf+c; - - ai->layer = (headr[1] & 0x06) >> 1; - - if (pr) - printk("Audiostream: Layer: %d", 4-ai->layer); - - - ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; - - if (pr){ - if (ai->bit_rate == 0) - printk(" Bit rate: free"); - else if (ai->bit_rate == 0xf) - printk(" BRate: reserved"); - else - printk(" BRate: %d kb/s", ai->bit_rate/1000); - } - - fr = (headr[2] & 0x0c ) >> 2; - ai->frequency = freq[fr]*100; - if (pr){ - if (ai->frequency == 3) - printk(" Freq: reserved\n"); - else - printk(" Freq: %d kHz\n",ai->frequency); - - } - ai->off = c; - return 0; -} -#endif - - -int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - u8 frame = 0; - int fr = 0; - - while ( !found && c < count){ - u8 *b = mbuf+c; - - if ( b[0] == 0x0b && b[1] == 0x77 ) - found = 1; - else { - c++; - } - } - - if (!found) return -1; - if (pr) - printk("Audiostream: AC3"); - - ai->off = c; - if (c+5 >= count) return -1; - - ai->layer = 0; // 0 for AC3 - headr = mbuf+c+2; - - frame = (headr[2]&0x3f); - ai->bit_rate = ac3_bitrates[frame >> 1]*1000; - - if (pr) - printk(" BRate: %d kb/s", (int) ai->bit_rate/1000); - - ai->frequency = (headr[2] & 0xc0 ) >> 6; - fr = (headr[2] & 0xc0 ) >> 6; - ai->frequency = freq[fr]*100; - if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency); - - - ai->framesize = ac3_frames[fr][frame >> 1]; - if ((frame & 1) && (fr == 1)) ai->framesize++; - ai->framesize = ai->framesize << 1; - if (pr) printk (" Framesize %d\n",(int) ai->framesize); - - - return 0; -} -EXPORT_SYMBOL(dvb_filter_get_ac3info); - - -#if 0 -static u8 *skip_pes_header(u8 **bufp) -{ - u8 *inbuf = *bufp; - u8 *buf = inbuf; - u8 *pts = NULL; - int skip = 0; - - static const int mpeg1_skip_table[16] = { - 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff - }; - - - if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ - if (buf[7] & PTS_ONLY) - pts = buf+9; - else pts = NULL; - buf = inbuf + 9 + inbuf[8]; - } else { /* mpeg1 */ - for (buf = inbuf + 6; *buf == 0xff; buf++) - if (buf == inbuf + 6 + 16) { - break; - } - if ((*buf & 0xc0) == 0x40) - buf += 2; - skip = mpeg1_skip_table [*buf >> 4]; - if (skip == 5 || skip == 10) pts = buf; - else pts = NULL; - - buf += mpeg1_skip_table [*buf >> 4]; - } - - *bufp = buf; - return pts; -} -#endif - -#if 0 -static void initialize_quant_matrix( u32 *matrix ) -{ - int i; - - matrix[0] = 0x08101013; - matrix[1] = 0x10131616; - matrix[2] = 0x16161616; - matrix[3] = 0x1a181a1b; - matrix[4] = 0x1b1b1a1a; - matrix[5] = 0x1a1a1b1b; - matrix[6] = 0x1b1d1d1d; - matrix[7] = 0x2222221d; - matrix[8] = 0x1d1d1b1b; - matrix[9] = 0x1d1d2020; - matrix[10] = 0x22222526; - matrix[11] = 0x25232322; - matrix[12] = 0x23262628; - matrix[13] = 0x28283030; - matrix[14] = 0x2e2e3838; - matrix[15] = 0x3a454553; - - for ( i = 16 ; i < 32 ; i++ ) - matrix[i] = 0x10101010; -} -#endif - -#if 0 -static void initialize_mpg_picture(struct mpg_picture *pic) -{ - int i; - - /* set MPEG1 */ - pic->mpeg1_flag = 1; - pic->profile_and_level = 0x4A ; /* MP@LL */ - pic->progressive_sequence = 1; - pic->low_delay = 0; - - pic->sequence_display_extension_flag = 0; - for ( i = 0 ; i < 4 ; i++ ){ - pic->frame_centre_horizontal_offset[i] = 0; - pic->frame_centre_vertical_offset[i] = 0; - } - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - - pic->picture_display_extension_flag[0] = 0; - pic->picture_display_extension_flag[1] = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; -} -#endif - -#if 0 -static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) -{ - int16_t last_h_offset; - int16_t last_v_offset; - - int16_t *p_h_offset; - int16_t *p_v_offset; - - if ( pic->mpeg1_flag ){ - pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE; - pic->top_field_first = 0; - pic->repeat_first_field = 0; - pic->progressive_frame = 1; - pic->picture_coding_parameter = 0x000010; - } - - /* Reset flag */ - pic->picture_display_extension_flag[field_type] = 0; - - last_h_offset = pic->last_frame_centre_horizontal_offset; - last_v_offset = pic->last_frame_centre_vertical_offset; - if ( field_type == FIRST_FIELD ){ - p_h_offset = pic->frame_centre_horizontal_offset; - p_v_offset = pic->frame_centre_vertical_offset; - *p_h_offset = last_h_offset; - *(p_h_offset + 1) = last_h_offset; - *(p_h_offset + 2) = last_h_offset; - *p_v_offset = last_v_offset; - *(p_v_offset + 1) = last_v_offset; - *(p_v_offset + 2) = last_v_offset; - } else { - pic->frame_centre_horizontal_offset[3] = last_h_offset; - pic->frame_centre_vertical_offset[3] = last_v_offset; - } -} -#endif - -#if 0 -static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) -{ - pic->picture_header = 0; - pic->sequence_header_data - = ( INIT_HORIZONTAL_SIZE << 20 ) - | ( INIT_VERTICAL_SIZE << 8 ) - | ( INIT_ASPECT_RATIO << 4 ) - | ( INIT_FRAME_RATE ); - pic->mpeg1_flag = 0; - pic->vinfo.horizontal_size - = INIT_DISP_HORIZONTAL_SIZE; - pic->vinfo.vertical_size - = INIT_DISP_VERTICAL_SIZE; - pic->picture_display_extension_flag[field_type] - = 0; - pic->pts_flag[field_type] = 0; - - pic->sequence_gop_header = 0; - pic->picture_header = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; - pic->sequence_display_extension_flag = 0; - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - pic->channel = chan; -} -#endif - -void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, - dvb_filter_pes2ts_cb_t *cb, void *priv) -{ - unsigned char *buf=p2ts->buf; - - buf[0]=0x47; - buf[1]=(pid>>8); - buf[2]=pid&0xff; - p2ts->cc=0; - p2ts->cb=cb; - p2ts->priv=priv; -} -EXPORT_SYMBOL(dvb_filter_pes2ts_init); - -int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, - int len, int payload_start) -{ - unsigned char *buf=p2ts->buf; - int ret=0, rest; - - //len=6+((pes[4]<<8)|pes[5]); - - if (payload_start) - buf[1]|=0x40; - else - buf[1]&=~0x40; - while (len>=184) { - buf[3]=0x10|((p2ts->cc++)&0x0f); - memcpy(buf+4, pes, 184); - if ((ret=p2ts->cb(p2ts->priv, buf))) - return ret; - len-=184; pes+=184; - buf[1]&=~0x40; - } - if (!len) - return 0; - buf[3]=0x30|((p2ts->cc++)&0x0f); - rest=183-len; - if (rest) { - buf[5]=0x00; - if (rest-1) - memset(buf+6, 0xff, rest-1); - } - buf[4]=rest; - memcpy(buf+5+rest, pes, len); - return p2ts->cb(p2ts->priv, buf); -} -EXPORT_SYMBOL(dvb_filter_pes2ts); diff --git a/drivers/media/dvb-core/dvb_filter.h b/drivers/media/dvb-core/dvb_filter.h deleted file mode 100644 index 375e3be184b1..000000000000 --- a/drivers/media/dvb-core/dvb_filter.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * dvb_filter.h - * - * Copyright (C) 2003 Convergence GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DVB_FILTER_H_ -#define _DVB_FILTER_H_ - -#include - -#include "demux.h" - -typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); - -struct dvb_filter_pes2ts { - unsigned char buf[188]; - unsigned char cc; - dvb_filter_pes2ts_cb_t *cb; - void *priv; -}; - -void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, - dvb_filter_pes2ts_cb_t *cb, void *priv); - -int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, - int len, int payload_start); - - -#define PROG_STREAM_MAP 0xBC -#define PRIVATE_STREAM1 0xBD -#define PADDING_STREAM 0xBE -#define PRIVATE_STREAM2 0xBF -#define AUDIO_STREAM_S 0xC0 -#define AUDIO_STREAM_E 0xDF -#define VIDEO_STREAM_S 0xE0 -#define VIDEO_STREAM_E 0xEF -#define ECM_STREAM 0xF0 -#define EMM_STREAM 0xF1 -#define DSM_CC_STREAM 0xF2 -#define ISO13522_STREAM 0xF3 -#define PROG_STREAM_DIR 0xFF - -#define DVB_PICTURE_START 0x00 -#define DVB_USER_START 0xb2 -#define DVB_SEQUENCE_HEADER 0xb3 -#define DVB_SEQUENCE_ERROR 0xb4 -#define DVB_EXTENSION_START 0xb5 -#define DVB_SEQUENCE_END 0xb7 -#define DVB_GOP_START 0xb8 -#define DVB_EXCEPT_SLICE 0xb0 - -#define SEQUENCE_EXTENSION 0x01 -#define SEQUENCE_DISPLAY_EXTENSION 0x02 -#define PICTURE_CODING_EXTENSION 0x08 -#define QUANT_MATRIX_EXTENSION 0x03 -#define PICTURE_DISPLAY_EXTENSION 0x07 - -#define I_FRAME 0x01 -#define B_FRAME 0x02 -#define P_FRAME 0x03 - -/* Initialize sequence_data */ -#define INIT_HORIZONTAL_SIZE 720 -#define INIT_VERTICAL_SIZE 576 -#define INIT_ASPECT_RATIO 0x02 -#define INIT_FRAME_RATE 0x03 -#define INIT_DISP_HORIZONTAL_SIZE 540 -#define INIT_DISP_VERTICAL_SIZE 576 - - -//flags2 -#define PTS_DTS_FLAGS 0xC0 -#define ESCR_FLAG 0x20 -#define ES_RATE_FLAG 0x10 -#define DSM_TRICK_FLAG 0x08 -#define ADD_CPY_FLAG 0x04 -#define PES_CRC_FLAG 0x02 -#define PES_EXT_FLAG 0x01 - -//pts_dts flags -#define PTS_ONLY 0x80 -#define PTS_DTS 0xC0 - -#define TS_SIZE 188 -#define TRANS_ERROR 0x80 -#define PAY_START 0x40 -#define TRANS_PRIO 0x20 -#define PID_MASK_HI 0x1F -//flags -#define TRANS_SCRMBL1 0x80 -#define TRANS_SCRMBL2 0x40 -#define ADAPT_FIELD 0x20 -#define PAYLOAD 0x10 -#define COUNT_MASK 0x0F - -// adaptation flags -#define DISCON_IND 0x80 -#define RAND_ACC_IND 0x40 -#define ES_PRI_IND 0x20 -#define PCR_FLAG 0x10 -#define OPCR_FLAG 0x08 -#define SPLICE_FLAG 0x04 -#define TRANS_PRIV 0x02 -#define ADAP_EXT_FLAG 0x01 - -// adaptation extension flags -#define LTW_FLAG 0x80 -#define PIECE_RATE 0x40 -#define SEAM_SPLICE 0x20 - - -#define MAX_PLENGTH 0xFFFF -#define MMAX_PLENGTH (256*MAX_PLENGTH) - -#ifndef IPACKS -#define IPACKS 2048 -#endif - -struct ipack { - int size; - int found; - u8 *buf; - u8 cid; - u32 plength; - u8 plen[2]; - u8 flag1; - u8 flag2; - u8 hlength; - u8 pts[5]; - u16 *pid; - int mpeg; - u8 check; - int which; - int done; - void *data; - void (*func)(u8 *buf, int size, void *priv); - int count; - int repack_subids; -}; - -struct dvb_video_info { - u32 horizontal_size; - u32 vertical_size; - u32 aspect_ratio; - u32 framerate; - u32 video_format; - u32 bit_rate; - u32 comp_bit_rate; - u32 vbv_buffer_size; - s16 vbv_delay; - u32 CSPF; - u32 off; -}; - -#define OFF_SIZE 4 -#define FIRST_FIELD 0 -#define SECOND_FIELD 1 -#define VIDEO_FRAME_PICTURE 0x03 - -struct mpg_picture { - int channel; - struct dvb_video_info vinfo; - u32 *sequence_gop_header; - u32 *picture_header; - s32 time_code; - int low_delay; - int closed_gop; - int broken_link; - int sequence_header_flag; - int gop_flag; - int sequence_end_flag; - - u8 profile_and_level; - s32 picture_coding_parameter; - u32 matrix[32]; - s8 matrix_change_flag; - - u8 picture_header_parameter; - /* bit 0 - 2: bwd f code - bit 3 : fpb vector - bit 4 - 6: fwd f code - bit 7 : fpf vector */ - - int mpeg1_flag; - int progressive_sequence; - int sequence_display_extension_flag; - u32 sequence_header_data; - s16 last_frame_centre_horizontal_offset; - s16 last_frame_centre_vertical_offset; - - u32 pts[2]; /* [0] 1st field, [1] 2nd field */ - int top_field_first; - int repeat_first_field; - int progressive_frame; - int bank; - int forward_bank; - int backward_bank; - int compress; - s16 frame_centre_horizontal_offset[OFF_SIZE]; - /* [0-2] 1st field, [3] 2nd field */ - s16 frame_centre_vertical_offset[OFF_SIZE]; - /* [0-2] 1st field, [3] 2nd field */ - s16 temporal_reference[2]; - /* [0] 1st field, [1] 2nd field */ - - s8 picture_coding_type[2]; - /* [0] 1st field, [1] 2nd field */ - s8 picture_structure[2]; - /* [0] 1st field, [1] 2nd field */ - s8 picture_display_extension_flag[2]; - /* [0] 1st field, [1] 2nd field */ - /* picture_display_extenion() 0:no 1:exit*/ - s8 pts_flag[2]; - /* [0] 1st field, [1] 2nd field */ -}; - -struct dvb_audio_info { - int layer; - u32 bit_rate; - u32 frequency; - u32 mode; - u32 mode_extension ; - u32 emphasis; - u32 framesize; - u32 off; -}; - -int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr); - - -#endif diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile index 49f71b1eaf14..3cf617737f7c 100644 --- a/drivers/media/pci/ttpci/Makefile +++ b/drivers/media/pci/ttpci/Makefile @@ -3,7 +3,7 @@ # and the AV7110 DVB device driver # -dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o +dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o dvb_filter.o ifdef CONFIG_DVB_AV7110_IR dvb-ttpci-objs += av7110_ir.o diff --git a/drivers/media/pci/ttpci/dvb_filter.c b/drivers/media/pci/ttpci/dvb_filter.c new file mode 100644 index 000000000000..6395812ed1f1 --- /dev/null +++ b/drivers/media/pci/ttpci/dvb_filter.c @@ -0,0 +1,600 @@ +#include +#include +#include +#include "dvb_filter.h" + +#if 0 +static unsigned int bitrates[3][16] = +{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, + {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, + {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; +#endif + +static u32 freq[4] = {480, 441, 320, 0}; + +static unsigned int ac3_bitrates[32] = + {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, + 0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static u32 ac3_frames[3][32] = + {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, + 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, + 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, + 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + + + +#if 0 +static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, + void (*pes_write)(u8 *buf, int count, void *data), + void *priv) +{ + dvb_filter_ipack_init(pa, IPACKS, pes_write); + dvb_filter_ipack_init(pv, IPACKS, pes_write); + pa->pid = pida; + pv->pid = pidv; + pa->data = priv; + pv->data = priv; +} +#endif + +#if 0 +static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) +{ + u8 off = 0; + + if (!buf || !p ){ + printk("NULL POINTER IDIOT\n"); + return; + } + if (buf[1]&PAY_START) { + if (p->plength == MMAX_PLENGTH-6 && p->found>6){ + p->plength = p->found-6; + p->found = 0; + send_ipack(p); + dvb_filter_ipack_reset(p); + } + } + if (buf[3] & ADAPT_FIELD) { // adaptation field? + off = buf[4] + 1; + if (off+4 > 187) return; + } + dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p); +} +#endif + +#if 0 +/* needs 5 byte input, returns picture coding type*/ +static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) +{ + u8 pct; + + if (pr) printk( "Pic header: "); + pic->temporal_reference[field] = (( headr[0] << 2 ) | + (headr[1] & 0x03) )& 0x03ff; + if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]); + + pct = ( headr[1] >> 2 ) & 0x07; + pic->picture_coding_type[field] = pct; + if (pr) { + switch(pct){ + case I_FRAME: + printk( " I-FRAME"); + break; + case B_FRAME: + printk( " B-FRAME"); + break; + case P_FRAME: + printk( " P-FRAME"); + break; + } + } + + + pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) | + ( (headr[3] & 0x1F) << 11) ) & 0xffff; + + if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay); + + pic->picture_header_parameter = ( headr[3] & 0xe0 ) | + ((headr[4] & 0x80) >> 3); + + if ( pct == B_FRAME ){ + pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f; + } + if (pr) printk( " pic head param: 0x%x", + pic->picture_header_parameter); + + return pct; +} +#endif + +#if 0 +/* needs 4 byte input */ +static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) +{ + if (pr) printk("GOP header: "); + + pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) | + ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff; + + if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F, + ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F), + ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F)); + + if ( ( headr[3] & 0x40 ) != 0 ){ + pic->closed_gop = 1; + } else { + pic->closed_gop = 0; + } + if (pr) printk("closed: %d", pic->closed_gop); + + if ( ( headr[3] & 0x20 ) != 0 ){ + pic->broken_link = 1; + } else { + pic->broken_link = 0; + } + if (pr) printk(" broken: %d\n", pic->broken_link); + + return 0; +} +#endif + +#if 0 +/* needs 8 byte input */ +static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) +{ + int sw; + int form = -1; + + if (pr) printk("Reading sequence header\n"); + + vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); + vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); + + sw = (int)((headr[3]&0xF0) >> 4) ; + + switch( sw ){ + case 1: + if (pr) + printk("Videostream: ASPECT: 1:1"); + vi->aspect_ratio = 100; + break; + case 2: + if (pr) + printk("Videostream: ASPECT: 4:3"); + vi->aspect_ratio = 133; + break; + case 3: + if (pr) + printk("Videostream: ASPECT: 16:9"); + vi->aspect_ratio = 177; + break; + case 4: + if (pr) + printk("Videostream: ASPECT: 2.21:1"); + vi->aspect_ratio = 221; + break; + + case 5 ... 15: + if (pr) + printk("Videostream: ASPECT: reserved"); + vi->aspect_ratio = 0; + break; + + default: + vi->aspect_ratio = 0; + return -1; + } + + if (pr) + printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size); + + sw = (int)(headr[3]&0x0F); + + switch ( sw ) { + case 1: + if (pr) + printk(" FRate: 23.976 fps"); + vi->framerate = 23976; + form = -1; + break; + case 2: + if (pr) + printk(" FRate: 24 fps"); + vi->framerate = 24000; + form = -1; + break; + case 3: + if (pr) + printk(" FRate: 25 fps"); + vi->framerate = 25000; + form = VIDEO_MODE_PAL; + break; + case 4: + if (pr) + printk(" FRate: 29.97 fps"); + vi->framerate = 29970; + form = VIDEO_MODE_NTSC; + break; + case 5: + if (pr) + printk(" FRate: 30 fps"); + vi->framerate = 30000; + form = VIDEO_MODE_NTSC; + break; + case 6: + if (pr) + printk(" FRate: 50 fps"); + vi->framerate = 50000; + form = VIDEO_MODE_PAL; + break; + case 7: + if (pr) + printk(" FRate: 60 fps"); + vi->framerate = 60000; + form = VIDEO_MODE_NTSC; + break; + } + + vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03); + + vi->vbv_buffer_size + = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5); + + if (pr){ + printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000); + printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size)); + printk("\n"); + } + + vi->video_format = form; + + return 0; +} +#endif + + +#if 0 +static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) +{ + u8 *headr; + int found = 0; + int c = 0; + + while (found < 4 && c+4 < count){ + u8 *b; + + b = mbuf+c; + if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 + && b[3] == 0xb3) found = 4; + else { + c++; + } + } + + if (! found) return -1; + c += 4; + if (c+12 >= count) return -1; + headr = mbuf+c; + if (read_sequence_header(headr, vi, pr) < 0) return -1; + vi->off = c-4; + return 0; +} +#endif + + +#if 0 +static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) +{ + u8 *headr; + int found = 0; + int c = 0; + int fr = 0; + + while (found < 2 && c < count){ + u8 b[2]; + memcpy( b, mbuf+c, 2); + + if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) + found = 2; + else { + c++; + } + } + + if (!found) return -1; + + if (c+3 >= count) return -1; + headr = mbuf+c; + + ai->layer = (headr[1] & 0x06) >> 1; + + if (pr) + printk("Audiostream: Layer: %d", 4-ai->layer); + + + ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; + + if (pr){ + if (ai->bit_rate == 0) + printk(" Bit rate: free"); + else if (ai->bit_rate == 0xf) + printk(" BRate: reserved"); + else + printk(" BRate: %d kb/s", ai->bit_rate/1000); + } + + fr = (headr[2] & 0x0c ) >> 2; + ai->frequency = freq[fr]*100; + if (pr){ + if (ai->frequency == 3) + printk(" Freq: reserved\n"); + else + printk(" Freq: %d kHz\n",ai->frequency); + + } + ai->off = c; + return 0; +} +#endif + + +int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) +{ + u8 *headr; + int found = 0; + int c = 0; + u8 frame = 0; + int fr = 0; + + while ( !found && c < count){ + u8 *b = mbuf+c; + + if ( b[0] == 0x0b && b[1] == 0x77 ) + found = 1; + else { + c++; + } + } + + if (!found) return -1; + if (pr) + printk("Audiostream: AC3"); + + ai->off = c; + if (c+5 >= count) return -1; + + ai->layer = 0; // 0 for AC3 + headr = mbuf+c+2; + + frame = (headr[2]&0x3f); + ai->bit_rate = ac3_bitrates[frame >> 1]*1000; + + if (pr) + printk(" BRate: %d kb/s", (int) ai->bit_rate/1000); + + ai->frequency = (headr[2] & 0xc0 ) >> 6; + fr = (headr[2] & 0xc0 ) >> 6; + ai->frequency = freq[fr]*100; + if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency); + + + ai->framesize = ac3_frames[fr][frame >> 1]; + if ((frame & 1) && (fr == 1)) ai->framesize++; + ai->framesize = ai->framesize << 1; + if (pr) printk (" Framesize %d\n",(int) ai->framesize); + + + return 0; +} + + +#if 0 +static u8 *skip_pes_header(u8 **bufp) +{ + u8 *inbuf = *bufp; + u8 *buf = inbuf; + u8 *pts = NULL; + int skip = 0; + + static const int mpeg1_skip_table[16] = { + 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff + }; + + + if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ + if (buf[7] & PTS_ONLY) + pts = buf+9; + else pts = NULL; + buf = inbuf + 9 + inbuf[8]; + } else { /* mpeg1 */ + for (buf = inbuf + 6; *buf == 0xff; buf++) + if (buf == inbuf + 6 + 16) { + break; + } + if ((*buf & 0xc0) == 0x40) + buf += 2; + skip = mpeg1_skip_table [*buf >> 4]; + if (skip == 5 || skip == 10) pts = buf; + else pts = NULL; + + buf += mpeg1_skip_table [*buf >> 4]; + } + + *bufp = buf; + return pts; +} +#endif + +#if 0 +static void initialize_quant_matrix( u32 *matrix ) +{ + int i; + + matrix[0] = 0x08101013; + matrix[1] = 0x10131616; + matrix[2] = 0x16161616; + matrix[3] = 0x1a181a1b; + matrix[4] = 0x1b1b1a1a; + matrix[5] = 0x1a1a1b1b; + matrix[6] = 0x1b1d1d1d; + matrix[7] = 0x2222221d; + matrix[8] = 0x1d1d1b1b; + matrix[9] = 0x1d1d2020; + matrix[10] = 0x22222526; + matrix[11] = 0x25232322; + matrix[12] = 0x23262628; + matrix[13] = 0x28283030; + matrix[14] = 0x2e2e3838; + matrix[15] = 0x3a454553; + + for ( i = 16 ; i < 32 ; i++ ) + matrix[i] = 0x10101010; +} +#endif + +#if 0 +static void initialize_mpg_picture(struct mpg_picture *pic) +{ + int i; + + /* set MPEG1 */ + pic->mpeg1_flag = 1; + pic->profile_and_level = 0x4A ; /* MP@LL */ + pic->progressive_sequence = 1; + pic->low_delay = 0; + + pic->sequence_display_extension_flag = 0; + for ( i = 0 ; i < 4 ; i++ ){ + pic->frame_centre_horizontal_offset[i] = 0; + pic->frame_centre_vertical_offset[i] = 0; + } + pic->last_frame_centre_horizontal_offset = 0; + pic->last_frame_centre_vertical_offset = 0; + + pic->picture_display_extension_flag[0] = 0; + pic->picture_display_extension_flag[1] = 0; + pic->sequence_header_flag = 0; + pic->gop_flag = 0; + pic->sequence_end_flag = 0; +} +#endif + +#if 0 +static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) +{ + int16_t last_h_offset; + int16_t last_v_offset; + + int16_t *p_h_offset; + int16_t *p_v_offset; + + if ( pic->mpeg1_flag ){ + pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE; + pic->top_field_first = 0; + pic->repeat_first_field = 0; + pic->progressive_frame = 1; + pic->picture_coding_parameter = 0x000010; + } + + /* Reset flag */ + pic->picture_display_extension_flag[field_type] = 0; + + last_h_offset = pic->last_frame_centre_horizontal_offset; + last_v_offset = pic->last_frame_centre_vertical_offset; + if ( field_type == FIRST_FIELD ){ + p_h_offset = pic->frame_centre_horizontal_offset; + p_v_offset = pic->frame_centre_vertical_offset; + *p_h_offset = last_h_offset; + *(p_h_offset + 1) = last_h_offset; + *(p_h_offset + 2) = last_h_offset; + *p_v_offset = last_v_offset; + *(p_v_offset + 1) = last_v_offset; + *(p_v_offset + 2) = last_v_offset; + } else { + pic->frame_centre_horizontal_offset[3] = last_h_offset; + pic->frame_centre_vertical_offset[3] = last_v_offset; + } +} +#endif + +#if 0 +static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) +{ + pic->picture_header = 0; + pic->sequence_header_data + = ( INIT_HORIZONTAL_SIZE << 20 ) + | ( INIT_VERTICAL_SIZE << 8 ) + | ( INIT_ASPECT_RATIO << 4 ) + | ( INIT_FRAME_RATE ); + pic->mpeg1_flag = 0; + pic->vinfo.horizontal_size + = INIT_DISP_HORIZONTAL_SIZE; + pic->vinfo.vertical_size + = INIT_DISP_VERTICAL_SIZE; + pic->picture_display_extension_flag[field_type] + = 0; + pic->pts_flag[field_type] = 0; + + pic->sequence_gop_header = 0; + pic->picture_header = 0; + pic->sequence_header_flag = 0; + pic->gop_flag = 0; + pic->sequence_end_flag = 0; + pic->sequence_display_extension_flag = 0; + pic->last_frame_centre_horizontal_offset = 0; + pic->last_frame_centre_vertical_offset = 0; + pic->channel = chan; +} +#endif + +void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, + dvb_filter_pes2ts_cb_t *cb, void *priv) +{ + unsigned char *buf=p2ts->buf; + + buf[0]=0x47; + buf[1]=(pid>>8); + buf[2]=pid&0xff; + p2ts->cc=0; + p2ts->cb=cb; + p2ts->priv=priv; +} + +int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, + int len, int payload_start) +{ + unsigned char *buf=p2ts->buf; + int ret=0, rest; + + //len=6+((pes[4]<<8)|pes[5]); + + if (payload_start) + buf[1]|=0x40; + else + buf[1]&=~0x40; + while (len>=184) { + buf[3]=0x10|((p2ts->cc++)&0x0f); + memcpy(buf+4, pes, 184); + if ((ret=p2ts->cb(p2ts->priv, buf))) + return ret; + len-=184; pes+=184; + buf[1]&=~0x40; + } + if (!len) + return 0; + buf[3]=0x30|((p2ts->cc++)&0x0f); + rest=183-len; + if (rest) { + buf[5]=0x00; + if (rest-1) + memset(buf+6, 0xff, rest-1); + } + buf[4]=rest; + memcpy(buf+5+rest, pes, len); + return p2ts->cb(p2ts->priv, buf); +} diff --git a/drivers/media/pci/ttpci/dvb_filter.h b/drivers/media/pci/ttpci/dvb_filter.h new file mode 100644 index 000000000000..375e3be184b1 --- /dev/null +++ b/drivers/media/pci/ttpci/dvb_filter.h @@ -0,0 +1,246 @@ +/* + * dvb_filter.h + * + * Copyright (C) 2003 Convergence GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DVB_FILTER_H_ +#define _DVB_FILTER_H_ + +#include + +#include "demux.h" + +typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); + +struct dvb_filter_pes2ts { + unsigned char buf[188]; + unsigned char cc; + dvb_filter_pes2ts_cb_t *cb; + void *priv; +}; + +void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, + dvb_filter_pes2ts_cb_t *cb, void *priv); + +int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, + int len, int payload_start); + + +#define PROG_STREAM_MAP 0xBC +#define PRIVATE_STREAM1 0xBD +#define PADDING_STREAM 0xBE +#define PRIVATE_STREAM2 0xBF +#define AUDIO_STREAM_S 0xC0 +#define AUDIO_STREAM_E 0xDF +#define VIDEO_STREAM_S 0xE0 +#define VIDEO_STREAM_E 0xEF +#define ECM_STREAM 0xF0 +#define EMM_STREAM 0xF1 +#define DSM_CC_STREAM 0xF2 +#define ISO13522_STREAM 0xF3 +#define PROG_STREAM_DIR 0xFF + +#define DVB_PICTURE_START 0x00 +#define DVB_USER_START 0xb2 +#define DVB_SEQUENCE_HEADER 0xb3 +#define DVB_SEQUENCE_ERROR 0xb4 +#define DVB_EXTENSION_START 0xb5 +#define DVB_SEQUENCE_END 0xb7 +#define DVB_GOP_START 0xb8 +#define DVB_EXCEPT_SLICE 0xb0 + +#define SEQUENCE_EXTENSION 0x01 +#define SEQUENCE_DISPLAY_EXTENSION 0x02 +#define PICTURE_CODING_EXTENSION 0x08 +#define QUANT_MATRIX_EXTENSION 0x03 +#define PICTURE_DISPLAY_EXTENSION 0x07 + +#define I_FRAME 0x01 +#define B_FRAME 0x02 +#define P_FRAME 0x03 + +/* Initialize sequence_data */ +#define INIT_HORIZONTAL_SIZE 720 +#define INIT_VERTICAL_SIZE 576 +#define INIT_ASPECT_RATIO 0x02 +#define INIT_FRAME_RATE 0x03 +#define INIT_DISP_HORIZONTAL_SIZE 540 +#define INIT_DISP_VERTICAL_SIZE 576 + + +//flags2 +#define PTS_DTS_FLAGS 0xC0 +#define ESCR_FLAG 0x20 +#define ES_RATE_FLAG 0x10 +#define DSM_TRICK_FLAG 0x08 +#define ADD_CPY_FLAG 0x04 +#define PES_CRC_FLAG 0x02 +#define PES_EXT_FLAG 0x01 + +//pts_dts flags +#define PTS_ONLY 0x80 +#define PTS_DTS 0xC0 + +#define TS_SIZE 188 +#define TRANS_ERROR 0x80 +#define PAY_START 0x40 +#define TRANS_PRIO 0x20 +#define PID_MASK_HI 0x1F +//flags +#define TRANS_SCRMBL1 0x80 +#define TRANS_SCRMBL2 0x40 +#define ADAPT_FIELD 0x20 +#define PAYLOAD 0x10 +#define COUNT_MASK 0x0F + +// adaptation flags +#define DISCON_IND 0x80 +#define RAND_ACC_IND 0x40 +#define ES_PRI_IND 0x20 +#define PCR_FLAG 0x10 +#define OPCR_FLAG 0x08 +#define SPLICE_FLAG 0x04 +#define TRANS_PRIV 0x02 +#define ADAP_EXT_FLAG 0x01 + +// adaptation extension flags +#define LTW_FLAG 0x80 +#define PIECE_RATE 0x40 +#define SEAM_SPLICE 0x20 + + +#define MAX_PLENGTH 0xFFFF +#define MMAX_PLENGTH (256*MAX_PLENGTH) + +#ifndef IPACKS +#define IPACKS 2048 +#endif + +struct ipack { + int size; + int found; + u8 *buf; + u8 cid; + u32 plength; + u8 plen[2]; + u8 flag1; + u8 flag2; + u8 hlength; + u8 pts[5]; + u16 *pid; + int mpeg; + u8 check; + int which; + int done; + void *data; + void (*func)(u8 *buf, int size, void *priv); + int count; + int repack_subids; +}; + +struct dvb_video_info { + u32 horizontal_size; + u32 vertical_size; + u32 aspect_ratio; + u32 framerate; + u32 video_format; + u32 bit_rate; + u32 comp_bit_rate; + u32 vbv_buffer_size; + s16 vbv_delay; + u32 CSPF; + u32 off; +}; + +#define OFF_SIZE 4 +#define FIRST_FIELD 0 +#define SECOND_FIELD 1 +#define VIDEO_FRAME_PICTURE 0x03 + +struct mpg_picture { + int channel; + struct dvb_video_info vinfo; + u32 *sequence_gop_header; + u32 *picture_header; + s32 time_code; + int low_delay; + int closed_gop; + int broken_link; + int sequence_header_flag; + int gop_flag; + int sequence_end_flag; + + u8 profile_and_level; + s32 picture_coding_parameter; + u32 matrix[32]; + s8 matrix_change_flag; + + u8 picture_header_parameter; + /* bit 0 - 2: bwd f code + bit 3 : fpb vector + bit 4 - 6: fwd f code + bit 7 : fpf vector */ + + int mpeg1_flag; + int progressive_sequence; + int sequence_display_extension_flag; + u32 sequence_header_data; + s16 last_frame_centre_horizontal_offset; + s16 last_frame_centre_vertical_offset; + + u32 pts[2]; /* [0] 1st field, [1] 2nd field */ + int top_field_first; + int repeat_first_field; + int progressive_frame; + int bank; + int forward_bank; + int backward_bank; + int compress; + s16 frame_centre_horizontal_offset[OFF_SIZE]; + /* [0-2] 1st field, [3] 2nd field */ + s16 frame_centre_vertical_offset[OFF_SIZE]; + /* [0-2] 1st field, [3] 2nd field */ + s16 temporal_reference[2]; + /* [0] 1st field, [1] 2nd field */ + + s8 picture_coding_type[2]; + /* [0] 1st field, [1] 2nd field */ + s8 picture_structure[2]; + /* [0] 1st field, [1] 2nd field */ + s8 picture_display_extension_flag[2]; + /* [0] 1st field, [1] 2nd field */ + /* picture_display_extenion() 0:no 1:exit*/ + s8 pts_flag[2]; + /* [0] 1st field, [1] 2nd field */ +}; + +struct dvb_audio_info { + int layer; + u32 bit_rate; + u32 frequency; + u32 mode; + u32 mode_extension ; + u32 emphasis; + u32 framesize; + u32 off; +}; + +int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr); + + +#endif diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 4e7671a3a1e4..35d5003ff809 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -36,7 +36,6 @@ #include "dmxdev.h" #include "dvb_demux.h" -#include "dvb_filter.h" #include "dvb_frontend.h" #include "dvb_net.h" #include "ttusbdecfe.h" @@ -92,6 +91,15 @@ enum ttusb_dec_interface { TTUSB_DEC_INTERFACE_OUT }; +typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); + +struct dvb_filter_pes2ts { + unsigned char buf[188]; + unsigned char cc; + dvb_filter_pes2ts_cb_t *cb; + void *priv; +}; + struct ttusb_dec { enum ttusb_dec_model model; char *model_name; @@ -201,6 +209,54 @@ static u16 rc_keys[] = { KEY_RADIO }; +static void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, + unsigned short pid, + dvb_filter_pes2ts_cb_t *cb, void *priv) +{ + unsigned char *buf=p2ts->buf; + + buf[0]=0x47; + buf[1]=(pid>>8); + buf[2]=pid&0xff; + p2ts->cc=0; + p2ts->cb=cb; + p2ts->priv=priv; +} + +static int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, + unsigned char *pes, int len, int payload_start) +{ + unsigned char *buf=p2ts->buf; + int ret=0, rest; + + //len=6+((pes[4]<<8)|pes[5]); + + if (payload_start) + buf[1]|=0x40; + else + buf[1]&=~0x40; + while (len>=184) { + buf[3]=0x10|((p2ts->cc++)&0x0f); + memcpy(buf+4, pes, 184); + if ((ret=p2ts->cb(p2ts->priv, buf))) + return ret; + len-=184; pes+=184; + buf[1]&=~0x40; + } + if (!len) + return 0; + buf[3]=0x30|((p2ts->cc++)&0x0f); + rest=183-len; + if (rest) { + buf[5]=0x00; + if (rest-1) + memset(buf+6, 0xff, rest-1); + } + buf[4]=rest; + memcpy(buf+5+rest, pes, len); + return p2ts->cb(p2ts->priv, buf); +} + static void ttusb_dec_set_model(struct ttusb_dec *dec, enum ttusb_dec_model model); -- cgit v1.2.3 From 54e0443b47bba8a4700273abc261c73ec1d358f7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:03:48 -0300 Subject: [media] dvb_filter: get rid of dead code There are lots of stuff here commented out for a really long time. Get rid of them. If one wants it again, it could always use git log. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/dvb_filter.c | 485 ----------------------------------- 1 file changed, 485 deletions(-) diff --git a/drivers/media/pci/ttpci/dvb_filter.c b/drivers/media/pci/ttpci/dvb_filter.c index 6395812ed1f1..227f93e2ef10 100644 --- a/drivers/media/pci/ttpci/dvb_filter.c +++ b/drivers/media/pci/ttpci/dvb_filter.c @@ -3,13 +3,6 @@ #include #include "dvb_filter.h" -#if 0 -static unsigned int bitrates[3][16] = -{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, - {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, - {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; -#endif - static u32 freq[4] = {480, 441, 320, 0}; static unsigned int ac3_bitrates[32] = @@ -25,323 +18,6 @@ static u32 ac3_frames[3][32] = 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -#if 0 -static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, - void (*pes_write)(u8 *buf, int count, void *data), - void *priv) -{ - dvb_filter_ipack_init(pa, IPACKS, pes_write); - dvb_filter_ipack_init(pv, IPACKS, pes_write); - pa->pid = pida; - pv->pid = pidv; - pa->data = priv; - pv->data = priv; -} -#endif - -#if 0 -static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) -{ - u8 off = 0; - - if (!buf || !p ){ - printk("NULL POINTER IDIOT\n"); - return; - } - if (buf[1]&PAY_START) { - if (p->plength == MMAX_PLENGTH-6 && p->found>6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - dvb_filter_ipack_reset(p); - } - } - if (buf[3] & ADAPT_FIELD) { // adaptation field? - off = buf[4] + 1; - if (off+4 > 187) return; - } - dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p); -} -#endif - -#if 0 -/* needs 5 byte input, returns picture coding type*/ -static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) -{ - u8 pct; - - if (pr) printk( "Pic header: "); - pic->temporal_reference[field] = (( headr[0] << 2 ) | - (headr[1] & 0x03) )& 0x03ff; - if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]); - - pct = ( headr[1] >> 2 ) & 0x07; - pic->picture_coding_type[field] = pct; - if (pr) { - switch(pct){ - case I_FRAME: - printk( " I-FRAME"); - break; - case B_FRAME: - printk( " B-FRAME"); - break; - case P_FRAME: - printk( " P-FRAME"); - break; - } - } - - - pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) | - ( (headr[3] & 0x1F) << 11) ) & 0xffff; - - if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay); - - pic->picture_header_parameter = ( headr[3] & 0xe0 ) | - ((headr[4] & 0x80) >> 3); - - if ( pct == B_FRAME ){ - pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f; - } - if (pr) printk( " pic head param: 0x%x", - pic->picture_header_parameter); - - return pct; -} -#endif - -#if 0 -/* needs 4 byte input */ -static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) -{ - if (pr) printk("GOP header: "); - - pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) | - ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff; - - if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F, - ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F), - ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F)); - - if ( ( headr[3] & 0x40 ) != 0 ){ - pic->closed_gop = 1; - } else { - pic->closed_gop = 0; - } - if (pr) printk("closed: %d", pic->closed_gop); - - if ( ( headr[3] & 0x20 ) != 0 ){ - pic->broken_link = 1; - } else { - pic->broken_link = 0; - } - if (pr) printk(" broken: %d\n", pic->broken_link); - - return 0; -} -#endif - -#if 0 -/* needs 8 byte input */ -static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) -{ - int sw; - int form = -1; - - if (pr) printk("Reading sequence header\n"); - - vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); - - sw = (int)((headr[3]&0xF0) >> 4) ; - - switch( sw ){ - case 1: - if (pr) - printk("Videostream: ASPECT: 1:1"); - vi->aspect_ratio = 100; - break; - case 2: - if (pr) - printk("Videostream: ASPECT: 4:3"); - vi->aspect_ratio = 133; - break; - case 3: - if (pr) - printk("Videostream: ASPECT: 16:9"); - vi->aspect_ratio = 177; - break; - case 4: - if (pr) - printk("Videostream: ASPECT: 2.21:1"); - vi->aspect_ratio = 221; - break; - - case 5 ... 15: - if (pr) - printk("Videostream: ASPECT: reserved"); - vi->aspect_ratio = 0; - break; - - default: - vi->aspect_ratio = 0; - return -1; - } - - if (pr) - printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size); - - sw = (int)(headr[3]&0x0F); - - switch ( sw ) { - case 1: - if (pr) - printk(" FRate: 23.976 fps"); - vi->framerate = 23976; - form = -1; - break; - case 2: - if (pr) - printk(" FRate: 24 fps"); - vi->framerate = 24000; - form = -1; - break; - case 3: - if (pr) - printk(" FRate: 25 fps"); - vi->framerate = 25000; - form = VIDEO_MODE_PAL; - break; - case 4: - if (pr) - printk(" FRate: 29.97 fps"); - vi->framerate = 29970; - form = VIDEO_MODE_NTSC; - break; - case 5: - if (pr) - printk(" FRate: 30 fps"); - vi->framerate = 30000; - form = VIDEO_MODE_NTSC; - break; - case 6: - if (pr) - printk(" FRate: 50 fps"); - vi->framerate = 50000; - form = VIDEO_MODE_PAL; - break; - case 7: - if (pr) - printk(" FRate: 60 fps"); - vi->framerate = 60000; - form = VIDEO_MODE_NTSC; - break; - } - - vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03); - - vi->vbv_buffer_size - = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5); - - if (pr){ - printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000); - printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size)); - printk("\n"); - } - - vi->video_format = form; - - return 0; -} -#endif - - -#if 0 -static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - - while (found < 4 && c+4 < count){ - u8 *b; - - b = mbuf+c; - if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 - && b[3] == 0xb3) found = 4; - else { - c++; - } - } - - if (! found) return -1; - c += 4; - if (c+12 >= count) return -1; - headr = mbuf+c; - if (read_sequence_header(headr, vi, pr) < 0) return -1; - vi->off = c-4; - return 0; -} -#endif - - -#if 0 -static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - int fr = 0; - - while (found < 2 && c < count){ - u8 b[2]; - memcpy( b, mbuf+c, 2); - - if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) - found = 2; - else { - c++; - } - } - - if (!found) return -1; - - if (c+3 >= count) return -1; - headr = mbuf+c; - - ai->layer = (headr[1] & 0x06) >> 1; - - if (pr) - printk("Audiostream: Layer: %d", 4-ai->layer); - - - ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; - - if (pr){ - if (ai->bit_rate == 0) - printk(" Bit rate: free"); - else if (ai->bit_rate == 0xf) - printk(" BRate: reserved"); - else - printk(" BRate: %d kb/s", ai->bit_rate/1000); - } - - fr = (headr[2] & 0x0c ) >> 2; - ai->frequency = freq[fr]*100; - if (pr){ - if (ai->frequency == 3) - printk(" Freq: reserved\n"); - else - printk(" Freq: %d kHz\n",ai->frequency); - - } - ai->off = c; - return 0; -} -#endif - - int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) { u8 *headr; @@ -391,167 +67,6 @@ int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int p return 0; } - -#if 0 -static u8 *skip_pes_header(u8 **bufp) -{ - u8 *inbuf = *bufp; - u8 *buf = inbuf; - u8 *pts = NULL; - int skip = 0; - - static const int mpeg1_skip_table[16] = { - 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff - }; - - - if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ - if (buf[7] & PTS_ONLY) - pts = buf+9; - else pts = NULL; - buf = inbuf + 9 + inbuf[8]; - } else { /* mpeg1 */ - for (buf = inbuf + 6; *buf == 0xff; buf++) - if (buf == inbuf + 6 + 16) { - break; - } - if ((*buf & 0xc0) == 0x40) - buf += 2; - skip = mpeg1_skip_table [*buf >> 4]; - if (skip == 5 || skip == 10) pts = buf; - else pts = NULL; - - buf += mpeg1_skip_table [*buf >> 4]; - } - - *bufp = buf; - return pts; -} -#endif - -#if 0 -static void initialize_quant_matrix( u32 *matrix ) -{ - int i; - - matrix[0] = 0x08101013; - matrix[1] = 0x10131616; - matrix[2] = 0x16161616; - matrix[3] = 0x1a181a1b; - matrix[4] = 0x1b1b1a1a; - matrix[5] = 0x1a1a1b1b; - matrix[6] = 0x1b1d1d1d; - matrix[7] = 0x2222221d; - matrix[8] = 0x1d1d1b1b; - matrix[9] = 0x1d1d2020; - matrix[10] = 0x22222526; - matrix[11] = 0x25232322; - matrix[12] = 0x23262628; - matrix[13] = 0x28283030; - matrix[14] = 0x2e2e3838; - matrix[15] = 0x3a454553; - - for ( i = 16 ; i < 32 ; i++ ) - matrix[i] = 0x10101010; -} -#endif - -#if 0 -static void initialize_mpg_picture(struct mpg_picture *pic) -{ - int i; - - /* set MPEG1 */ - pic->mpeg1_flag = 1; - pic->profile_and_level = 0x4A ; /* MP@LL */ - pic->progressive_sequence = 1; - pic->low_delay = 0; - - pic->sequence_display_extension_flag = 0; - for ( i = 0 ; i < 4 ; i++ ){ - pic->frame_centre_horizontal_offset[i] = 0; - pic->frame_centre_vertical_offset[i] = 0; - } - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - - pic->picture_display_extension_flag[0] = 0; - pic->picture_display_extension_flag[1] = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; -} -#endif - -#if 0 -static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) -{ - int16_t last_h_offset; - int16_t last_v_offset; - - int16_t *p_h_offset; - int16_t *p_v_offset; - - if ( pic->mpeg1_flag ){ - pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE; - pic->top_field_first = 0; - pic->repeat_first_field = 0; - pic->progressive_frame = 1; - pic->picture_coding_parameter = 0x000010; - } - - /* Reset flag */ - pic->picture_display_extension_flag[field_type] = 0; - - last_h_offset = pic->last_frame_centre_horizontal_offset; - last_v_offset = pic->last_frame_centre_vertical_offset; - if ( field_type == FIRST_FIELD ){ - p_h_offset = pic->frame_centre_horizontal_offset; - p_v_offset = pic->frame_centre_vertical_offset; - *p_h_offset = last_h_offset; - *(p_h_offset + 1) = last_h_offset; - *(p_h_offset + 2) = last_h_offset; - *p_v_offset = last_v_offset; - *(p_v_offset + 1) = last_v_offset; - *(p_v_offset + 2) = last_v_offset; - } else { - pic->frame_centre_horizontal_offset[3] = last_h_offset; - pic->frame_centre_vertical_offset[3] = last_v_offset; - } -} -#endif - -#if 0 -static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) -{ - pic->picture_header = 0; - pic->sequence_header_data - = ( INIT_HORIZONTAL_SIZE << 20 ) - | ( INIT_VERTICAL_SIZE << 8 ) - | ( INIT_ASPECT_RATIO << 4 ) - | ( INIT_FRAME_RATE ); - pic->mpeg1_flag = 0; - pic->vinfo.horizontal_size - = INIT_DISP_HORIZONTAL_SIZE; - pic->vinfo.vertical_size - = INIT_DISP_VERTICAL_SIZE; - pic->picture_display_extension_flag[field_type] - = 0; - pic->pts_flag[field_type] = 0; - - pic->sequence_gop_header = 0; - pic->picture_header = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; - pic->sequence_display_extension_flag = 0; - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - pic->channel = chan; -} -#endif - void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, dvb_filter_pes2ts_cb_t *cb, void *priv) { -- cgit v1.2.3 From 9a9689cf6d4dfb8b105946e20846ec20ea403bf9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:11:07 -0300 Subject: [media] dvb_filter: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. While here, add missing log level annotations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/dvb_filter.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/ttpci/dvb_filter.c b/drivers/media/pci/ttpci/dvb_filter.c index 227f93e2ef10..b67127b67d4e 100644 --- a/drivers/media/pci/ttpci/dvb_filter.c +++ b/drivers/media/pci/ttpci/dvb_filter.c @@ -17,7 +17,6 @@ static u32 ac3_frames[3][32] = {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) { u8 *headr; @@ -38,7 +37,7 @@ int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int p if (!found) return -1; if (pr) - printk("Audiostream: AC3"); + printk(KERN_DEBUG "Audiostream: AC3"); ai->off = c; if (c+5 >= count) return -1; @@ -50,19 +49,19 @@ int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int p ai->bit_rate = ac3_bitrates[frame >> 1]*1000; if (pr) - printk(" BRate: %d kb/s", (int) ai->bit_rate/1000); + printk(KERN_CONT " BRate: %d kb/s", (int) ai->bit_rate/1000); ai->frequency = (headr[2] & 0xc0 ) >> 6; fr = (headr[2] & 0xc0 ) >> 6; ai->frequency = freq[fr]*100; - if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency); - + if (pr) + printk(KERN_CONT " Freq: %d Hz\n", (int) ai->frequency); ai->framesize = ac3_frames[fr][frame >> 1]; if ((frame & 1) && (fr == 1)) ai->framesize++; ai->framesize = ai->framesize << 1; - if (pr) printk (" Framesize %d\n",(int) ai->framesize); - + if (pr) + printk(KERN_DEBUG " Framesize %d\n", (int) ai->framesize); return 0; } -- cgit v1.2.3 From 69396c4e2a985091ca6f8d246913fb21ace060ca Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:23:29 -0300 Subject: [media] uvc_driver: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Laurent Pinchart --- drivers/media/usb/uvc/uvc_driver.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 302e284a95eb..9c4b56b4a9c6 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1309,7 +1309,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, switch (UVC_ENTITY_TYPE(entity)) { case UVC_VC_EXTENSION_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- XU %d", entity->id); + printk(KERN_CONT " <- XU %d", entity->id); if (entity->bNrInPins != 1) { uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " @@ -1321,7 +1321,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, case UVC_VC_PROCESSING_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- PU %d", entity->id); + printk(KERN_CONT " <- PU %d", entity->id); if (chain->processing != NULL) { uvc_trace(UVC_TRACE_DESCR, "Found multiple " @@ -1334,7 +1334,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, case UVC_VC_SELECTOR_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- SU %d", entity->id); + printk(KERN_CONT " <- SU %d", entity->id); /* Single-input selector units are ignored. */ if (entity->bNrInPins == 1) @@ -1353,7 +1353,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, case UVC_ITT_CAMERA: case UVC_ITT_MEDIA_TRANSPORT_INPUT: if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT %d\n", entity->id); + printk(KERN_CONT " <- IT %d\n", entity->id); break; @@ -1361,17 +1361,17 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain, case UVC_OTT_DISPLAY: case UVC_OTT_MEDIA_TRANSPORT_OUTPUT: if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" OT %d", entity->id); + printk(KERN_CONT " OT %d", entity->id); break; case UVC_TT_STREAMING: if (UVC_ENTITY_IS_ITERM(entity)) { if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT %d\n", entity->id); + printk(KERN_CONT " <- IT %d\n", entity->id); } else { if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" OT %d", entity->id); + printk(KERN_CONT " OT %d", entity->id); } break; @@ -1416,9 +1416,9 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) - printk(" (->"); + printk(KERN_CONT " (->"); - printk(" XU %d", forward->id); + printk(KERN_CONT " XU %d", forward->id); found = 1; } break; @@ -1436,16 +1436,16 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) - printk(" (->"); + printk(KERN_CONT " (->"); - printk(" OT %d", forward->id); + printk(KERN_CONT " OT %d", forward->id); found = 1; } break; } } if (found) - printk(")"); + printk(KERN_CONT ")"); return 0; } @@ -1471,7 +1471,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, } if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT"); + printk(KERN_CONT " <- IT"); chain->selector = entity; for (i = 0; i < entity->bNrInPins; ++i) { @@ -1485,14 +1485,14 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, } if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" %d", term->id); + printk(KERN_CONT " %d", term->id); list_add_tail(&term->chain, &chain->entities); uvc_scan_chain_forward(chain, term, entity); } if (uvc_trace_param & UVC_TRACE_PROBE) - printk("\n"); + printk(KERN_CONT "\n"); id = 0; break; -- cgit v1.2.3 From 832d40c028cfc7049ceff79155f87ccb5e6a3582 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:48:35 -0300 Subject: [media] imon: use %*ph to do small hexa dumps Since commit 563873318d32 ("Merge branch 'printk-cleanups"), continuation lines require KERN_CONT. Instead, let's just use %*ph to print the buffer. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 86cc70fe2534..d62b1f38292c 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1593,7 +1593,6 @@ static void imon_incoming_packet(struct imon_context *ictx, struct device *dev = ictx->dev; unsigned long flags; u32 kc; - int i; u64 scancode; int press_type = 0; int msec; @@ -1664,10 +1663,8 @@ static void imon_incoming_packet(struct imon_context *ictx, } if (debug) { - printk(KERN_INFO "intf%d decoded packet: ", intf); - for (i = 0; i < len; ++i) - printk("%02x ", buf[i]); - printk("\n"); + printk(KERN_INFO "intf%d decoded packet: %*ph\n", + intf, len, buf); } press_type = imon_parse_press_type(ictx, buf, ktype); -- cgit v1.2.3 From c5bac2e75270b10ff5a5675bebad4df2106506f1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 10:37:48 -0300 Subject: [media] mt20xx: use %*ph to do small hexa dumps Since commit 563873318d32 ("Merge branch 'printk-cleanups"), continuation lines require KERN_CONT. Instead, let's just use %*ph to print the buffer. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/mt20xx.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c index 52da4671b0e0..29dadd171b31 100644 --- a/drivers/media/tuners/mt20xx.c +++ b/drivers/media/tuners/mt20xx.c @@ -487,13 +487,8 @@ static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsign buf[5]=div2a; if(num2!=0) buf[5]=buf[5]|0x40; - if (debug > 1) { - int i; - tuner_dbg("bufs is: "); - for(i=0;i<6;i++) - printk("%x ",buf[i]); - printk("\n"); - } + if (debug > 1) + tuner_dbg("bufs is: %*ph\n", 6, buf); ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6); if (ret!=6) @@ -619,15 +614,9 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, tuner_i2c_xfer_send(&priv->i2c_props,buf,1); tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); - if (debug) { - int i; - tuner_dbg("MT20xx hexdump:"); - for(i=0;i<21;i++) { - printk(" %02x",buf[i]); - if(((i+1)%8)==0) printk(" "); - } - printk("\n"); - } + if (debug) + tuner_dbg("MT20xx hexdump: %*ph\n", 21, buf); + company_code = buf[0x11] << 8 | buf[0x12]; tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", company_code,buf[0x13],buf[0x14]); -- cgit v1.2.3 From 178991e03c43db6a45ecf3d28fee6165fc66b250 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 14:02:21 -0300 Subject: [media] tvaudio: mark printk continuation lines as such This driver has printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvaudio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index 42d1e26e581c..ce86534450ac 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -1894,8 +1894,9 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n"); printk(KERN_INFO "tvaudio: known chips: "); for (desc = chiplist; desc->name != NULL; desc++) - printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name); - printk("\n"); + printk(KERN_CONT "%s%s", + (desc == chiplist) ? "" : ", ", desc->name); + printk(KERN_CONT "\n"); } chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); -- cgit v1.2.3 From 7887d3710b6eac7c980f4e7b4b86bd383695ae80 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:23:12 -0300 Subject: [media] flexcop-i2c: mark printk continuation lines as such This driver has printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-i2c.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c index 965d5eb33752..e41cd23f8e45 100644 --- a/drivers/media/common/b2c2/flexcop-i2c.c +++ b/drivers/media/common/b2c2/flexcop-i2c.c @@ -124,10 +124,10 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, #ifdef DUMP_I2C_MESSAGES printk(KERN_DEBUG "%d ", i2c->port); if (op == FC_READ) - printk("rd("); + printk(KERN_CONT "rd("); else - printk("wr("); - printk("%02x): %02x ", chipaddr, addr); + printk(KERN_CONT "wr("); + printk(KERN_CONT "%02x): %02x ", chipaddr, addr); #endif /* in that case addr is the only value -> @@ -151,7 +151,7 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, #ifdef DUMP_I2C_MESSAGES for (i = 0; i < bytes_to_transfer; i++) - printk("%02x ", buf[i]); + printk(KERN_CONT "%02x ", buf[i]); #endif if (ret < 0) @@ -163,7 +163,7 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, } #ifdef DUMP_I2C_MESSAGES - printk("\n"); + printk(KERN_CONT "\n"); #endif return 0; -- cgit v1.2.3 From 6dd23d4c952f4ccf4dd9454c8464557c5151f2be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:27:35 -0300 Subject: [media] cx2341x: mark printk continuation lines as such This driver has printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/cx2341x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/common/cx2341x.c b/drivers/media/common/cx2341x.c index 5e4afa0131e6..2725702eda7b 100644 --- a/drivers/media/common/cx2341x.c +++ b/drivers/media/common/cx2341x.c @@ -1190,8 +1190,8 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); if (p->stream_insert_nav_packets) - printk(" (with navigation packets)"); - printk("\n"); + printk(KERN_CONT " (with navigation packets)"); + printk(KERN_CONT "\n"); printk(KERN_INFO "%s: VBI Format: %s\n", prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT)); @@ -1209,8 +1209,8 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), p->video_bitrate); if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) - printk(", Peak %d", p->video_bitrate_peak); - printk("\n"); + printk(KERN_CONT ", Peak %d", p->video_bitrate_peak); + printk(KERN_CONT "\n"); printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n", prefix, @@ -1232,9 +1232,9 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE), p->audio_mute ? " (muted)" : ""); if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) - printk(", %s", cx2341x_menu_item(p, + printk(KERN_CONT ", %s", cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION)); - printk(", %s, %s\n", + printk(KERN_CONT ", %s, %s\n", cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS), cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); -- cgit v1.2.3 From 5479a582deb57e9f4804fc001fa41b3f07eb9334 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:32:32 -0300 Subject: [media] dvb-pll: use pr_foo() macros instead of printk() Replace printk() macros by their pr_foo() counterparts. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dvb-pll.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 735a96662022..b6d199196b83 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -18,6 +18,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -25,6 +27,9 @@ #include "dvb-pll.h" +#define dprintk(fmt, arg...) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg) + struct dvb_pll_priv { /* pll number */ int nr; @@ -362,7 +367,7 @@ static void opera1_bw(struct dvb_frontend *fe, u8 *buf) result = i2c_transfer(priv->i2c, &msg, 1); if (result != 1) - printk(KERN_ERR "%s: i2c_transfer failed:%d", + pr_err("%s: i2c_transfer failed:%d", __func__, result); if (b_w <= 10000) @@ -432,7 +437,7 @@ static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf) result = i2c_transfer(priv->i2c, &msg, 1); if (result != 1) - printk(KERN_ERR "%s: i2c_transfer failed:%d", + pr_err("%s: i2c_transfer failed:%d", __func__, result); buf[2] = 0x9e; @@ -578,7 +583,7 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, } if (debug) - printk("pll: %s: freq=%d | i=%d/%d\n", desc->name, + dprintk("pll: %s: freq=%d | i=%d/%d\n", desc->name, frequency, i, desc->count); if (i == desc->count) return -EINVAL; @@ -594,7 +599,7 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, desc->set(fe, buf); if (debug) - printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", + dprintk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", desc->name, div, buf[0], buf[1], buf[2], buf[3]); // calculate the frequency we set it to @@ -803,10 +808,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, fe->tuner_priv = priv; if ((debug) || (id[priv->nr] == pll_desc_id)) { - printk("dvb-pll[%d]", priv->nr); + dprintk("dvb-pll[%d]", priv->nr); if (i2c != NULL) - printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); - printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, + pr_cont(" %d-%04x", i2c_adapter_id(i2c), pll_addr); + pr_cont(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, id[priv->nr] == pll_desc_id ? "insmod option" : "autodetected"); } -- cgit v1.2.3 From cc5ad2b659d2c37c8b264a72621653cbbd2a7c06 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:37:40 -0300 Subject: [media] nxt6000: use pr_foo() macros instead of printk() Replace printk() macros by their pr_foo() counterparts and use pr_cont() for the continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/nxt6000.c | 136 +++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 60 deletions(-) diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c index 73f9505367ac..1545d898b125 100644 --- a/drivers/media/dvb-frontends/nxt6000.c +++ b/drivers/media/dvb-frontends/nxt6000.c @@ -19,6 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -39,7 +41,11 @@ struct nxt6000_state { }; static int debug; -#define dprintk if (debug) printk +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data) { @@ -215,119 +221,129 @@ static void nxt6000_dump_status(struct nxt6000_state *state) { u8 val; -/* - printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT)); - printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS)); - printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT)); - printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT)); - printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1)); - printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2)); - printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3)); - printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4)); - printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1)); - printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2)); -*/ - printk("NXT6000 status:"); +#if 0 + pr_info("RS_COR_STAT: 0x%02X\n", + nxt6000_readreg(fe, RS_COR_STAT)); + pr_info("VIT_SYNC_STATUS: 0x%02X\n", + nxt6000_readreg(fe, VIT_SYNC_STATUS)); + pr_info("OFDM_COR_STAT: 0x%02X\n", + nxt6000_readreg(fe, OFDM_COR_STAT)); + pr_info("OFDM_SYR_STAT: 0x%02X\n", + nxt6000_readreg(fe, OFDM_SYR_STAT)); + pr_info("OFDM_TPS_RCVD_1: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RCVD_1)); + pr_info("OFDM_TPS_RCVD_2: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RCVD_2)); + pr_info("OFDM_TPS_RCVD_3: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RCVD_3)); + pr_info("OFDM_TPS_RCVD_4: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RCVD_4)); + pr_info("OFDM_TPS_RESERVED_1: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RESERVED_1)); + pr_info("OFDM_TPS_RESERVED_2: 0x%02X\n", + nxt6000_readreg(fe, OFDM_TPS_RESERVED_2)); +#endif + pr_info("NXT6000 status:"); val = nxt6000_readreg(state, RS_COR_STAT); - printk(" DATA DESCR LOCK: %d,", val & 0x01); - printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01); + pr_cont(" DATA DESCR LOCK: %d,", val & 0x01); + pr_cont(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01); val = nxt6000_readreg(state, VIT_SYNC_STATUS); - printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01); + pr_cont(" VITERBI LOCK: %d,", (val >> 7) & 0x01); switch ((val >> 4) & 0x07) { case 0x00: - printk(" VITERBI CODERATE: 1/2,"); + pr_cont(" VITERBI CODERATE: 1/2,"); break; case 0x01: - printk(" VITERBI CODERATE: 2/3,"); + pr_cont(" VITERBI CODERATE: 2/3,"); break; case 0x02: - printk(" VITERBI CODERATE: 3/4,"); + pr_cont(" VITERBI CODERATE: 3/4,"); break; case 0x03: - printk(" VITERBI CODERATE: 5/6,"); + pr_cont(" VITERBI CODERATE: 5/6,"); break; case 0x04: - printk(" VITERBI CODERATE: 7/8,"); + pr_cont(" VITERBI CODERATE: 7/8,"); break; default: - printk(" VITERBI CODERATE: Reserved,"); + pr_cont(" VITERBI CODERATE: Reserved,"); } val = nxt6000_readreg(state, OFDM_COR_STAT); - printk(" CHCTrack: %d,", (val >> 7) & 0x01); - printk(" TPSLock: %d,", (val >> 6) & 0x01); - printk(" SYRLock: %d,", (val >> 5) & 0x01); - printk(" AGCLock: %d,", (val >> 4) & 0x01); + pr_cont(" CHCTrack: %d,", (val >> 7) & 0x01); + pr_cont(" TPSLock: %d,", (val >> 6) & 0x01); + pr_cont(" SYRLock: %d,", (val >> 5) & 0x01); + pr_cont(" AGCLock: %d,", (val >> 4) & 0x01); switch (val & 0x0F) { case 0x00: - printk(" CoreState: IDLE,"); + pr_cont(" CoreState: IDLE,"); break; case 0x02: - printk(" CoreState: WAIT_AGC,"); + pr_cont(" CoreState: WAIT_AGC,"); break; case 0x03: - printk(" CoreState: WAIT_SYR,"); + pr_cont(" CoreState: WAIT_SYR,"); break; case 0x04: - printk(" CoreState: WAIT_PPM,"); + pr_cont(" CoreState: WAIT_PPM,"); break; case 0x01: - printk(" CoreState: WAIT_TRL,"); + pr_cont(" CoreState: WAIT_TRL,"); break; case 0x05: - printk(" CoreState: WAIT_TPS,"); + pr_cont(" CoreState: WAIT_TPS,"); break; case 0x06: - printk(" CoreState: MONITOR_TPS,"); + pr_cont(" CoreState: MONITOR_TPS,"); break; default: - printk(" CoreState: Reserved,"); + pr_cont(" CoreState: Reserved,"); } val = nxt6000_readreg(state, OFDM_SYR_STAT); - printk(" SYRLock: %d,", (val >> 4) & 0x01); - printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K"); + pr_cont(" SYRLock: %d,", (val >> 4) & 0x01); + pr_cont(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K"); switch ((val >> 4) & 0x03) { case 0x00: - printk(" SYRGuard: 1/32,"); + pr_cont(" SYRGuard: 1/32,"); break; case 0x01: - printk(" SYRGuard: 1/16,"); + pr_cont(" SYRGuard: 1/16,"); break; case 0x02: - printk(" SYRGuard: 1/8,"); + pr_cont(" SYRGuard: 1/8,"); break; case 0x03: - printk(" SYRGuard: 1/4,"); + pr_cont(" SYRGuard: 1/4,"); break; } @@ -336,77 +352,77 @@ static void nxt6000_dump_status(struct nxt6000_state *state) switch ((val >> 4) & 0x07) { case 0x00: - printk(" TPSLP: 1/2,"); + pr_cont(" TPSLP: 1/2,"); break; case 0x01: - printk(" TPSLP: 2/3,"); + pr_cont(" TPSLP: 2/3,"); break; case 0x02: - printk(" TPSLP: 3/4,"); + pr_cont(" TPSLP: 3/4,"); break; case 0x03: - printk(" TPSLP: 5/6,"); + pr_cont(" TPSLP: 5/6,"); break; case 0x04: - printk(" TPSLP: 7/8,"); + pr_cont(" TPSLP: 7/8,"); break; default: - printk(" TPSLP: Reserved,"); + pr_cont(" TPSLP: Reserved,"); } switch (val & 0x07) { case 0x00: - printk(" TPSHP: 1/2,"); + pr_cont(" TPSHP: 1/2,"); break; case 0x01: - printk(" TPSHP: 2/3,"); + pr_cont(" TPSHP: 2/3,"); break; case 0x02: - printk(" TPSHP: 3/4,"); + pr_cont(" TPSHP: 3/4,"); break; case 0x03: - printk(" TPSHP: 5/6,"); + pr_cont(" TPSHP: 5/6,"); break; case 0x04: - printk(" TPSHP: 7/8,"); + pr_cont(" TPSHP: 7/8,"); break; default: - printk(" TPSHP: Reserved,"); + pr_cont(" TPSHP: Reserved,"); } val = nxt6000_readreg(state, OFDM_TPS_RCVD_4); - printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K"); + pr_cont(" TPSMode: %s,", val & 0x01 ? "8K" : "2K"); switch ((val >> 4) & 0x03) { case 0x00: - printk(" TPSGuard: 1/32,"); + pr_cont(" TPSGuard: 1/32,"); break; case 0x01: - printk(" TPSGuard: 1/16,"); + pr_cont(" TPSGuard: 1/16,"); break; case 0x02: - printk(" TPSGuard: 1/8,"); + pr_cont(" TPSGuard: 1/8,"); break; case 0x03: - printk(" TPSGuard: 1/4,"); + pr_cont(" TPSGuard: 1/4,"); break; } @@ -416,8 +432,8 @@ static void nxt6000_dump_status(struct nxt6000_state *state) val = nxt6000_readreg(state, RF_AGC_STATUS); val = nxt6000_readreg(state, RF_AGC_STATUS); - printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01); - printk("\n"); + pr_cont(" RF AGC LOCK: %d,", (val >> 4) & 0x01); + pr_cont("\n"); } static int nxt6000_read_status(struct dvb_frontend *fe, enum fe_status *status) -- cgit v1.2.3 From d9942ad0228a7e1a46a24f7962cb790443042da3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:00 -0200 Subject: [media] b2c2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-eeprom.c | 3 +-- drivers/media/common/b2c2/flexcop-i2c.c | 4 ++-- drivers/media/common/b2c2/flexcop-misc.c | 9 +++------ drivers/media/common/b2c2/flexcop.c | 3 +-- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c index a25373a9bd84..844c7836c2a6 100644 --- a/drivers/media/common/b2c2/flexcop-eeprom.c +++ b/drivers/media/common/b2c2/flexcop-eeprom.c @@ -136,8 +136,7 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { if (extended != 0) { - err("TODO: extended (EUI64) MAC addresses aren't " - "completely supported yet"); + err("TODO: extended (EUI64) MAC addresses aren't completely supported yet"); ret = -EINVAL; } else memcpy(fc->dvb_adapter.proposed_mac,buf,6); diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c index e41cd23f8e45..58d39a59fc09 100644 --- a/drivers/media/common/b2c2/flexcop-i2c.c +++ b/drivers/media/common/b2c2/flexcop-i2c.c @@ -33,8 +33,8 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, return -EREMOTEIO; } } - deb_i2c("tried %d times i2c operation, " - "never finished or too many ack errors.\n", i); + deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n", + i); return -EREMOTEIO; } diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c index b8eff235367d..bb0d95fe64f9 100644 --- a/drivers/media/common/b2c2/flexcop-misc.c +++ b/drivers/media/common/b2c2/flexcop-misc.c @@ -23,18 +23,15 @@ void flexcop_determine_revision(struct flexcop_device *fc) fc->rev = FLEXCOP_III; break; default: - err("unknown FlexCop Revision: %x. Please report this to " - "linux-dvb@linuxtv.org.", + err("unknown FlexCop Revision: %x. Please report this to linux-dvb@linuxtv.org.", v.misc_204.Rev_N_sig_revision_hi); break; } if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps)) - deb_info("this FlexCop has " - "the additional 32 hardware pid filter.\n"); + deb_info("this FlexCop has the additional 32 hardware pid filter.\n"); else - deb_info("this FlexCop has " - "the 6 basic main hardware pid filter.\n"); + deb_info("this FlexCop has the 6 basic main hardware pid filter.\n"); /* bus parts have to decide if hw pid filtering is used or not. */ } diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c index 0f5114d406f8..4338ab0043b4 100644 --- a/drivers/media/common/b2c2/flexcop.c +++ b/drivers/media/common/b2c2/flexcop.c @@ -46,8 +46,7 @@ int b2c2_flexcop_debug; EXPORT_SYMBOL_GPL(b2c2_flexcop_debug); module_param_named(debug, b2c2_flexcop_debug, int, 0644); MODULE_PARM_DESC(debug, - "set debug level (1=info,2=tuner,4=i2c,8=ts," - "16=sram,32=reg (|-able))." + "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS); #undef DEBSTATUS -- cgit v1.2.3 From 72cc0671b0fad38891f134afa069f38dc74f39b9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:01 -0200 Subject: [media] cx25840: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/cx25840/cx25840-core.c | 11 +++-------- drivers/media/i2c/cx25840/cx25840-ir.c | 7 +++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 142ae28803bb..0dcf450052ac 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -873,10 +873,7 @@ void cx25840_std_setup(struct i2c_client *client) "Chroma sub-carrier freq = %d.%06d MHz\n", fsc / 1000000, fsc % 1000000); - v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " - "vblank %i, vactive %i, vblank656 %i, src_dec %i, " - "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, " - "sc 0x%06x\n", + v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n", hblank, hactive, vblank, vactive, vblank656, src_decimation, burst, luma_lpf, uv_lpf, comb, sc); } @@ -5169,11 +5166,9 @@ static int cx25840_probe(struct i2c_client *client, id = CX2310X_AV; } else if ((device_id & 0xff) == (device_id >> 8)) { v4l_err(client, - "likely a confused/unresponsive cx2388[578] A/V decoder" - " found @ 0x%x (%s)\n", + "likely a confused/unresponsive cx2388[578] A/V decoder found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); - v4l_err(client, "A method to reset it from the cx25840 driver" - " software is not known at this time\n"); + v4l_err(client, "A method to reset it from the cx25840 driver software is not known at this time\n"); return -ENODEV; } else { v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index 4b782012cadc..15fbd9607cee 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -1113,8 +1113,8 @@ int cx25840_ir_log_status(struct v4l2_subdev *sd) j = 0; break; } - v4l2_info(sd, "\tNext carrier edge window: 16 clocks " - "-%1d/+%1d, %u to %u Hz\n", i, j, + v4l2_info(sd, "\tNext carrier edge window: 16 clocks -%1d/+%1d, %u to %u Hz\n", + i, j, clock_divider_to_freq(rxclk, 16 + j), clock_divider_to_freq(rxclk, 16 - i)); } @@ -1124,8 +1124,7 @@ int cx25840_ir_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "\tLow pass filter: %s\n", filtr ? "enabled" : "disabled"); if (filtr) - v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, " - "%u ns\n", + v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, %u ns\n", lpf_count_to_us(filtr), lpf_count_to_ns(filtr)); v4l2_info(sd, "\tPulse width timer timed-out: %s\n", -- cgit v1.2.3 From 4b68f05e4d607c596288d2c81bdf196a4950ce6c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:01 -0200 Subject: [media] smiapp: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-regs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c index 1e501c06d18c..d6779e35d36f 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.c +++ b/drivers/media/i2c/smiapp/smiapp-regs.c @@ -268,8 +268,8 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) if (r == 1) { if (retries) dev_err(&client->dev, - "sensor i2c stall encountered. " - "retries: %d\n", retries); + "sensor i2c stall encountered. retries: %d\n", + retries); return 0; } -- cgit v1.2.3 From 8f44c3925139fc2fc1ccae6b2a9dcd51215fb16b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:01 -0200 Subject: [media] soc_camera: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/soc_camera/ov772x.c | 3 +-- drivers/media/i2c/soc_camera/ov9740.c | 3 +-- drivers/media/i2c/soc_camera/tw9910.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index 7e68762b3a4b..985a3672b243 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -1064,8 +1064,7 @@ static int ov772x_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&adapter->dev, - "I2C-Adapter doesn't support " - "I2C_FUNC_SMBUS_BYTE_DATA\n"); + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n"); return -EIO; } diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index 0da632d7d33a..f11f76cdacad 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -881,8 +881,7 @@ static int ov9740_video_probe(struct i2c_client *client) goto done; } - dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, " - "Manufacturer 0x%02x, SMIA Version 0x%02x\n", + dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, Manufacturer 0x%02x, SMIA Version 0x%02x\n", priv->model, priv->revision, priv->manid, priv->smiaver); ret = v4l2_ctrl_handler_setup(&priv->hdl); diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 4002c07f3857..c9c49ed707b8 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -947,8 +947,7 @@ static int tw9910_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, - "I2C-Adapter doesn't support " - "I2C_FUNC_SMBUS_BYTE_DATA\n"); + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n"); return -EIO; } -- cgit v1.2.3 From d6376f0e64b19e55a6c7f3e5bd6648fd1f87e1f2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:02 -0200 Subject: [media] b2c2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/b2c2/flexcop-dma.c | 6 ++---- drivers/media/pci/b2c2/flexcop-pci.c | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/b2c2/flexcop-dma.c b/drivers/media/pci/b2c2/flexcop-dma.c index 2881e0d956ad..913dc97f8b49 100644 --- a/drivers/media/pci/b2c2/flexcop-dma.c +++ b/drivers/media/pci/b2c2/flexcop-dma.c @@ -57,8 +57,7 @@ int flexcop_dma_config(struct flexcop_device *fc, fc->write_ibi_reg(fc,dma2_014,v0x4); fc->write_ibi_reg(fc,dma2_01c,v0xc); } else { - err("either DMA1 or DMA2 can be configured within one " - "flexcop_dma_config call."); + err("either DMA1 or DMA2 can be configured within one flexcop_dma_config call."); return -EINVAL; } @@ -82,8 +81,7 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc, r0x0 = dma2_010; r0xc = dma2_01c; } else { - err("either transfer DMA1 or DMA2 can be started within one " - "flexcop_dma_xfer_control call."); + err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call."); return -EINVAL; } diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c index 4cac1fc233f2..99ce28442a75 100644 --- a/drivers/media/pci/b2c2/flexcop-pci.c +++ b/drivers/media/pci/b2c2/flexcop-pci.c @@ -185,8 +185,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; - deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, " - "last_cur_pos: %08x ", + deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", jiffies_to_usecs(jiffies - fc_pci->last_irq), v.raw, (unsigned long long)cur_addr, cur_pos, fc_pci->last_dma1_cur_pos); @@ -220,8 +219,8 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) fc_pci->last_dma1_cur_pos = cur_pos; fc_pci->count++; } else { - deb_irq("isr for flexcop called, " - "apparently without reason (%08x)\n", v.raw); + deb_irq("isr for flexcop called, apparently without reason (%08x)\n", + v.raw); ret = IRQ_NONE; } -- cgit v1.2.3 From 652fd6eaebc7ff2b268ca905e6aec5bd001b1b16 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:02 -0200 Subject: [media] bt8xx: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-cards.c | 9 +++------ drivers/media/pci/bt8xx/bttv-driver.c | 6 ++---- drivers/media/pci/bt8xx/bttv-i2c.c | 6 ++---- drivers/media/pci/bt8xx/bttv-input.c | 4 ++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index 8a17cc0bfa07..a1b0f3193bc0 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -125,10 +125,8 @@ module_param_array(remote, int, NULL, 0444); module_param_array(audiodev, int, NULL, 0444); module_param_array(audiomux, int, NULL, 0444); -MODULE_PARM_DESC(triton1,"set ETBF pci config bit " - "[enable bug compatibility for triton1 + others]"); -MODULE_PARM_DESC(vsfx,"set VSFX pci config bit " - "[yet another chipset flaw workaround]"); +MODULE_PARM_DESC(triton1, "set ETBF pci config bit [enable bug compatibility for triton1 + others]"); +MODULE_PARM_DESC(vsfx, "set VSFX pci config bit [yet another chipset flaw workaround]"); MODULE_PARM_DESC(latency,"pci latency timer"); MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list"); MODULE_PARM_DESC(pll, "specify installed crystal (0=none, 28=28 MHz, 35=35 MHz, 14=14 MHz)"); @@ -141,8 +139,7 @@ MODULE_PARM_DESC(audiodev, "specify audio device:\n" "\t\t 2 = tda7432\n" "\t\t 3 = tvaudio"); MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition."); -MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" - " [some VIA/SIS chipsets are known to have problem with overlay]"); +MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]"); /* ----------------------------------------------------------------------- */ /* list of card IDs for bt878+ cards */ diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 97b91a9f9fa9..fb4aefbcc8f8 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -148,8 +148,7 @@ MODULE_PARM_DESC(irq_debug, "irq handler debug messages, default is 0 (no)"); MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); MODULE_PARM_DESC(gbuffers, "number of capture buffers. range 2-32, default 8"); MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 0x208000"); -MODULE_PARM_DESC(reset_crop, "reset cropping parameters at open(), default " - "is 1 (yes) for compatibility with older applications"); +MODULE_PARM_DESC(reset_crop, "reset cropping parameters at open(), default is 1 (yes) for compatibility with older applications"); MODULE_PARM_DESC(automute, "mute audio on bad/missing video signal, default is 1 (yes)"); MODULE_PARM_DESC(chroma_agc, "enables the AGC of chroma signal, default is 0 (no)"); MODULE_PARM_DESC(agc_crush, "enables the luminance AGC crush, default is 1 (yes)"); @@ -3506,8 +3505,7 @@ static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc) (unsigned long)rc); if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) { - pr_notice("%d: Oh, there (temporarily?) is no input signal. " - "Ok, then this is harmless, don't worry ;)\n", + pr_notice("%d: Oh, there (temporarily?) is no input signal. Ok, then this is harmless, don't worry ;)\n", btv->c.nr); return; } diff --git a/drivers/media/pci/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c index d43911deb617..274fd036b306 100644 --- a/drivers/media/pci/bt8xx/bttv-i2c.c +++ b/drivers/media/pci/bt8xx/bttv-i2c.c @@ -44,15 +44,13 @@ static int i2c_scan; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); module_param(i2c_hw, int, 0444); -MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, " - "instead of software bitbang"); +MODULE_PARM_DESC(i2c_hw, "force use of hardware i2c support, instead of software bitbang"); module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); static unsigned int i2c_udelay = 5; module_param(i2c_udelay, int, 0444); -MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs " - "(should be 5 or higher). Lower value means higher bus speed."); +MODULE_PARM_DESC(i2c_udelay, "soft i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); /* ----------------------------------------------------------------------- */ /* I2C functions - bitbanging adapter (software i2c) */ diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index a75c53da224a..4da720e4867e 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -185,8 +185,8 @@ static u32 bttv_rc5_decode(unsigned int code) return 0; } } - dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), + dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, instr=%x\n", + rc5, org_code, RC5_START(rc5), RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); return rc5; } -- cgit v1.2.3 From 6beb1388a0b5730337360818d9385808e50aa870 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:03 -0200 Subject: [media] cx18: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-alsa-main.c | 8 +++---- drivers/media/pci/cx18/cx18-av-core.c | 17 ++++++-------- drivers/media/pci/cx18/cx18-av-firmware.c | 3 +-- drivers/media/pci/cx18/cx18-controls.c | 9 +++---- drivers/media/pci/cx18/cx18-driver.c | 35 ++++++++++++--------------- drivers/media/pci/cx18/cx18-dvb.c | 6 ++--- drivers/media/pci/cx18/cx18-fileops.c | 6 ++--- drivers/media/pci/cx18/cx18-ioctl.c | 6 ++--- drivers/media/pci/cx18/cx18-irq.c | 4 ++-- drivers/media/pci/cx18/cx18-mailbox.c | 39 +++++++++++-------------------- drivers/media/pci/cx18/cx18-queue.c | 8 +++---- drivers/media/pci/cx18/cx18-streams.c | 7 +++--- 12 files changed, 58 insertions(+), 90 deletions(-) diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index 0b0e8015ad34..9fb7f5978c8b 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c @@ -217,8 +217,8 @@ static int cx18_alsa_load(struct cx18 *cx) s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; if (s->video_dev.v4l2_dev == NULL) { - CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " - "skipping\n", __func__); + CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - skipping\n", + __func__); return 0; } @@ -232,8 +232,8 @@ static int cx18_alsa_load(struct cx18 *cx) CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n", __func__); } else { - CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance " - "\n", __func__); + CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance\n", + __func__); } return 0; } diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index 30bbe8d1ea55..7f7306fd9a7f 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -468,21 +468,19 @@ void cx18_av_std_setup(struct cx18 *cx) CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n", pll / 8000000, (pll / 8) % 1000000); - CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio " - "= %d.%03d\n", src_decimation / 256, + CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio = %d.%03d\n", + src_decimation / 256, ((src_decimation % 256) * 1000) / 256); tmp = 28636360 * (u64) sc; do_div(tmp, src_decimation); fsc = tmp >> 13; CX18_DEBUG_INFO_DEV(sd, - "Chroma sub-carrier initial freq = %d.%06d " - "MHz\n", fsc / 1000000, fsc % 1000000); + "Chroma sub-carrier initial freq = %d.%06d MHz\n", + fsc / 1000000, fsc % 1000000); - CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " - "vactive %i, vblank656 %i, src_dec %i, " - "burst 0x%02x, luma_lpf %i, uv_lpf %i, " - "comb 0x%02x, sc 0x%06x\n", + CX18_DEBUG_INFO_DEV(sd, + "hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n", hblank, hactive, vblank, vactive, vblank656, src_decimation, burst, luma_lpf, uv_lpf, comb, sc); @@ -1069,8 +1067,7 @@ static void log_video_status(struct cx18 *cx) CX18_INFO_DEV(sd, "Specified video input: Composite %d\n", vid_input - CX18_AV_COMPOSITE1 + 1); } else { - CX18_INFO_DEV(sd, "Specified video input: " - "S-Video (Luma In%d, Chroma In%d)\n", + CX18_INFO_DEV(sd, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); } diff --git a/drivers/media/pci/cx18/cx18-av-firmware.c b/drivers/media/pci/cx18/cx18-av-firmware.c index a34fd082b76e..160e2e53383f 100644 --- a/drivers/media/pci/cx18/cx18-av-firmware.c +++ b/drivers/media/pci/cx18/cx18-av-firmware.c @@ -61,8 +61,7 @@ static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw) dl_control &= 0xffff3fff; /* ignore top 2 bits of address */ expected = 0x0f000000 | ((u32)data[addr] << 16) | addr; if (expected != dl_control) { - CX18_ERR_DEV(sd, "verification of %s firmware load " - "failed: expected %#010x got %#010x\n", + CX18_ERR_DEV(sd, "verification of %s firmware load failed: expected %#010x got %#010x\n", FWFILE, expected, dl_control); ret = -EIO; break; diff --git a/drivers/media/pci/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c index adb5a8c72c06..812a2507945a 100644 --- a/drivers/media/pci/cx18/cx18-controls.c +++ b/drivers/media/pci/cx18/cx18-controls.c @@ -44,8 +44,7 @@ static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) { /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */ cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; - CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " - "the MPEG stream\n"); + CX18_DEBUG_INFO("disabled insertion of sliced VBI data into the MPEG stream\n"); return 0; } @@ -63,16 +62,14 @@ static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) } cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; - CX18_WARN("Unable to allocate buffers for " - "sliced VBI data insertion\n"); + CX18_WARN("Unable to allocate buffers for sliced VBI data insertion\n"); return -ENOMEM; } } } cx->vbi.insert_mpeg = fmt; - CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS," - "when sliced VBI is enabled\n"); + CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,when sliced VBI is enabled\n"); /* * If our current settings have no lines set for capture, store a valid, diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 2f23b26b16c0..b8eedbe51c8f 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -405,8 +405,8 @@ static void cx18_process_eeprom(struct cx18 *cx) CX18_ERR("Invalid EEPROM\n"); return; default: - CX18_ERR("Unknown model %d, defaulting to original HVR-1600 " - "(cardtype=1)\n", tv.model); + CX18_ERR("Unknown model %d, defaulting to original HVR-1600 (cardtype=1)\n", + tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } @@ -635,8 +635,8 @@ static void cx18_process_options(struct cx18 *cx) /* convert from kB to bytes */ cx->stream_buf_size[i] *= 1024; } - CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, " - "%d bytes\n", i, cx->options.megabytes[i], + CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, %d bytes\n", + i, cx->options.megabytes[i], cx->stream_buffers[i], cx->stream_buf_size[i]); } @@ -838,14 +838,13 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && cx18_pci_latency) { - CX18_INFO("Unreasonably low latency timer, " - "setting to 64 (was %d)\n", pci_latency); + CX18_INFO("Unreasonably low latency timer, setting to 64 (was %d)\n", + pci_latency); pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); } - CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%llx\n", + CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, irq: %d, latency: %d, memory: 0x%llx\n", cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), cx->pci_dev->irq, pci_latency, (u64)cx->base_addr); @@ -910,8 +909,8 @@ static int cx18_probe(struct pci_dev *pci_dev, /* FIXME - module parameter arrays constrain max instances */ i = atomic_inc_return(&cx18_instance) - 1; if (i >= CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: cannot manage card %d, driver has a " - "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1); + printk(KERN_ERR "cx18: cannot manage card %d, driver has a limit of 0 - %d\n", + i, CX18_MAX_CARDS - 1); return -ENOMEM; } @@ -926,8 +925,8 @@ static int cx18_probe(struct pci_dev *pci_dev, retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); if (retval) { - printk(KERN_ERR "cx18: v4l2_device_register of card %d failed" - "\n", cx->instance); + printk(KERN_ERR "cx18: v4l2_device_register of card %d failed\n", + cx->instance); kfree(cx); return retval; } @@ -958,13 +957,10 @@ static int cx18_probe(struct pci_dev *pci_dev, cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { - CX18_ERR("ioremap failed. Can't get a window into CX23418 " - "memory and register space\n"); - CX18_ERR("Each capture card with a CX23418 needs 64 MB of " - "vmalloc address space for the window\n"); + CX18_ERR("ioremap failed. Can't get a window into CX23418 memory and register space\n"); + CX18_ERR("Each capture card with a CX23418 needs 64 MB of vmalloc address space for the window\n"); CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); - CX18_ERR("Use the vmalloc= kernel command line option to set " - "VmallocTotal to a larger value\n"); + CX18_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n"); retval = -ENOMEM; goto free_mem; } @@ -1000,8 +996,7 @@ static int cx18_probe(struct pci_dev *pci_dev, /* Initialize GPIO Reset Controller to do chip resets during i2c init */ if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0) - CX18_WARN("Could not register GPIO reset controller" - "subdevice; proceeding anyway.\n"); + CX18_WARN("Could not register GPIO reset controllersubdevice; proceeding anyway.\n"); else cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL; } diff --git a/drivers/media/pci/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c index 3eac59c51231..03d0478170a7 100644 --- a/drivers/media/pci/cx18/cx18-dvb.c +++ b/drivers/media/pci/cx18/cx18-dvb.c @@ -155,10 +155,8 @@ static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream, } if (ret) { - CX18_ERR("The MPC718 board variant with the MT352 DVB-T" - "demodualtor will not work without it\n"); - CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware " - "mpc718' if you need the firmware\n"); + CX18_ERR("The MPC718 board variant with the MT352 DVB-Tdemodualtor will not work without it\n"); + CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware mpc718' if you need the firmware\n"); } return ret; } diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index df837408efd5..78b399b8613e 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -49,8 +49,7 @@ int cx18_claim_stream(struct cx18_open_id *id, int type) /* Nothing should ever try to directly claim the IDX stream */ if (type == CX18_ENC_STREAM_TYPE_IDX) { - CX18_WARN("MPEG Index stream cannot be claimed " - "directly, but something tried.\n"); + CX18_WARN("MPEG Index stream cannot be claimed directly, but something tried.\n"); return -EINVAL; } @@ -728,8 +727,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end) /* Stop internal use associated VBI and IDX streams */ if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { - CX18_DEBUG_INFO("close stopping embedded VBI " - "capture\n"); + CX18_DEBUG_INFO("close stopping embedded VBI capture\n"); cx18_stop_v4l2_encode_stream(s_vbi, 0); } if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) { diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index fecca2a63891..0faeb979ceb9 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -951,8 +951,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return 0; h = cx18_find_handle(cx); if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_PAUSE\n"); + CX18_ERR("Can't find valid task handle for V4L2_ENC_CMD_PAUSE\n"); return -EBADFD; } cx18_mute(cx); @@ -968,8 +967,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return 0; h = cx18_find_handle(cx); if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_RESUME\n"); + CX18_ERR("Can't find valid task handle for V4L2_ENC_CMD_RESUME\n"); return -EBADFD; } cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); diff --git a/drivers/media/pci/cx18/cx18-irq.c b/drivers/media/pci/cx18/cx18-irq.c index 80edfe93a3d8..361426485e98 100644 --- a/drivers/media/pci/cx18/cx18-irq.c +++ b/drivers/media/pci/cx18/cx18-irq.c @@ -59,8 +59,8 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); if (sw1 || sw2 || hw2) - CX18_DEBUG_HI_IRQ("received interrupts " - "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); + CX18_DEBUG_HI_IRQ("received interrupts SW1: %x SW2: %x HW2: %x\n", + sw1, sw2, hw2); /* * SW1 responses have to happen first. The sending XPU times out the diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c index 1f8aa9a749a1..d3cf3588879f 100644 --- a/drivers/media/pci/cx18/cx18-mailbox.c +++ b/drivers/media/pci/cx18/cx18-mailbox.c @@ -123,8 +123,8 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) if (!(cx18_debug & CX18_DBGFLG_API)) return; - CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s" - "\n", name, mb->request, mb->ack, mb->cmd, mb->error, + CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s\n", + name, mb->request, mb->ack, mb->cmd, mb->error, u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr)); } @@ -255,8 +255,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) s = cx18_handle_to_stream(cx, handle); if (s == NULL) { - CX18_WARN("Got DMA done notification for unknown/inactive" - " handle %d, %s mailbox seq no %d\n", handle, + CX18_WARN("Got DMA done notification for unknown/inactive handle %d, %s mailbox seq no %d\n", + handle, (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ? "stale" : "good", mb->request); return; @@ -290,9 +290,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && !(id >= s->mdl_base_idx && id < (s->mdl_base_idx + s->buffers))) { - CX18_WARN("Fell behind! Ignoring stale mailbox with " - " inconsistent data. Lost MDL for mailbox " - "seq no %d\n", mb->request); + CX18_WARN("Fell behind! Ignoring stale mailbox with inconsistent data. Lost MDL for mailbox seq no %d\n", + mb->request); break; } mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used); @@ -418,9 +417,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order) /* Don't ack if the RPU has gotten impatient and timed us out */ if (req != cx18_readl(cx, &ack_mb->request) || req == cx18_readl(cx, &ack_mb->ack)) { - CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " - "incoming %s to EPU mailbox (sequence no. %u) " - "while processing\n", + CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our incoming %s to EPU mailbox (sequence no. %u) while processing\n", rpu_str[order->rpu], rpu_str[order->rpu], req); order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC; return; @@ -555,8 +552,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) order = alloc_in_work_order_irq(cx); if (order == NULL) { - CX18_WARN("Unable to find blank work order form to schedule " - "incoming mailbox command processing\n"); + CX18_WARN("Unable to find blank work order form to schedule incoming mailbox command processing\n"); return; } @@ -573,9 +569,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i); if (order_mb->request == order_mb->ack) { - CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " - "incoming %s to EPU mailbox (sequence no. %u)" - "\n", + CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our incoming %s to EPU mailbox (sequence no. %u)\n", rpu_str[rpu], rpu_str[rpu], order_mb->request); if (cx18_debug & CX18_DBGFLG_WARN) dump_mb(cx, order_mb, "incoming"); @@ -663,8 +657,8 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) if (req != ack) { /* waited long enough, make the mbox "not busy" from our end */ cx18_writel(cx, req, &mb->ack); - CX18_ERR("mbox was found stuck busy when setting up for %s; " - "clearing busy and trying to proceed\n", info->name); + CX18_ERR("mbox was found stuck busy when setting up for %s; clearing busy and trying to proceed\n", + info->name); } else if (ret != timeout) CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n", jiffies_to_msecs(timeout-ret)); @@ -707,14 +701,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) mutex_unlock(mb_lock); if (ret >= timeout) { /* Timed out */ - CX18_DEBUG_WARN("sending %s timed out waiting %d msecs " - "for RPU acknowledgement\n", + CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU acknowledgment\n", info->name, jiffies_to_msecs(ret)); } else { - CX18_DEBUG_WARN("woken up before mailbox ack was ready " - "after submitting %s to RPU. only " - "waited %d msecs on req %u but awakened" - " with unmatched ack %u\n", + CX18_DEBUG_WARN("woken up before mailbox ack was ready after submitting %s to RPU. only waited %d msecs on req %u but awakened with unmatched ack %u\n", info->name, jiffies_to_msecs(ret), req, ack); @@ -723,8 +713,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) } if (ret >= timeout) - CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment " - "sending %s; timed out waiting %d msecs\n", + CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment sending %s; timed out waiting %d msecs\n", info->name, jiffies_to_msecs(ret)); else CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c index 2a247d264b87..13e96d6055eb 100644 --- a/drivers/media/pci/cx18/cx18-queue.c +++ b/drivers/media/pci/cx18/cx18-queue.c @@ -164,9 +164,8 @@ struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id, mdl->skipped++; if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) { /* mdl must have fallen out of rotation */ - CX18_WARN("Skipped %s, MDL %d, %d " - "times - it must have dropped out of " - "rotation\n", s->name, mdl->id, + CX18_WARN("Skipped %s, MDL %d, %d times - it must have dropped out of rotation\n", + s->name, mdl->id, mdl->skipped); /* Sweep it up to put it back into rotation */ list_move_tail(&mdl->list, &sweep_up); @@ -352,8 +351,7 @@ int cx18_stream_alloc(struct cx18_stream *s) if (s->buffers == 0) return 0; - CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers " - "(%d.%02d kB total)\n", + CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%d.%02d kB total)\n", s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024, (s->buffers * s->buf_size * 100 / 1024) % 100); diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index f3802ec1b383..7f699f0ee76c 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -353,8 +353,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) if (cx->card->hw_all & CX18_HW_DVB) { s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL); if (s->dvb == NULL) { - CX18_ERR("Couldn't allocate cx18_dvb structure" - " for %s\n", s->name); + CX18_ERR("Couldn't allocate cx18_dvb structure for %s\n", + s->name); return -ENOMEM; } } else { @@ -462,8 +462,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) case VFL_TYPE_VBI: if (cx->stream_buffers[type]) - CX18_INFO("Registered device %s for %s " - "(%d x %d bytes)\n", + CX18_INFO("Registered device %s for %s (%d x %d bytes)\n", name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type]); else -- cgit v1.2.3 From 07ab29e11696cf05c3563479bfc838c28a03d606 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:03 -0200 Subject: [media] cx23885: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cimax2.c | 7 ++----- drivers/media/pci/cx23885/cx23885-417.c | 18 +++++++----------- drivers/media/pci/cx23885/cx23885-alsa.c | 15 +++++++-------- drivers/media/pci/cx23885/cx23885-cards.c | 8 +++----- drivers/media/pci/cx23885/cx23885-core.c | 15 +++++++-------- drivers/media/pci/cx23885/cx23885-dvb.c | 3 +-- drivers/media/pci/cx23885/cx23885-video.c | 3 +-- drivers/media/pci/cx23885/cx23888-ir.c | 7 +++---- 8 files changed, 31 insertions(+), 45 deletions(-) diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c index 631e4f24aea6..d644c65622e2 100644 --- a/drivers/media/pci/cx23885/cimax2.c +++ b/drivers/media/pci/cx23885/cimax2.c @@ -365,11 +365,8 @@ static void netup_read_ci_status(struct work_struct *work) if (ret != 0) return; - ci_dbg_print("%s: Slot Status Addr=[0x%04x], " - "Reg=[0x%02x], data=%02x, " - "TS config = %02x\n", __func__, - state->ci_i2c_addr, 0, buf[0], - buf[0]); + ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, TS config = %02x\n", + __func__, state->ci_i2c_addr, 0, buf[0], buf[0]); if (buf[0] & 1) diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index da892f3e3c29..0c122585a1f0 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -770,9 +770,8 @@ static int cx23885_mbox_func(void *priv, mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); if (value != 0x12345678) { printk(KERN_ERR - "Firmware and/or mailbox pointer not initialized " - "or corrupted, signature = 0x%x, cmd = %s\n", value, - cmd_to_str(command)); + "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n", + value, cmd_to_str(command)); return -1; } @@ -781,8 +780,8 @@ static int cx23885_mbox_func(void *priv, */ mc417_memory_read(dev, dev->cx23417_mailbox, &flag); if (flag) { - printk(KERN_ERR "ERROR: Mailbox appears to be in use " - "(%x), cmd = %s\n", flag, cmd_to_str(command)); + printk(KERN_ERR "ERROR: Mailbox appears to be in use (%x), cmd = %s\n", + flag, cmd_to_str(command)); return -1; } @@ -935,14 +934,12 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) printk(KERN_ERR "ERROR: Hotplug firmware request failed (%s).\n", CX23885_FIRM_IMAGE_NAME); - printk(KERN_ERR "Please fix your hotplug setup, the board will " - "not work without firmware loaded!\n"); + printk(KERN_ERR "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { - printk(KERN_ERR "ERROR: Firmware size mismatch " - "(have %zu, expected %d)\n", + printk(KERN_ERR "ERROR: Firmware size mismatch (have %zu, expected %d)\n", firmware->size, CX23885_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; @@ -1077,8 +1074,7 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder) retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" - "version failed!\n"); + printk(KERN_ERR "ERROR: cx23417 firmware get encoder :version failed!\n"); return -1; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index 6115d4e148ba..9d2a4e2dc54f 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -186,8 +186,8 @@ static int cx23885_start_audio_dma(struct cx23885_audio_dev *chip) cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); atomic_set(&chip->count, 0); - dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d " - "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start+12)>>1, + dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n", + buf->bpl, cx_read(audio_ch->cmds_start+12)>>1, chip->num_periods, buf->bpl * chip->num_periods); /* Enables corresponding bits at AUD_INT_STAT */ @@ -327,8 +327,7 @@ static int snd_cx23885_pcm_open(struct snd_pcm_substream *substream) int err; if (!chip) { - printk(KERN_ERR "BUG: cx23885 can't find device struct." - " Can't proceed with open\n"); + printk(KERN_ERR "BUG: cx23885 can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -555,8 +554,8 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) return NULL; if (dev->sram_channels[AUDIO_SRAM_CHANNEL].cmds_start == 0) { - printk(KERN_WARNING "%s(): Missing SRAM channel configuration " - "for analog TV Audio\n", __func__); + printk(KERN_WARNING "%s(): Missing SRAM channel configuration for analog TV Audio\n", + __func__); return NULL; } @@ -590,8 +589,8 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) error: snd_card_free(card); - printk(KERN_ERR "%s(): Failed to register analog " - "audio adapter\n", __func__); + printk(KERN_ERR "%s(): Failed to register analog audio adapter\n", + __func__); return NULL; } diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 99ba8d6328f0..e2c4edbfbdb7 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -1304,8 +1304,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) */ break; default: - printk(KERN_WARNING "%s: warning: " - "unknown hauppauge model #%d\n", + printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); break; } @@ -2342,9 +2341,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) ret = request_firmware(&fw, filename, &dev->pci->dev); if (ret != 0) - printk(KERN_ERR "did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details " - "on firmware-problems.", filename); + printk(KERN_ERR "did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems.", + filename); else altera_init(&netup_config, fw); diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index c86b1093ab99..5020a60a4f1f 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -915,8 +915,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_init_tsport(dev, &dev->ts2, 2); if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for " - "subsystem: %04x:%04x\n", + printk(KERN_ERR "CORE %s No more PCIe resources for subsystem: %04x:%04x\n", dev->name, dev->pci->subsystem_vendor, dev->pci->subsystem_device); @@ -980,8 +979,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { if (cx23885_video_register(dev) < 0) { - printk(KERN_ERR "%s() Failed to register analog " - "video adapters on VID_A\n", __func__); + printk(KERN_ERR "%s() Failed to register analog video adapters on VID_A\n", + __func__); } } @@ -1579,8 +1578,8 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status) (status & VID_B_MSK_VBI_SYNC) || (status & VID_B_MSK_OF) || (status & VID_B_MSK_VBI_OF)) { - printk(KERN_ERR "%s: V4L mpeg risc op code error, status " - "= 0x%x\n", dev->name, status); + printk(KERN_ERR "%s: V4L mpeg risc op code error, status = 0x%x\n", + dev->name, status); if (status & VID_B_MSK_BAD_PKT) dprintk(1, " VID_B_MSK_BAD_PKT\n"); if (status & VID_B_MSK_OPC_ERR) @@ -1995,8 +1994,8 @@ static int cx23885_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, + printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev, 0)); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 818f3c2fc98d..42413fa423b4 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2482,8 +2482,7 @@ static int dvb_register(struct cx23885_tsport *port) break; default: - printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " - " isn't supported yet\n", + printk(KERN_INFO "%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); break; } diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 33d168ef278d..92ff452e5886 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -1065,8 +1065,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) } if (status & VID_BC_MSK_SYNC) - dprintk(7, " (VID_BC_MSK_SYNC 0x%08x) " - "video lines miss-match\n", + dprintk(7, " (VID_BC_MSK_SYNC 0x%08x) video lines miss-match\n", VID_BC_MSK_SYNC); if (status & VID_BC_MSK_OF) diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index c1aa888af705..3115cfddab95 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -1015,8 +1015,8 @@ static int cx23888_ir_log_status(struct v4l2_subdev *sd) j = 0; break; } - v4l2_info(sd, "\tNext carrier edge window: 16 clocks " - "-%1d/+%1d, %u to %u Hz\n", i, j, + v4l2_info(sd, "\tNext carrier edge window: 16 clocks -%1d/+%1d, %u to %u Hz\n", + i, j, clock_divider_to_freq(rxclk, 16 + j), clock_divider_to_freq(rxclk, 16 - i)); } @@ -1026,8 +1026,7 @@ static int cx23888_ir_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "\tLow pass filter: %s\n", filtr ? "enabled" : "disabled"); if (filtr) - v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, " - "%u ns\n", + v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, %u ns\n", lpf_count_to_us(filtr), lpf_count_to_ns(filtr)); v4l2_info(sd, "\tPulse width timer timed-out: %s\n", -- cgit v1.2.3 From e318e584f70f60170809dd975bbd480fc06cc5e4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:04 -0200 Subject: [media] cx88: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 15 ++++++--------- drivers/media/pci/cx88/cx88-cards.c | 14 ++++++-------- drivers/media/pci/cx88/cx88-dsp.c | 12 ++++++------ drivers/media/pci/cx88/cx88-dvb.c | 6 ++---- drivers/media/pci/cx88/cx88-i2c.c | 3 +-- drivers/media/pci/cx88/cx88-mpeg.c | 15 +++++++-------- drivers/media/pci/cx88/cx88-tvaudio.c | 6 ++---- drivers/media/pci/cx88/cx88-video.c | 4 ++-- 8 files changed, 32 insertions(+), 43 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 723f06462104..495f9a0569e0 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -120,9 +120,7 @@ MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_LICENSE("GPL"); MODULE_VERSION(CX88_VERSION); -MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," - "{{Conexant,23882}," - "{{Conexant,23883}"); +MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}"); static unsigned int debug; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages"); @@ -154,8 +152,8 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET); atomic_set(&chip->count, 0); - dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d " - "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1, + dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n", + buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1, chip->num_periods, buf->bpl * chip->num_periods); /* Enables corresponding bits at AUD_INT_STAT */ @@ -425,8 +423,7 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) int err; if (!chip) { - printk(KERN_ERR "BUG: cx88 can't find device struct." - " Can't proceed with open\n"); + printk(KERN_ERR "BUG: cx88 can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -914,8 +911,8 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, /* print pci info */ pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat); - dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", core->name, devno, + dprintk(1, "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + core->name, devno, pci_name(pci), pci->revision, pci->irq, pci_lat, (unsigned long long)pci_resource_start(pci,0)); diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 8f2556ec3971..31295b36dafc 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -2847,8 +2847,7 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) break; } - info_printk(core, "Leadtek Winfast 2000XP Expert config: " - "tuner=%d, eeprom[0]=0x%02x\n", + info_printk(core, "Leadtek Winfast 2000XP Expert config: tuner=%d, eeprom[0]=0x%02x\n", core->board.tuner_type, eeprom_data[0]); } @@ -3107,8 +3106,8 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) msg.len = (i != 12 ? 5 : 2); err = i2c_transfer(&core->i2c_adap, &msg, 1); if (err != 1) { - warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d " - "failed (err = %d)!\n", i, err); + warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", + i, err); return; } } @@ -3284,8 +3283,7 @@ static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) "%s: version might help as well.\n", core->name,core->name,core->name,core->name); } - err_printk(core, "Here is a list of valid choices for the card= " - "insmod option:\n"); + err_printk(core, "Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) printk(KERN_ERR "%s: card=%d -> %s\n", core->name, i, cx88_boards[i].name); @@ -3510,8 +3508,8 @@ static void cx88_card_setup(struct cx88_core *core) for (i = 0; i < ARRAY_SIZE(buffer); i++) if (2 != i2c_master_send(&core->i2c_client, buffer[i],2)) - warn_printk(core, "Unable to enable " - "tuner(%i).\n", i); + warn_printk(core, "Unable to enable tuner(%i).\n", + i); } break; case CX88_BOARD_MSI_TVANYWHERE_MASTER: diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index a9907265ff66..7fafd132ccaf 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -186,8 +186,8 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) dual = freq_magnitude(x, N, dual_freq); noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END); - dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, " - "noise=%d\n", carrier, stereo, dual, noise); + dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, noise=%d\n", + carrier, stereo, dual, noise); if (stereo > dual) ret = V4L2_TUNER_SUB_STEREO; @@ -222,8 +222,8 @@ static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N) s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP); s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF); s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL); - dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d" - "\n", dual_ref, dual, sap_ref, sap); + dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d\n", + dual_ref, dual, sap_ref, sap); /* FIXME: Currently not supported */ return UNSET; } @@ -241,8 +241,8 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) u32 current_address = cx_read(srch->ptr1_reg); u32 offset = (current_address - srch->fifo_start + bpl); - dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), " - "sample_count=%d, aud_intstat=%08x\n", current_address, + dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), sample_count=%d, aud_intstat=%08x\n", + current_address, current_address - srch->fifo_start, sample_count, cx_read(MO_AUD_INTSTAT)); diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index ac2392d8887a..fe5fd2a4650b 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -625,8 +625,7 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) return -EINVAL; if (!fe0->dvb.frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. " - "Can't attach xc3028\n", + printk(KERN_ERR "%s/2: dvb frontend not attached. Can't attach xc3028\n", dev->core->name); return -EINVAL; } @@ -665,8 +664,7 @@ static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) return -EINVAL; if (!fe0->dvb.frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. " - "Can't attach xc4000\n", + printk(KERN_ERR "%s/2: dvb frontend not attached. Can't attach xc4000\n", dev->core->name); return -EINVAL; } diff --git a/drivers/media/pci/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c index cf2d69615838..804f7417d19f 100644 --- a/drivers/media/pci/cx88/cx88-i2c.c +++ b/drivers/media/pci/cx88/cx88-i2c.c @@ -45,8 +45,7 @@ MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); static unsigned int i2c_udelay = 5; module_param(i2c_udelay, int, 0644); -MODULE_PARM_DESC(i2c_udelay,"i2c delay at insmod time, in usecs " - "(should be 5 or higher). Lower value means higher bus speed."); +MODULE_PARM_DESC(i2c_udelay, "i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); #define dprintk(level,fmt, arg...) if (i2c_debug >= level) \ printk(KERN_DEBUG "%s: " fmt, core->name , ## arg) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 245357adbc25..86b46b62d985 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -401,8 +401,8 @@ static int cx8802_init_common(struct cx8802_dev *dev) dev->pci_rev = dev->pci->revision; pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->core->name, + printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + dev->core->name, pci_name(dev->pci), dev->pci_rev, dev->pci->irq, dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0)); @@ -690,8 +690,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) list_del(&d->drvlist); kfree(d); } else - printk(KERN_ERR "%s/2: cx8802 driver remove " - "failed (%d)\n", dev->core->name, err); + printk(KERN_ERR "%s/2: cx8802 driver remove failed (%d)\n", + dev->core->name, err); } mutex_unlock(&dev->core->lock); @@ -768,8 +768,7 @@ static void cx8802_remove(struct pci_dev *pci_dev) struct cx8802_driver *drv, *tmp; int err; - printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver " - "while cx8802 sub-drivers still loaded?!\n", + printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver while cx8802 sub-drivers still loaded?!\n", dev->core->name); list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { @@ -777,8 +776,8 @@ static void cx8802_remove(struct pci_dev *pci_dev) if (err == 0) { list_del(&drv->drvlist); } else - printk(KERN_ERR "%s/2: cx8802 driver remove " - "failed (%d)\n", dev->core->name, err); + printk(KERN_ERR "%s/2: cx8802 driver remove failed (%d)\n", + dev->core->name, err); kfree(drv); } } diff --git a/drivers/media/pci/cx88/cx88-tvaudio.c b/drivers/media/pci/cx88/cx88-tvaudio.c index 6bbce6ad6295..dd8e6f324204 100644 --- a/drivers/media/pci/cx88/cx88-tvaudio.c +++ b/drivers/media/pci/cx88/cx88-tvaudio.c @@ -62,8 +62,7 @@ MODULE_PARM_DESC(always_analog,"force analog audio out"); static unsigned int radio_deemphasis; module_param(radio_deemphasis,int,0644); -MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, " - "0=None, 1=50us (elsewhere), 2=75us (USA)"); +MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, 0=None, 1=50us (elsewhere), 2=75us (USA)"); #define dprintk(fmt, arg...) if (audio_debug) \ printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) @@ -976,8 +975,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) } if (UNSET != ctl) { - dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x " - "[status=0x%x,ctl=0x%x,vol=0x%x]\n", + dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x [status=0x%x,ctl=0x%x,vol=0x%x]\n", mask, ctl, cx_read(AUD_STATUS), cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL)); cx_andor(AUD_CTL, mask, ctl); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index d83eb3b10f54..418e2db40b39 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1307,8 +1307,8 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", core->name, + printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + core->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); -- cgit v1.2.3 From 935747ff180594471b27e3bc776ab0cf93e525cf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:04 -0200 Subject: [media] ddbridge: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 18e3a4deee64..a6c9fe235974 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -824,8 +824,7 @@ static int dvb_input_attach(struct ddb_input *input) &input->port->dev->pdev->dev, adapter_nr); if (ret < 0) { - printk(KERN_ERR "ddbridge: Could not register adapter." - "Check if you enabled enough adapters in dvb-core!\n"); + printk(KERN_ERR "ddbridge: Could not register adapter.Check if you enabled enough adapters in dvb-core!\n"); return ret; } input->attached = 1; @@ -1730,8 +1729,7 @@ static __init int module_init_ddbridge(void) { int ret; - printk(KERN_INFO "Digital Devices PCIE bridge driver, " - "Copyright (C) 2010-11 Digital Devices GmbH\n"); + printk(KERN_INFO "Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n"); ret = ddb_class_create(); if (ret < 0) -- cgit v1.2.3 From 0e8aebb52d38298720229d2a77476be23188a208 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:04 -0200 Subject: [media] dm1105: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/dm1105/dm1105.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 5dd504741b12..a589aa78d1d9 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -315,8 +315,7 @@ static void dm1105_card_list(struct pci_dev *pci) "dm1105: Updating to the latest version might help\n" "dm1105: as well.\n"); } - printk(KERN_ERR "Here is a list of valid choices for the card= " - "insmod option:\n"); + printk(KERN_ERR "Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++) printk(KERN_ERR "dm1105: card=%d -> %s\n", i, dm1105_boards[i].name); -- cgit v1.2.3 From 67ccf860a0181e0af627fa873990fa98a6c4036d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:05 -0200 Subject: [media] ivtv: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-alsa-main.c | 12 +++++------ drivers/media/pci/ivtv/ivtv-driver.c | 37 ++++++++++++--------------------- drivers/media/pci/ivtv/ivtv-firmware.c | 4 ++-- drivers/media/pci/ivtv/ivtv-yuv.c | 8 +++---- drivers/media/pci/ivtv/ivtvfb.c | 3 +-- 5 files changed, 26 insertions(+), 38 deletions(-) diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index 8a86b61a896d..374f45f81ab3 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c @@ -177,8 +177,8 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev) #if 0 ret = snd_ivtv_mixer_create(itvsc); if (ret) { - IVTV_ALSA_WARN("%s: snd_ivtv_mixer_create() failed with err %d:" - " proceeding anyway\n", __func__, ret); + IVTV_ALSA_WARN("%s: snd_ivtv_mixer_create() failed with err %d: proceeding anyway\n", + __func__, ret); } #endif @@ -235,8 +235,8 @@ static int ivtv_alsa_load(struct ivtv *itv) s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; if (s->vdev.v4l2_dev == NULL) { - IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " - "skipping\n", __func__); + IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - skipping\n", + __func__); return 0; } @@ -250,8 +250,8 @@ static int ivtv_alsa_load(struct ivtv *itv) IVTV_ALSA_ERR("%s: failed to create struct snd_ivtv_card\n", __func__); } else { - IVTV_DEBUG_ALSA_INFO("%s: created ivtv ALSA interface instance " - "\n", __func__); + IVTV_DEBUG_ALSA_INFO("%s: created ivtv ALSA interface instance \n", + __func__); } return 0; } diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index ee48c3e09de4..0a3b80a4bd69 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -885,8 +885,8 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && ivtv_pci_latency) { - IVTV_INFO("Unreasonably low latency timer, " - "setting to 64 (was %d)\n", pci_latency); + IVTV_INFO("Unreasonably low latency timer, setting to 64 (was %d)\n", + pci_latency); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); } @@ -896,8 +896,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, these problems. */ pci_write_config_dword(pdev, 0x40, 0xffff); - IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%llx\n", + IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, irq: %d, latency: %d, memory: 0x%llx\n", pdev->device, pdev->revision, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq, pci_latency, (u64)itv->base_addr); @@ -1047,13 +1046,10 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); if (!itv->enc_mem) { - IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " - "encoder memory\n"); - IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of " - "vmalloc address space for this window\n"); + IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 encoder memory\n"); + IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of vmalloc address space for this window\n"); IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); - IVTV_ERR("Use the vmalloc= kernel command line option to set " - "VmallocTotal to a larger value\n"); + IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n"); retval = -ENOMEM; goto free_mem; } @@ -1064,14 +1060,10 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); if (!itv->dec_mem) { - IVTV_ERR("ioremap failed. Can't get a window into " - "CX23415 decoder memory\n"); - IVTV_ERR("Each capture card with a CX23415 needs 8 MB " - "of vmalloc address space for this window\n"); - IVTV_ERR("Check the output of 'grep Vmalloc " - "/proc/meminfo'\n"); - IVTV_ERR("Use the vmalloc= kernel command line option " - "to set VmallocTotal to a larger value\n"); + IVTV_ERR("ioremap failed. Can't get a window into CX23415 decoder memory\n"); + IVTV_ERR("Each capture card with a CX23415 needs 8 MB of vmalloc address space for this window\n"); + IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); + IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n"); retval = -ENOMEM; goto free_mem; } @@ -1086,13 +1078,10 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) itv->reg_mem = ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (!itv->reg_mem) { - IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 " - "register space\n"); - IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of " - "vmalloc address space for this window\n"); + IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 register space\n"); + IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of vmalloc address space for this window\n"); IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); - IVTV_ERR("Use the vmalloc= kernel command line option to set " - "VmallocTotal to a larger value\n"); + IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n"); retval = -ENOMEM; goto free_io; } diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c index 5b3095f65dce..ba279fdb3df8 100644 --- a/drivers/media/pci/ivtv/ivtv-firmware.c +++ b/drivers/media/pci/ivtv/ivtv-firmware.c @@ -376,8 +376,8 @@ int ivtv_firmware_check(struct ivtv *itv, char *where) /* If something failed & currently idle, try to reload */ if (res && !atomic_read(&itv->capturing) && !atomic_read(&itv->decoding)) { - IVTV_INFO("Detected in %s that firmware had failed - " - "Reloading\n", where); + IVTV_INFO("Detected in %s that firmware had failed - Reloading\n", + where); res = ivtv_firmware_restart(itv); /* * Even if restarted ok, still signal a problem had occurred. diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c index b094054cda6e..a61f63234e1f 100644 --- a/drivers/media/pci/ivtv/ivtv-yuv.c +++ b/drivers/media/pci/ivtv/ivtv-yuv.c @@ -88,8 +88,8 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, if (y_pages == y_dma.page_count) { IVTV_DEBUG_WARN - ("failed to map uv user pages, returned %d " - "expecting %d\n", uv_pages, uv_dma.page_count); + ("failed to map uv user pages, returned %d expecting %d\n", + uv_pages, uv_dma.page_count); if (uv_pages >= 0) { for (i = 0; i < uv_pages; i++) @@ -100,8 +100,8 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, } } else { IVTV_DEBUG_WARN - ("failed to map y user pages, returned %d " - "expecting %d\n", y_pages, y_dma.page_count); + ("failed to map y user pages, returned %d expecting %d\n", + y_pages, y_dma.page_count); } if (y_pages >= 0) { for (i = 0; i < y_pages; i++) diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 8b95eefb610b..612a8402cf4d 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -293,8 +293,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, /* Map User DMA */ if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) { mutex_unlock(&itv->udma.lock); - IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, " - "Error with get_user_pages: %d bytes, %d pages returned\n", + IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with get_user_pages: %d bytes, %d pages returned\n", size_in_bytes, itv->udma.page_count); /* get_user_pages must have failed completely */ -- cgit v1.2.3 From f8a3dcb5a927141610e30d01e5782ba4a4516980 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:05 -0200 Subject: [media] meye: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/meye/meye.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index ba887e8e1b17..11d81389ab1e 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -60,8 +60,7 @@ MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)"); /* size of a grab buffer */ static unsigned int gbufsize = MEYE_MAX_BUFSIZE; module_param(gbufsize, int, 0444); -MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400" - " (will be rounded up to a page multiple)"); +MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400 (will be rounded up to a page multiple)"); /* /dev/videoX registration number */ static int video_nr = -1; @@ -1261,8 +1260,7 @@ static int vidioc_reqbufs(struct file *file, void *fh, meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize); if (!meye.grab_fbuffer) { - printk(KERN_ERR "meye: v4l framebuffer allocation" - " failed\n"); + printk(KERN_ERR "meye: v4l framebuffer allocation failed\n"); mutex_unlock(&meye.lock); return -ENOMEM; } @@ -1659,8 +1657,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) ret = -EIO; if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { v4l2_err(v4l2_dev, "meye: unable to power on the camera\n"); - v4l2_err(v4l2_dev, "meye: did you enable the camera in " - "sonypi using the module options ?\n"); + v4l2_err(v4l2_dev, "meye: did you enable the camera in sonypi using the module options ?\n"); goto outsonypienable; } @@ -1834,8 +1831,7 @@ static int __init meye_init(void) if (gbufsize > MEYE_MAX_BUFSIZE) gbufsize = MEYE_MAX_BUFSIZE; gbufsize = PAGE_ALIGN(gbufsize); - printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) " - "for capture\n", + printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) for capture\n", gbuffers, gbufsize / 1024, gbuffers * gbufsize / 1024); return pci_register_driver(&meye_driver); -- cgit v1.2.3 From 2d96b44f0abfd429816d66148b75bad84a625f3b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:06 -0200 Subject: [media] pt1: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pt1/pt1.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index e7e4428109c3..d5ee82aee9e8 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -282,13 +282,12 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page) continue; if (upacket >> 24 & 1) - printk_ratelimited(KERN_INFO "earth-pt1: device " - "buffer overflowing. table[%d] buf[%d]\n", + printk_ratelimited(KERN_INFO "earth-pt1: device buffer overflowing. table[%d] buf[%d]\n", pt1->table_index, pt1->buf_index); sc = upacket >> 26 & 0x7; if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7)) - printk_ratelimited(KERN_INFO "earth-pt1: data loss" - " in streamID(adapter)[%d]\n", index); + printk_ratelimited(KERN_INFO "earth-pt1: data loss in streamID(adapter)[%d]\n", + index); adap->st_count = sc; buf = adap->buf; -- cgit v1.2.3 From 395eff951a9dc6d6d08d9afe27f2aa975bc23c39 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:06 -0200 Subject: [media] saa7134: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 3 +-- drivers/media/pci/saa7134/saa7134-cards.c | 8 +++---- drivers/media/pci/saa7134/saa7134-core.c | 39 ++++++++++++++----------------- drivers/media/pci/saa7134/saa7134-dvb.c | 32 ++++++++++++------------- drivers/media/pci/saa7134/saa7134-input.c | 13 ++++------- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index dc0e2fc5f68b..8a35ecfb75e3 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -813,8 +813,7 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) int amux, err; if (!saa7134) { - pr_err("BUG: saa7134 can't find device struct." - " Can't proceed with open\n"); + pr_err("BUG: saa7134 can't find device struct. Can't proceed with open\n"); return -ENODEV; } dev = saa7134->dev; diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index c480a7e87593..2b60af493de4 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7341,8 +7341,8 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ break; default: - pr_warn("%s: warning: " - "unknown hauppauge model #%d\n", dev->name, tv.model); + pr_warn("%s: warning: unknown hauppauge model #%d\n", + dev->name, tv.model); break; } @@ -7920,8 +7920,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) msg.addr = 0x0b; msg.len = 1; if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) { - pr_warn("%s: send wake up byte to pic16C505" - "(IR chip) failed\n", dev->name); + pr_warn("%s: send wake up byte to pic16C505(IR chip) failed\n", + dev->name); } else { msg.flags = I2C_M_RD; rc = i2c_transfer(&dev->i2c_adap, &msg, 1); diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index ffb66a9ae23e..7d6bb5c9343f 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -66,8 +66,7 @@ MODULE_PARM_DESC(latency,"pci latency timer"); int saa7134_no_overlay=-1; module_param_named(no_overlay, saa7134_no_overlay, int, 0444); -MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" - " [some VIA/SIS chipsets are known to have problem with overlay]"); +MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]"); bool saa7134_userptr; module_param(saa7134_userptr, bool, 0644); @@ -619,25 +618,25 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) print_irqstatus(dev,loop,report,status); if (report & SAA7134_IRQ_REPORT_PE) { /* disable all parity error */ - pr_warn("%s/irq: looping -- " - "clearing PE (parity error!) enable bit\n",dev->name); + pr_warn("%s/irq: looping -- clearing PE (parity error!) enable bit\n", + dev->name); saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); } else if (report & SAA7134_IRQ_REPORT_GPIO16) { /* disable gpio16 IRQ */ - pr_warn("%s/irq: looping -- " - "clearing GPIO16 enable bit\n",dev->name); + pr_warn("%s/irq: looping -- clearing GPIO16 enable bit\n", + dev->name); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_P); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_N); } else if (report & SAA7134_IRQ_REPORT_GPIO18) { /* disable gpio18 IRQs */ - pr_warn("%s/irq: looping -- " - "clearing GPIO18 enable bit\n",dev->name); + pr_warn("%s/irq: looping -- clearing GPIO18 enable bit\n", + dev->name); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_N); } else { /* disable all irqs */ - pr_warn("%s/irq: looping -- " - "clearing all enable bits\n",dev->name); + pr_warn("%s/irq: looping -- clearing all enable bits\n", + dev->name); saa_writel(SAA7134_IRQ1,0); saa_writel(SAA7134_IRQ2,0); } @@ -1081,18 +1080,14 @@ static int saa7134_initdev(struct pci_dev *pci_dev, } #endif if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) { - pr_info("%s: quirk: this driver and your " - "chipset may not work together" - " in overlay mode.\n",dev->name); + pr_info("%s: quirk: this driver and your chipset may not work together in overlay mode.\n", + dev->name); if (!saa7134_no_overlay) { - pr_info("%s: quirk: overlay " - "mode will be disabled.\n", + pr_info("%s: quirk: overlay mode will be disabled.\n", dev->name); saa7134_no_overlay = 1; } else { - pr_info("%s: quirk: overlay " - "mode will be forced. Use this" - " option at your own risk.\n", + pr_info("%s: quirk: overlay mode will be forced. Use this option at your own risk.\n", dev->name); } } @@ -1106,10 +1101,10 @@ static int saa7134_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - pr_info("%s: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); + pr_info("%s: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, + dev->pci_lat, + (unsigned long long)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); if (err) { diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 59a4b5f7724e..598b8bbfe726 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -1449,8 +1449,8 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - pr_warn("%s: Medion Quadro, no tda826x " - "found !\n", __func__); + pr_warn("%s: Medion Quadro, no tda826x found !\n", + __func__); goto detach_frontend; } if (dev_id != 0x08) { @@ -1458,8 +1458,8 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - pr_warn("%s: Medion Quadro, no ISL6405 " - "found !\n", __func__); + pr_warn("%s: Medion Quadro, no ISL6405 found !\n", + __func__); goto detach_frontend; } if (dev_id == 0x07) { @@ -1629,8 +1629,8 @@ static int dvb_init(struct saa7134_dev *dev) struct dvb_frontend *fe; if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { - pr_warn("%s: MD7134 DVB-S, no SD1878 " - "found !\n", __func__); + pr_warn("%s: MD7134 DVB-S, no SD1878 found !\n", + __func__); goto detach_frontend; } /* we need to open the i2c gate (we know it exists) */ @@ -1638,8 +1638,8 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - pr_warn("%s: MD7134 DVB-S, no ISL6405 " - "found !\n", __func__); + pr_warn("%s: MD7134 DVB-S, no ISL6405 found !\n", + __func__); goto detach_frontend; } fe->ops.i2c_gate_ctrl(fe, 0); @@ -1670,14 +1670,14 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - pr_warn("%s: Asus Tiger 3in1, no " - "tda826x found!\n", __func__); + pr_warn("%s: Asus Tiger 3in1, no tda826x found!\n", + __func__); goto detach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { - pr_warn("%s: Asus Tiger 3in1, no lnbp21" - " found!\n", __func__); + pr_warn("%s: Asus Tiger 3in1, no lnbp21 found!\n", + __func__); goto detach_frontend; } } @@ -1695,14 +1695,14 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - pr_warn("%s: Asus My Cinema PS3-100, no " - "tda826x found!\n", __func__); + pr_warn("%s: Asus My Cinema PS3-100, no tda826x found!\n", + __func__); goto detach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { - pr_warn("%s: Asus My Cinema PS3-100, no lnbp21" - " found!\n", __func__); + pr_warn("%s: Asus My Cinema PS3-100, no lnbp21 found!\n", + __func__); goto detach_frontend; } } diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index eff52bbbfd66..823b75ed47e1 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -123,8 +123,7 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - ir_dbg(ir, "get_key_flydvb_trio: " - "ir->c->adapter->algo_data is NULL!\n"); + ir_dbg(ir, "get_key_flydvb_trio: ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -150,8 +149,8 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, msleep(10); continue; } - ir_dbg(ir, "send wake up byte to pic16C505 (IR chip)" - "failed %dx\n", attempt); + ir_dbg(ir, "send wake up byte to pic16C505 (IR chip)failed %dx\n", + attempt); return -EIO; } if (1 != i2c_master_recv(ir->c, &b, 1)) { @@ -174,8 +173,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol /* is needed to access GPIO. Used by the saa_readl macro. */ struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - ir_dbg(ir, "get_key_msi_tvanywhere_plus: " - "ir->c->adapter->algo_data is NULL!\n"); + ir_dbg(ir, "get_key_msi_tvanywhere_plus: ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -223,8 +221,7 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, /* is needed to access GPIO. Used by the saa_readl macro. */ struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - ir_dbg(ir, "get_key_kworld_pc150u: " - "ir->c->adapter->algo_data is NULL!\n"); + ir_dbg(ir, "get_key_kworld_pc150u: ir->c->adapter->algo_data is NULL!\n"); return -EIO; } -- cgit v1.2.3 From 24f711c135a71fd2afbb1f6dc2235d470f083880 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:07 -0200 Subject: [media] saa7164: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-buffer.c | 3 +- drivers/media/pci/saa7164/saa7164-bus.c | 4 +- drivers/media/pci/saa7164/saa7164-cards.c | 4 +- drivers/media/pci/saa7164/saa7164-cmd.c | 12 +++--- drivers/media/pci/saa7164/saa7164-core.c | 66 ++++++++++++----------------- drivers/media/pci/saa7164/saa7164-dvb.c | 34 +++++++-------- drivers/media/pci/saa7164/saa7164-encoder.c | 18 ++++---- drivers/media/pci/saa7164/saa7164-fw.c | 10 ++--- drivers/media/pci/saa7164/saa7164-vbi.c | 14 +++--- 9 files changed, 72 insertions(+), 93 deletions(-) diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c index f30758e24f5d..62c34504199d 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -218,8 +218,7 @@ int saa7164_buffer_activate(struct saa7164_buffer *buf, int i) saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma); saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0); - dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) " - "buf 0x%llx/%llx (0x%x/%x) nr=%d\n", + dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) buf 0x%llx/%llx (0x%x/%x) nr=%d\n", buf->idx, (u64)port->bufoffset + (i * sizeof(u32)), saa7164_readl(port->bufoffset + (sizeof(u32) * i)), diff --git a/drivers/media/pci/saa7164/saa7164-bus.c b/drivers/media/pci/saa7164/saa7164-bus.c index a18fe5d47238..e305c02f9dc9 100644 --- a/drivers/media/pci/saa7164/saa7164-bus.c +++ b/drivers/media/pci/saa7164/saa7164-bus.c @@ -427,8 +427,8 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp; if (bytes_to_read > write_distance) { - printk(KERN_ERR "%s() Invalid bus state, missing msg " - "or mangled ring, faulty H/W / bad code?\n", __func__); + printk(KERN_ERR "%s() Invalid bus state, missing msg or mangled ring, faulty H/W / bad code?\n", + __func__); ret = SAA_ERR_INVALID_COMMAND; goto out; } diff --git a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c index c2b738227f58..15a98c638c55 100644 --- a/drivers/media/pci/saa7164/saa7164-cards.c +++ b/drivers/media/pci/saa7164/saa7164-cards.c @@ -726,8 +726,8 @@ void saa7164_card_list(struct saa7164_dev *dev) dev->name, dev->name, dev->name, dev->name); } - printk(KERN_ERR "%s: Here are valid choices for the card= insmod " - "option:\n", dev->name); + printk(KERN_ERR "%s: Here are valid choices for the card= insmod option:\n", + dev->name); for (i = 0; i < saa7164_bcount; i++) printk(KERN_ERR "%s: card=%d -> %s\n", diff --git a/drivers/media/pci/saa7164/saa7164-cmd.c b/drivers/media/pci/saa7164/saa7164-cmd.c index 3285c37b4583..45951b3cc251 100644 --- a/drivers/media/pci/saa7164/saa7164-cmd.c +++ b/drivers/media/pci/saa7164/saa7164-cmd.c @@ -301,8 +301,8 @@ static int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) else saa7164_cmd_timeout_seqno(dev, seqno); - dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d " - "(signalled=%d)\n", __func__, seqno, r, + dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d (signalled=%d)\n", + __func__, seqno, r, dev->cmds[seqno].signalled); } else ret = SAA_OK; @@ -353,8 +353,8 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command, int ret; int safety = 0; - dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, " - "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id, + dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, sel = 0x%x)\n", + __func__, saa7164_unitid_name(dev, id), id, command, controlselector); if ((size == 0) || (buf == NULL)) { @@ -452,9 +452,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command, if (presponse_t->seqno != pcommand_t->seqno) { dprintk(DBGLVL_CMD, - "wrong event: seqno = %d, " - "expected seqno = %d, " - "will dequeue regardless\n", + "wrong event: seqno = %d, expected seqno = %d, will dequeue regardless\n", presponse_t->seqno, pcommand_t->seqno); ret = saa7164_cmd_dequeue(dev); diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 8bbd092fbe1d..03a1511a92be 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -710,9 +710,7 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id) } else { /* Find the function */ dprintk(DBGLVL_IRQ, - "%s() unhandled interrupt " - "reg 0x%x bit 0x%x " - "intid = 0x%x\n", + "%s() unhandled interrupt reg 0x%x bit 0x%x intid = 0x%x\n", __func__, i, bit, intid); } } @@ -767,13 +765,11 @@ void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr) { int i; - dprintk(1, "--------------------> " - "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); + dprintk(1, "--------------------> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"); for (i = 0; i < 0x100; i += 16) - dprintk(1, "region0[0x%08x] = " - "%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", i, + dprintk(1, "region0[0x%08x] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + i, (u8)saa7164_readb(addr + i + 0), (u8)saa7164_readb(addr + i + 1), (u8)saa7164_readb(addr + i + 2), @@ -825,8 +821,7 @@ static void saa7164_dump_hwdesc(struct saa7164_dev *dev) static void saa7164_dump_intfdesc(struct saa7164_dev *dev) { - dprintk(1, "@0x%p intfdesc " - "sizeof(struct tmComResInterfaceDescr) = %d bytes\n", + dprintk(1, "@0x%p intfdesc sizeof(struct tmComResInterfaceDescr) = %d bytes\n", &dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr)); dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength); @@ -1011,8 +1006,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_port_init(dev, SAA7164_PORT_VBI2); if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for " - "subsystem: %04x:%04x\n", + printk(KERN_ERR "CORE %s No more PCIe resources for subsystem: %04x:%04x\n", dev->name, dev->pci->subsystem_vendor, dev->pci->subsystem_device); @@ -1204,8 +1198,8 @@ static bool saa7164_enable_msi(struct pci_dev *pci_dev, struct saa7164_dev *dev) err = pci_enable_msi(pci_dev); if (err) { - printk(KERN_ERR "%s() Failed to enable MSI interrupt." - " Falling back to a shared IRQ\n", __func__); + printk(KERN_ERR "%s() Failed to enable MSI interrupt. Falling back to a shared IRQ\n", + __func__); return false; } @@ -1215,8 +1209,8 @@ static bool saa7164_enable_msi(struct pci_dev *pci_dev, struct saa7164_dev *dev) if (err) { /* fall back to legacy interrupt */ - printk(KERN_ERR "%s() Failed to get an MSI interrupt." - " Falling back to a shared IRQ\n", __func__); + printk(KERN_ERR "%s() Failed to get an MSI interrupt. Falling back to a shared IRQ\n", + __func__); pci_disable_msi(pci_dev); return false; } @@ -1256,8 +1250,8 @@ static int saa7164_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, + printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev, 0)); @@ -1307,8 +1301,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev, err = saa7164_downloadfirmware(dev); if (err < 0) { printk(KERN_ERR - "Failed to boot firmware, no features " - "registered\n"); + "Failed to boot firmware, no features registered\n"); goto fail_fw; } @@ -1327,8 +1320,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev, */ version = 0; if (saa7164_api_get_fw_version(dev, &version) == SAA_OK) - dprintk(1, "Bus is operating correctly using " - "version %d.%d.%d.%d (0x%x)\n", + dprintk(1, "Bus is operating correctly using version %d.%d.%d.%d (0x%x)\n", (version & 0x0000fc00) >> 10, (version & 0x000003e0) >> 5, (version & 0x0000001f), @@ -1356,45 +1348,43 @@ static int saa7164_initdev(struct pci_dev *pci_dev, /* Begin to create the video sub-systems and register funcs */ if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) { if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) { - printk(KERN_ERR "%s() Failed to register " - "dvb adapters on porta\n", + printk(KERN_ERR "%s() Failed to register dvb adapters on porta\n", __func__); } } if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) { if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "dvb adapters on portb\n", + printk(KERN_ERR"%s() Failed to register dvb adapters on portb\n", __func__); } } if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) { if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "mpeg encoder\n", __func__); + printk(KERN_ERR"%s() Failed to register mpeg encoder\n", + __func__); } } if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) { if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "mpeg encoder\n", __func__); + printk(KERN_ERR"%s() Failed to register mpeg encoder\n", + __func__); } } if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) { if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "vbi device\n", __func__); + printk(KERN_ERR"%s() Failed to register vbi device\n", + __func__); } } if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) { if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) { - printk(KERN_ERR"%s() Failed to register " - "vbi device\n", __func__); + printk(KERN_ERR"%s() Failed to register vbi device\n", + __func__); } } saa7164_api_set_debug(dev, fw_debug); @@ -1404,15 +1394,15 @@ static int saa7164_initdev(struct pci_dev *pci_dev, "saa7164 debug"); if (IS_ERR(dev->kthread)) { dev->kthread = NULL; - printk(KERN_ERR "%s() Failed to create " - "debug kernel thread\n", __func__); + printk(KERN_ERR "%s() Failed to create debug kernel thread\n", + __func__); } } } /* != BOARD_UNKNOWN */ else - printk(KERN_ERR "%s() Unsupported board detected, " - "registering without firmware\n", __func__); + printk(KERN_ERR "%s() Unsupported board detected, registering without firmware\n", + __func__); dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug); dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs); diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index e9a783b71b45..cd3eeda5250b 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -244,8 +244,8 @@ static int saa7164_dvb_start_port(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() acquire/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; goto out; @@ -261,8 +261,8 @@ static int saa7164_dvb_start_port(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() pause/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -279,8 +279,8 @@ static int saa7164_dvb_start_port(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() run/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -357,8 +357,7 @@ static int dvb_register(struct saa7164_port *port) /* Sanity check that the PCI configuration space is active */ if (port->hwcfg.BARLocation == 0) { result = -ENOMEM; - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d), NO PCI configuration\n", + printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d), NO PCI configuration\n", DRIVER_NAME, result); goto fail_adapter; } @@ -386,8 +385,7 @@ static int dvb_register(struct saa7164_port *port) if (!buf) { result = -ENOMEM; - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d), unable to allocate buffers\n", + printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d), unable to allocate buffers\n", DRIVER_NAME, result); goto fail_adapter; } @@ -401,8 +399,8 @@ static int dvb_register(struct saa7164_port *port) result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, &dev->pci->dev, adapter_nr); if (result < 0) { - printk(KERN_ERR "%s: dvb_register_adapter failed " - "(errno = %d)\n", DRIVER_NAME, result); + printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d)\n", + DRIVER_NAME, result); goto fail_adapter; } dvb->adapter.priv = port; @@ -410,8 +408,8 @@ static int dvb_register(struct saa7164_port *port) /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (result < 0) { - printk(KERN_ERR "%s: dvb_register_frontend failed " - "(errno = %d)\n", DRIVER_NAME, result); + printk(KERN_ERR "%s: dvb_register_frontend failed (errno = %d)\n", + DRIVER_NAME, result); goto fail_frontend; } @@ -444,16 +442,16 @@ static int dvb_register(struct saa7164_port *port) dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_ERR "%s: add_frontend failed " - "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result); + printk(KERN_ERR "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", + DRIVER_NAME, result); goto fail_fe_hw; } dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - printk(KERN_ERR "%s: add_frontend failed " - "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result); + printk(KERN_ERR "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + DRIVER_NAME, result); goto fail_fe_mem; } diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 32a353d162e7..68124ce7ebc3 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -157,8 +157,7 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port) params->pitch); if (!buf) { - printk(KERN_ERR "%s() failed " - "(errno = %d), unable to allocate buffer\n", + printk(KERN_ERR "%s() failed (errno = %d), unable to allocate buffer\n", __func__, result); result = -ENOMEM; goto failed; @@ -681,8 +680,8 @@ static int saa7164_encoder_start_streaming(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() acquire/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() acquire/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; goto out; @@ -698,8 +697,8 @@ static int saa7164_encoder_start_streaming(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() pause/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -716,8 +715,8 @@ static int saa7164_encoder_start_streaming(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() run/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -1026,8 +1025,7 @@ int saa7164_encoder_register(struct saa7164_port *port) /* Sanity check that the PCI configuration space is active */ if (port->hwcfg.BARLocation == 0) { - printk(KERN_ERR "%s() failed " - "(errno = %d), NO PCI configuration\n", + printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n", __func__, result); result = -ENOMEM; goto failed; diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c index 269e0782c7b6..8568adfd7ece 100644 --- a/drivers/media/pci/saa7164/saa7164-fw.c +++ b/drivers/media/pci/saa7164/saa7164-fw.c @@ -421,8 +421,8 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) ret = request_firmware(&fw, fwname, &dev->pci->dev); if (ret) { - printk(KERN_ERR "%s() Upload failed. " - "(file not found?)\n", __func__); + printk(KERN_ERR "%s() Upload failed. (file not found?)\n", + __func__); return -ENOMEM; } @@ -478,15 +478,13 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK) == 0x00) && (version == 0x00)) { - dprintk(DBGLVL_FW, "BootLoader version in " - "rom %d.%d.%d.%d\n", + dprintk(DBGLVL_FW, "BootLoader version in rom %d.%d.%d.%d\n", (bootloaderversion & 0x0000fc00) >> 10, (bootloaderversion & 0x000003e0) >> 5, (bootloaderversion & 0x0000001f), (bootloaderversion & 0xffff0000) >> 16 ); - dprintk(DBGLVL_FW, "BootLoader version " - "in file %d.%d.%d.%d\n", + dprintk(DBGLVL_FW, "BootLoader version in file %d.%d.%d.%d\n", (boothdr->version & 0x0000fc00) >> 10, (boothdr->version & 0x000003e0) >> 5, (boothdr->version & 0x0000001f), diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index ee54491459a6..e5dcb81029d3 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -110,8 +110,7 @@ static int saa7164_vbi_buffers_alloc(struct saa7164_port *port) params->pitch); if (!buf) { - printk(KERN_ERR "%s() failed " - "(errno = %d), unable to allocate buffer\n", + printk(KERN_ERR "%s() failed (errno = %d), unable to allocate buffer\n", __func__, result); result = -ENOMEM; goto failed; @@ -384,8 +383,8 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port) /* Stop the hardware, regardless */ result = saa7164_vbi_stop_port(port); if (result != SAA_OK) { - printk(KERN_ERR "%s() pause/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() pause/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -403,8 +402,8 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port) result = saa7164_vbi_acquire_port(port); result = saa7164_vbi_stop_port(port); if (result != SAA_OK) { - printk(KERN_ERR "%s() run/forced stop transition " - "failed, res = 0x%x\n", __func__, result); + printk(KERN_ERR "%s() run/forced stop transition failed, res = 0x%x\n", + __func__, result); } ret = -EIO; @@ -728,8 +727,7 @@ int saa7164_vbi_register(struct saa7164_port *port) /* Sanity check that the PCI configuration space is active */ if (port->hwcfg.BARLocation == 0) { - printk(KERN_ERR "%s() failed " - "(errno = %d), NO PCI configuration\n", + printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n", __func__, result); result = -ENOMEM; goto failed; -- cgit v1.2.3 From 3d160041dccefcb79874a06009493de55cc11914 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:07 -0200 Subject: [media] solo6x10: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-v4l2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c index b4be47969b6b..896bec6627aa 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c @@ -702,8 +702,8 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", SOLO6X10_NAME, solo_dev->vfd->num); - dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " - "%d inputs (%d extended)\n", solo_dev->vfd->num, + dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with %d inputs (%d extended)\n", + solo_dev->vfd->num, solo_dev->nr_chans, solo_dev->nr_ext); return 0; -- cgit v1.2.3 From 008e6ff9b9bf57a22b49643923bfa4dcaa792fa9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:07 -0200 Subject: [media] ttpci: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/av7110.c | 30 ++++++++++++------------------ drivers/media/pci/ttpci/av7110_hw.c | 12 ++++-------- drivers/media/pci/ttpci/budget-av.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 4 +--- drivers/media/pci/ttpci/budget-patch.c | 3 +-- drivers/media/pci/ttpci/budget.c | 3 +-- drivers/media/pci/ttpci/ttpci-eeprom.c | 3 +-- 7 files changed, 21 insertions(+), 37 deletions(-) diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 382caf200ba1..fbcc2e5c9414 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -100,8 +100,7 @@ MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetect module_param(hw_sections, int, 0444); MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); module_param(rgb_on, int, 0444); -MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" - " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); +MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); module_param(volume, int, 0444); MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); module_param(budgetpatch, int, 0444); @@ -833,8 +832,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) ret = av7110_fw_request(av7110, buf, 20, &handle, 1); if (ret != 0 || handle >= 32) { - printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " - "ret %d handle %04x\n", + printk(KERN_ERR "dvb-ttpci: %s error buf %04x %04x %04x %04x ret %d handle %04x\n", __func__, buf[0], buf[1], buf[2], buf[3], ret, handle); dvbdmxfilter->hw_handle = 0xffff; @@ -876,8 +874,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) buf[2] = handle; ret = av7110_fw_request(av7110, buf, 3, answ, 2); if (ret != 0 || answ[1] != handle) { - printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x " - "resp %04x %04x pid %d\n", + printk(KERN_ERR "dvb-ttpci: %s error cmd %04x %04x %04x ret %x resp %04x %04x pid %d\n", __func__, buf[0], buf[1], buf[2], ret, answ[0], answ[1], dvbdmxfilter->feed->pid); if (!ret) @@ -1532,15 +1529,12 @@ static int get_firmware(struct av7110* av7110) ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); if (ret) { if (ret == -ENOENT) { - printk(KERN_ERR "dvb-ttpci: could not load firmware," - " file not found: dvb-ttpci-01.fw\n"); - printk(KERN_ERR "dvb-ttpci: usually this should be in " - "/usr/lib/hotplug/firmware or /lib/firmware\n"); - printk(KERN_ERR "dvb-ttpci: and can be downloaded from" - " https://linuxtv.org/download/dvb/firmware/\n"); + printk(KERN_ERR "dvb-ttpci: could not load firmware, file not found: dvb-ttpci-01.fw\n"); + printk(KERN_ERR "dvb-ttpci: usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n"); + printk(KERN_ERR "dvb-ttpci: and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n"); } else - printk(KERN_ERR "dvb-ttpci: cannot request firmware" - " (error %i)\n", ret); + printk(KERN_ERR "dvb-ttpci: cannot request firmware (error %i)\n", + ret); return -EINVAL; } @@ -2700,8 +2694,9 @@ static int av7110_attach(struct saa7146_dev* dev, goto err_stop_arm_9; if (FW_VERSION(av7110->arm_app)<0x2501) - printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " - "System might be unstable!\n", FW_VERSION(av7110->arm_app)); + printk(KERN_WARNING + "dvb-ttpci: Warning, firmware version 0x%04x is too old. System might be unstable!\n", + FW_VERSION(av7110->arm_app)); thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); if (IS_ERR(thread)) { @@ -2944,7 +2939,6 @@ static void __exit av7110_exit(void) module_init(av7110_init); module_exit(av7110_exit); -MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " - "Siemens, Technotrend, Hauppauge"); +MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by Siemens, Technotrend, Hauppauge"); MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/pci/ttpci/av7110_hw.c b/drivers/media/pci/ttpci/av7110_hw.c index 0583d56ef5ef..520414cbe087 100644 --- a/drivers/media/pci/ttpci/av7110_hw.c +++ b/drivers/media/pci/ttpci/av7110_hw.c @@ -235,8 +235,7 @@ int av7110_bootarm(struct av7110 *av7110) iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { - printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " - "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", + printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: %08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", ret, 0x10325476); return -1; } @@ -262,8 +261,7 @@ int av7110_bootarm(struct av7110 *av7110) iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); if (saa7146_wait_for_debi_done(av7110->dev, 1)) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "saa7146_wait_for_debi_done() timed out\n"); + printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out\n"); return -ETIMEDOUT; } saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); @@ -271,8 +269,7 @@ int av7110_bootarm(struct av7110 *av7110) dprintk(1, "load dram code\n"); if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "load_dram() failed\n"); + printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): load_dram() failed\n"); return -1; } @@ -283,8 +280,7 @@ int av7110_bootarm(struct av7110 *av7110) mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram); if (saa7146_wait_for_debi_done(av7110->dev, 1)) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "saa7146_wait_for_debi_done() timed out after loading DRAM\n"); + printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out after loading DRAM\n"); return -ETIMEDOUT; } saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 6f0d0161970e..896c66d4b3ae 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -1636,5 +1636,4 @@ module_exit(budget_av_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); +MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 7b27af4d9658..20ad93bf0f54 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -1586,6 +1586,4 @@ module_exit(budget_ci_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB cards w/ CI-module produced by " - "Siemens, Technotrend, Hauppauge"); +MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c index 591dbdfa2a13..f152eda0123a 100644 --- a/drivers/media/pci/ttpci/budget-patch.c +++ b/drivers/media/pci/ttpci/budget-patch.c @@ -679,5 +679,4 @@ module_exit(budget_patch_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others"); -MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 " - "based so-called Budget Patch cards"); +MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 based so-called Budget Patch cards"); diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index fb8ede5a1531..3091b480ce22 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -897,5 +897,4 @@ module_exit(budget_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); +MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.c b/drivers/media/pci/ttpci/ttpci-eeprom.c index 079ee098b7e3..9534f29c1ffd 100644 --- a/drivers/media/pci/ttpci/ttpci-eeprom.c +++ b/drivers/media/pci/ttpci/ttpci-eeprom.c @@ -171,5 +171,4 @@ EXPORT_SYMBOL(ttpci_eeprom_parse_mac); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); -MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards " - "made by Siemens, Technotrend, Hauppauge"); +MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards made by Siemens, Technotrend, Hauppauge"); -- cgit v1.2.3 From db6d8d5fdf9537641c76ba7f32e02b4bcc600972 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:08 -0200 Subject: [media] tw68: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/tw68/tw68-video.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c index a45e02367321..58c4dd75bfa1 100644 --- a/drivers/media/pci/tw68/tw68-video.c +++ b/drivers/media/pci/tw68/tw68-video.c @@ -279,9 +279,8 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width, height /= 2; /* we must set for 1-frame */ pr_debug("%s: width=%d, height=%d, both=%d\n" - " tvnorm h_delay=%d, h_start=%d, h_stop=%d, " - "v_delay=%d, v_start=%d, v_stop=%d\n" , __func__, - width, height, V4L2_FIELD_HAS_BOTH(field), + " tvnorm h_delay=%d, h_start=%d, h_stop=%d, v_delay=%d, v_start=%d, v_stop=%d\n", + __func__, width, height, V4L2_FIELD_HAS_BOTH(field), norm->h_delay, norm->h_start, norm->h_stop, norm->v_delay, norm->video_v_start, norm->video_v_stop); @@ -309,16 +308,15 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width, V4L2_FIELD_HAS_TOP(field) ? "T" : "", V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "", v4l2_norm_to_name(dev->tvnorm->id)); - pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; " - "vactive=%d, vdelay=%d, vscale=%d\n", __func__, + pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; vactive=%d, vdelay=%d, vscale=%d\n", + __func__, hactive, hdelay, hscale, vactive, vdelay, vscale); comb = ((vdelay & 0x300) >> 2) | ((vactive & 0x300) >> 4) | ((hdelay & 0x300) >> 6) | ((hactive & 0x300) >> 8); - pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, " - "VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n", + pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n", __func__, comb, vdelay, vactive, hdelay, hactive); tw_writeb(TW68_CROP_HI, comb); tw_writeb(TW68_VDELAY_LO, vdelay & 0xff); @@ -327,8 +325,8 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width, tw_writeb(TW68_HACTIVE_LO, hactive & 0xff); comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8); - pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, " - "HSCALE_LO=%02x\n", __func__, comb, vscale, hscale); + pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, HSCALE_LO=%02x\n", + __func__, comb, vscale, hscale); tw_writeb(TW68_SCALE_HI, comb); tw_writeb(TW68_VSCALE_LO, vscale); tw_writeb(TW68_HSCALE_LO, hscale); -- cgit v1.2.3 From ded026e0805fd4aa772716be4ca8e2751d3a7de7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:08 -0200 Subject: [media] davinci: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/dm355_ccdc.c | 4 ++-- drivers/media/platform/davinci/dm644x_ccdc.c | 4 ++-- drivers/media/platform/davinci/vpbe.c | 15 +++++---------- drivers/media/platform/davinci/vpfe_capture.c | 6 ++---- drivers/media/platform/davinci/vpif_capture.c | 9 ++------- drivers/media/platform/davinci/vpif_display.c | 9 ++------- drivers/media/platform/davinci/vpss.c | 7 +++---- 7 files changed, 18 insertions(+), 36 deletions(-) diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index c90b9a4f0c24..65c2973167c6 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -334,8 +334,8 @@ static int ccdc_set_params(void __user *params) x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); if (x) { - dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc" - "params, %d\n", x); + dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdcparams, %d\n", + x); return -EFAULT; } diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 6fba32bec974..c7523a7e0594 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -354,8 +354,8 @@ static int ccdc_set_params(void __user *params) x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); if (x) { - dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying" - "ccdc params, %d\n", x); + dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copyingccdc params, %d\n", + x); return -EFAULT; } diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 9a6c2cc38acb..7d2670732805 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -705,15 +705,13 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) "v4l2 sub device %s registered\n", enc_info->module_name); else { - v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s" - " failed to register", + v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s failed to register", enc_info->module_name); ret = -ENODEV; goto fail_kfree_encoders; } } else - v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" - " currently not supported"); + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders currently not supported"); } /* Add amplifier subdevice for dm365 */ if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && @@ -735,8 +733,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) amp_info->module_name); } else { vpbe_dev->amp = NULL; - v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" - " currently not supported"); + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers currently not supported"); } } else { vpbe_dev->amp = NULL; @@ -835,15 +832,13 @@ static int vpbe_probe(struct platform_device *pdev) if (!cfg->module_name[0] || !cfg->osd.module_name[0] || !cfg->venc.module_name[0]) { - v4l2_err(pdev->dev.driver, "vpbe display module names not" - " defined\n"); + v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n"); return ret; } vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL); if (vpbe_dev == NULL) { - v4l2_err(pdev->dev.driver, "Unable to allocate memory" - " for vpbe_device\n"); + v4l2_err(pdev->dev.driver, "Unable to allocate memory for vpbe_device\n"); return -ENOMEM; } vpbe_dev->cfg = cfg; diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 6efb2f1631c4..ca22c3493f55 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -919,8 +919,7 @@ static const struct vpfe_pixel_format * else pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; - v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height =" - " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n", + v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height = %d, bpp = %d, bytesperline = %d, sizeimage = %d\n", pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp, pixfmt->bytesperline, pixfmt->sizeimage); return vpfe_pix_fmt; @@ -1088,8 +1087,7 @@ static int vpfe_enum_input(struct file *file, void *priv, &subdev, &index, inp->index) < 0) { - v4l2_err(&vpfe_dev->v4l2_dev, "input information not found" - " for the subdev\n"); + v4l2_err(&vpfe_dev->v4l2_dev, "input information not found for the subdev\n"); return -EINVAL; } sdinfo = &vpfe_dev->cfg->sub_devs[subdev]; diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 5104cc0ee40e..c6a3a904afc8 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1152,11 +1152,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, timings->bt.vfrontporch && (timings->bt.vbackporch || timings->bt.vsync))) { - vpif_dbg(2, debug, "Timings for width, height, " - "horizontal back porch, horizontal sync, " - "horizontal front porch, vertical back porch, " - "vertical sync and vertical back porch " - "must be defined\n"); + vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n"); return -EINVAL; } @@ -1181,8 +1177,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, std_info->l11 = std_info->vsize - (bt->il_vfrontporch - 1); } else { - vpif_dbg(2, debug, "Required timing values for " - "interlaced BT format missing\n"); + vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n"); return -EINVAL; } } else { diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 75b27233ec2f..6b3ea1e8e97f 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -954,11 +954,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, timings->bt.vfrontporch && (timings->bt.vbackporch || timings->bt.vsync))) { - vpif_dbg(2, debug, "Timings for width, height, " - "horizontal back porch, horizontal sync, " - "horizontal front porch, vertical back porch, " - "vertical sync and vertical back porch " - "must be defined\n"); + vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n"); return -EINVAL; } @@ -983,8 +979,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, std_info->l11 = std_info->vsize - (bt->il_vfrontporch - 1); } else { - vpif_dbg(2, debug, "Required timing values for " - "interlaced BT format missing\n"); + vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n"); return -EINVAL; } } else { diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index fce86f17dffc..373b796132f2 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c @@ -261,8 +261,8 @@ static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en) shift = 6; break; default: - printk(KERN_ERR "dm355_enable_clock:" - " Invalid selector: %d\n", clock_sel); + printk(KERN_ERR "dm355_enable_clock: Invalid selector: %d\n", + clock_sel); return -EINVAL; } @@ -421,8 +421,7 @@ static int vpss_probe(struct platform_device *pdev) else if (!strcmp(platform_name, "dm644x_vpss")) oper_cfg.platform = DM644X; else { - dev_err(&pdev->dev, "vpss driver not supported on" - " this platform\n"); + dev_err(&pdev->dev, "vpss driver not supported on this platform\n"); return -ENODEV; } -- cgit v1.2.3 From 57425dc76d8174e7bfe94a11d089d3feeebb474c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:09 -0200 Subject: [media] exynos4-is: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 1a1154a9dfa4..e3a8709138fa 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -938,8 +938,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) csis = fmd->csis[pdata->mux_id].sd; if (WARN(csis == NULL, - "MIPI-CSI interface specified " - "but s5p-csis module is not loaded!\n")) + "MIPI-CSI interface specified but s5p-csis module is not loaded!\n")) return -EINVAL; pad = sensor->entity.num_pads - 1; -- cgit v1.2.3 From a4585c31c5018578b4abf699ddfdff719dd1c313 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:09 -0200 Subject: [media] marvell-ccic: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 26 +++++++------------------ 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index af59bf4dca2d..a8bda6679422 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -49,24 +49,17 @@ static bool alloc_bufs_at_read; module_param(alloc_bufs_at_read, bool, 0444); MODULE_PARM_DESC(alloc_bufs_at_read, - "Non-zero value causes DMA buffers to be allocated when the " - "video capture device is read, rather than at module load " - "time. This saves memory, but decreases the chances of " - "successfully getting those buffers. This parameter is " - "only used in the vmalloc buffer mode"); + "Non-zero value causes DMA buffers to be allocated when the video capture device is read, rather than at module load time. This saves memory, but decreases the chances of successfully getting those buffers. This parameter is only used in the vmalloc buffer mode"); static int n_dma_bufs = 3; module_param(n_dma_bufs, uint, 0644); MODULE_PARM_DESC(n_dma_bufs, - "The number of DMA buffers to allocate. Can be either two " - "(saves memory, makes timing tighter) or three."); + "The number of DMA buffers to allocate. Can be either two (saves memory, makes timing tighter) or three."); static int dma_buf_size = VGA_WIDTH * VGA_HEIGHT * 2; /* Worst case */ module_param(dma_buf_size, uint, 0444); MODULE_PARM_DESC(dma_buf_size, - "The size of the allocated DMA buffers. If actual operating " - "parameters require larger buffers, an attempt to reallocate " - "will be made."); + "The size of the allocated DMA buffers. If actual operating parameters require larger buffers, an attempt to reallocate will be made."); #else /* MCAM_MODE_VMALLOC */ static const bool alloc_bufs_at_read; static const int n_dma_bufs = 3; /* Used by S/G_PARM */ @@ -75,15 +68,12 @@ static const int n_dma_bufs = 3; /* Used by S/G_PARM */ static bool flip; module_param(flip, bool, 0444); MODULE_PARM_DESC(flip, - "If set, the sensor will be instructed to flip the image " - "vertically."); + "If set, the sensor will be instructed to flip the image vertically."); static int buffer_mode = -1; module_param(buffer_mode, int, 0444); MODULE_PARM_DESC(buffer_mode, - "Set the buffer mode to be used; default is to go with what " - "the platform driver asks for. Set to 0 for vmalloc, 1 for " - "DMA contiguous."); + "Set the buffer mode to be used; default is to go with what the platform driver asks for. Set to 0 for vmalloc, 1 for DMA contiguous."); /* * Status flags. Always manipulated with bit operations. @@ -1759,8 +1749,7 @@ int mccic_register(struct mcam_camera *cam) cam->buffer_mode = buffer_mode; if (cam->buffer_mode == B_DMA_sg && cam->chip_id == MCAM_CAFE) { - printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, " - "attempting vmalloc mode instead\n"); + printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, attempting vmalloc mode instead\n"); cam->buffer_mode = B_vmalloc; } if (!mcam_buffer_mode_supported(cam->buffer_mode)) { @@ -1828,8 +1817,7 @@ int mccic_register(struct mcam_camera *cam) */ if (cam->buffer_mode == B_vmalloc && !alloc_bufs_at_read) { if (mcam_alloc_dma_bufs(cam, 1)) - cam_warn(cam, "Unable to alloc DMA buffers at load" - " will try again later."); + cam_warn(cam, "Unable to alloc DMA buffers at load will try again later."); } mutex_unlock(&cam->s_mutex); -- cgit v1.2.3 From bc39030bb2d49cf197bf9714d71ea3fc4a970e60 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:10 -0200 Subject: [media] omap: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/omap_vout.c | 24 +++++++++++++----------- drivers/media/platform/omap/omap_vout_vrfb.c | 5 +++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index e668dde6d857..c39b5463e0b3 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -408,8 +408,8 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout, v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s enable=%d addr=%pad width=%d\n height=%d color_mode=%d\n" "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n" - "out_height=%d rotation_type=%d screen_width=%d\n", - __func__, ovl->is_enabled(ovl), &info.paddr, info.width, info.height, + "out_height=%d rotation_type=%d screen_width=%d\n", __func__, + ovl->is_enabled(ovl), &info.paddr, info.width, info.height, info.color_mode, info.rotation, info.mirror, info.pos_x, info.pos_y, info.out_width, info.out_height, info.rotation_type, info.screen_width); @@ -791,7 +791,8 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q, dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr, size, DMA_TO_DEVICE); if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr)) - v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n"); + v4l2_err(&vout->vid_dev->v4l2_dev, + "dma_map_single failed\n"); vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; } @@ -1657,8 +1658,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) /* Turn of the pipeline */ ret = omapvid_apply_changes(vout); if (ret) - v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in" - " streamoff\n"); + v4l2_err(&vout->vid_dev->v4l2_dev, + "failed to change mode in streamoff\n"); INIT_LIST_HEAD(&vout->dma_queue); ret = videobuf_streamoff(&vout->vbq); @@ -1858,8 +1859,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) vfd = vout->vfd = video_device_alloc(); if (!vfd) { - printk(KERN_ERR VOUT_NAME ": could not allocate" - " video device struct\n"); + printk(KERN_ERR VOUT_NAME + ": could not allocate video device struct\n"); v4l2_ctrl_handler_free(hdl); return -ENOMEM; } @@ -1984,16 +1985,17 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) */ vfd = vout->vfd; if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) { - dev_err(&pdev->dev, ": Could not register " - "Video for Linux device\n"); + dev_err(&pdev->dev, + ": Could not register Video for Linux device\n"); vfd->minor = -1; ret = -ENODEV; goto error2; } video_set_drvdata(vfd, vout); - dev_info(&pdev->dev, ": registered and initialized" - " video device %d\n", vfd->minor); + dev_info(&pdev->dev, + ": registered and initialized video device %d\n", + vfd->minor); if (k == (pdev->num_resources - 1)) return 0; diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index b8638e4e1627..92c4e1826356 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c @@ -139,8 +139,9 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch); if (ret < 0) { vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED; - dev_info(&pdev->dev, ": failed to allocate DMA Channel for" - " video%d\n", vfd->minor); + dev_info(&pdev->dev, + ": failed to allocate DMA Channel for video%d\n", + vfd->minor); } init_waitqueue_head(&vout->vrfb_dma_tx.wait); -- cgit v1.2.3 From d26da99058869a5a655820ea43b86f246bf6874a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:10 -0200 Subject: [media] omap3isp: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 4 +- drivers/media/platform/omap3isp/ispccdc.c | 9 +++-- drivers/media/platform/omap3isp/ispcsi2.c | 13 ++---- drivers/media/platform/omap3isp/ispcsiphy.c | 4 +- drivers/media/platform/omap3isp/isph3a_aewb.c | 8 ++-- drivers/media/platform/omap3isp/isph3a_af.c | 8 ++-- drivers/media/platform/omap3isp/ispstat.c | 58 +++++++++++++++------------ 7 files changed, 54 insertions(+), 50 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 0321d84addc7..2e1b17ef82a3 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -480,8 +480,8 @@ void omap3isp_hist_dma_done(struct isp_device *isp) omap3isp_stat_pcr_busy(&isp->isp_hist)) { /* Histogram cannot be enabled in this frame anymore */ atomic_set(&isp->isp_hist.buf_err, 1); - dev_dbg(isp->dev, "hist: Out of synchronization with " - "CCDC. Ignoring next buffer.\n"); + dev_dbg(isp->dev, + "hist: Out of synchronization with CCDC. Ignoring next buffer.\n"); } } diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 882310eb45cc..7207558d722c 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -151,8 +151,8 @@ static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc, } if (lsc_cfg->offset & 3) { - dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of " - "4\n"); + dev_dbg(isp->dev, + "CCDC: LSC: Offset must be a multiple of 4\n"); return -EINVAL; } @@ -416,8 +416,9 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, return 0; if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) { - dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table " - "need to be supplied\n", __func__); + dev_dbg(to_device(ccdc), + "%s: Both LSC configuration and table need to be supplied\n", + __func__); return -EINVAL; } diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index f75a1be29d84..7dae2fe0d42d 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -753,8 +753,8 @@ void omap3isp_csi2_isr(struct isp_csi2_device *csi2) ISPCSI2_PHY_IRQSTATUS); isp_reg_writel(isp, cpxio1_irqstatus, csi2->regs1, ISPCSI2_PHY_IRQSTATUS); - dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ " - "%x\n", cpxio1_irqstatus); + dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ %x\n", + cpxio1_irqstatus); pipe->error = true; } @@ -763,13 +763,8 @@ void omap3isp_csi2_isr(struct isp_csi2_device *csi2) ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ | ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ | ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) { - dev_dbg(isp->dev, "CSI2 Err:" - " OCP:%d," - " Short_pack:%d," - " ECC:%d," - " CPXIO2:%d," - " FIFO_OVF:%d," - "\n", + dev_dbg(isp->dev, + "CSI2 Err: OCP:%d, Short_pack:%d, ECC:%d, CPXIO2:%d, FIFO_OVF:%d,\n", (csi2_irqstatus & ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0, (csi2_irqstatus & diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 495447d66cfd..871d4fe09c7f 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -267,8 +267,8 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy) int rval; if (phy->vdd == NULL) { - dev_err(phy->isp->dev, "Power regulator for CSI PHY not " - "available\n"); + dev_err(phy->isp->dev, + "Power regulator for CSI PHY not available\n"); return -ENODEV; } diff --git a/drivers/media/platform/omap3isp/isph3a_aewb.c b/drivers/media/platform/omap3isp/isph3a_aewb.c index ccaf92f39236..d44626f20ac6 100644 --- a/drivers/media/platform/omap3isp/isph3a_aewb.c +++ b/drivers/media/platform/omap3isp/isph3a_aewb.c @@ -304,8 +304,8 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp) aewb_recover_cfg = devm_kzalloc(isp->dev, sizeof(*aewb_recover_cfg), GFP_KERNEL); if (!aewb_recover_cfg) { - dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for " - "recover configuration.\n"); + dev_err(aewb->isp->dev, + "AEWB: cannot allocate memory for recover configuration.\n"); return -ENOMEM; } @@ -321,8 +321,8 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp) aewb_recover_cfg->subsample_hor_inc = OMAP3ISP_AEWB_MIN_SUB_INC; if (h3a_aewb_validate_params(aewb, aewb_recover_cfg)) { - dev_err(aewb->isp->dev, "AEWB: recover configuration is " - "invalid.\n"); + dev_err(aewb->isp->dev, + "AEWB: recover configuration is invalid.\n"); return -EINVAL; } diff --git a/drivers/media/platform/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c index 92937f7eecef..99bd6cc21d86 100644 --- a/drivers/media/platform/omap3isp/isph3a_af.c +++ b/drivers/media/platform/omap3isp/isph3a_af.c @@ -367,8 +367,8 @@ int omap3isp_h3a_af_init(struct isp_device *isp) af_recover_cfg = devm_kzalloc(isp->dev, sizeof(*af_recover_cfg), GFP_KERNEL); if (!af_recover_cfg) { - dev_err(af->isp->dev, "AF: cannot allocate memory for recover " - "configuration.\n"); + dev_err(af->isp->dev, + "AF: cannot allocate memory for recover configuration.\n"); return -ENOMEM; } @@ -379,8 +379,8 @@ int omap3isp_h3a_af_init(struct isp_device *isp) af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN; af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN; if (h3a_af_validate_params(af, af_recover_cfg)) { - dev_err(af->isp->dev, "AF: recover configuration is " - "invalid.\n"); + dev_err(af->isp->dev, + "AF: recover configuration is invalid.\n"); return -EINVAL; } diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index 1b9217d3b1b6..47cbc7e3d825 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -113,8 +113,9 @@ static int isp_stat_buf_check_magic(struct ispstat *stat, ret = 0; if (ret) { - dev_dbg(stat->isp->dev, "%s: beginning magic check does not " - "match.\n", stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: beginning magic check does not match.\n", + stat->subdev.name); return ret; } @@ -122,8 +123,9 @@ static int isp_stat_buf_check_magic(struct ispstat *stat, for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE; w < end; w++) { if (unlikely(*w != MAGIC_NUM)) { - dev_dbg(stat->isp->dev, "%s: ending magic check does " - "not match.\n", stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: ending magic check does not match.\n", + stat->subdev.name); return -EINVAL; } } @@ -256,9 +258,9 @@ static void isp_stat_buf_next(struct ispstat *stat) { if (unlikely(stat->active_buf)) /* Overwriting unused active buffer */ - dev_dbg(stat->isp->dev, "%s: new buffer requested without " - "queuing active one.\n", - stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: new buffer requested without queuing active one.\n", + stat->subdev.name); else stat->active_buf = isp_stat_buf_find_oldest_or_empty(stat); } @@ -292,8 +294,9 @@ static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat, return ERR_PTR(-EBUSY); } if (isp_stat_buf_check_magic(stat, buf)) { - dev_dbg(stat->isp->dev, "%s: current buffer has " - "corrupted data\n.", stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: current buffer has corrupted data\n.", + stat->subdev.name); /* Mark empty because it doesn't have valid data. */ buf->empty = 1; } else { @@ -307,8 +310,9 @@ static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat, spin_unlock_irqrestore(&stat->isp->stat_lock, flags); if (buf->buf_size > data->buf_size) { - dev_warn(stat->isp->dev, "%s: userspace's buffer size is " - "not enough.\n", stat->subdev.name); + dev_warn(stat->isp->dev, + "%s: userspace's buffer size is not enough.\n", + stat->subdev.name); isp_stat_buf_release(stat); return ERR_PTR(-EINVAL); } @@ -531,20 +535,22 @@ int omap3isp_stat_config(struct ispstat *stat, void *new_conf) mutex_lock(&stat->ioctl_lock); - dev_dbg(stat->isp->dev, "%s: configuring module with buffer " - "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size); + dev_dbg(stat->isp->dev, + "%s: configuring module with buffer size=0x%08lx\n", + stat->subdev.name, (unsigned long)buf_size); ret = stat->ops->validate_params(stat, new_conf); if (ret) { mutex_unlock(&stat->ioctl_lock); - dev_dbg(stat->isp->dev, "%s: configuration values are " - "invalid.\n", stat->subdev.name); + dev_dbg(stat->isp->dev, "%s: configuration values are invalid.\n", + stat->subdev.name); return ret; } if (buf_size != user_cfg->buf_size) - dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size " - "request to 0x%08lx\n", stat->subdev.name, + dev_dbg(stat->isp->dev, + "%s: driver has corrected buffer size request to 0x%08lx\n", + stat->subdev.name, (unsigned long)user_cfg->buf_size); /* @@ -595,8 +601,9 @@ int omap3isp_stat_config(struct ispstat *stat, void *new_conf) /* Module has a valid configuration. */ stat->configured = 1; - dev_dbg(stat->isp->dev, "%s: module has been successfully " - "configured.\n", stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: module has been successfully configured.\n", + stat->subdev.name); mutex_unlock(&stat->ioctl_lock); @@ -762,8 +769,8 @@ int omap3isp_stat_enable(struct ispstat *stat, u8 enable) if (!stat->configured && enable) { spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags); mutex_unlock(&stat->ioctl_lock); - dev_dbg(stat->isp->dev, "%s: cannot enable module as it's " - "never been successfully configured so far.\n", + dev_dbg(stat->isp->dev, + "%s: cannot enable module as it's never been successfully configured so far.\n", stat->subdev.name); return -EINVAL; } @@ -859,8 +866,8 @@ static void __stat_isr(struct ispstat *stat, int from_dma) if (stat->state == ISPSTAT_ENABLED) { spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags); dev_err(stat->isp->dev, - "%s: interrupt occurred when module was still " - "processing a buffer.\n", stat->subdev.name); + "%s: interrupt occurred when module was still processing a buffer.\n", + stat->subdev.name); ret = STAT_NO_BUF; goto out; } else { @@ -964,8 +971,9 @@ static void __stat_isr(struct ispstat *stat, int from_dma) atomic_set(&stat->buf_err, 1); ret = STAT_NO_BUF; - dev_dbg(stat->isp->dev, "%s: cannot process buffer, " - "device is busy.\n", stat->subdev.name); + dev_dbg(stat->isp->dev, + "%s: cannot process buffer, device is busy.\n", + stat->subdev.name); } out: -- cgit v1.2.3 From c12a5cc61637e8aa87db591be9b1d6dba3f15616 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:10 -0200 Subject: [media] s5p-mfc: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 13 ++++++------- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 7 ++----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 52081ddc9bf2..cf787eae11b7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -793,18 +793,17 @@ static int vidioc_g_crop(struct file *file, void *priv, cr->c.top = top; cr->c.width = ctx->img_width - left - right; cr->c.height = ctx->img_height - top - bottom; - mfc_debug(2, "Cropping info [h264]: l=%d t=%d " - "w=%d h=%d (r=%d b=%d fw=%d fh=%d\n", left, top, - cr->c.width, cr->c.height, right, bottom, - ctx->buf_width, ctx->buf_height); + mfc_debug(2, "Cropping info [h264]: l=%d t=%d w=%d h=%d (r=%d b=%d fw=%d fh=%d\n", + left, top, cr->c.width, cr->c.height, right, bottom, + ctx->buf_width, ctx->buf_height); } else { cr->c.left = 0; cr->c.top = 0; cr->c.width = ctx->img_width; cr->c.height = ctx->img_height; - mfc_debug(2, "Cropping info: w=%d h=%d fw=%d " - "fh=%d\n", cr->c.width, cr->c.height, ctx->buf_width, - ctx->buf_height); + mfc_debug(2, "Cropping info: w=%d h=%d fw=%d fh=%d\n", + cr->c.width, cr->c.height, ctx->buf_width, + ctx->buf_height); } return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index 81e1e4ce6c24..f4301d5bbd32 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -1293,14 +1293,11 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) * First set the output frame buffers */ if (ctx->capture_state != QUEUE_BUFS_MMAPED) { - mfc_err("It seems that not all destionation buffers were " - "mmaped\nMFC requires that all destination are mmaped " - "before starting processing\n"); + mfc_err("It seems that not all destionation buffers were mmaped\nMFC requires that all destination are mmaped before starting processing\n"); return -EAGAIN; } if (list_empty(&ctx->src_queue)) { - mfc_err("Header has been deallocated in the middle of" - " initialization\n"); + mfc_err("Header has been deallocated in the middle of initialization\n"); return -EIO; } temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); -- cgit v1.2.3 From 7152c88e556bcbee525689063c260cd296f295a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:11 -0200 Subject: [media] c8sectpfe: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Acked-by: Peter Griffin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 30c148b9d65e..42b123ff2953 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -112,8 +112,7 @@ static void channel_swdemux_tsklet(unsigned long data) buf = (u8 *) channel->back_buffer_aligned; dev_dbg(fei->dev, - "chan=%d channel=%p num_packets = %d, buf = %p, pos = 0x%x\n\t" - "rp=0x%lx, wp=0x%lx\n", + "chan=%d channel=%p num_packets = %d, buf = %p, pos = 0x%x\n\trp=0x%lx, wp=0x%lx\n", channel->tsin_id, channel, num_packets, buf, pos, rp, wp); for (n = 0; n < num_packets; n++) { @@ -789,8 +788,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) /* sanity check value */ if (tsin->tsin_id > fei->hw_stats.num_ib) { dev_err(&pdev->dev, - "tsin-num %d specified greater than number\n\t" - "of input block hw in SoC! (%d)", + "tsin-num %d specified greater than number\n\tof input block hw in SoC! (%d)", tsin->tsin_id, fei->hw_stats.num_ib); ret = -EINVAL; goto err_clk_disable; @@ -855,8 +853,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) tsin->demux_mapping = index; dev_dbg(fei->dev, - "channel=%p n=%d tsin_num=%d, invert-ts-clk=%d\n\t" - "serial-not-parallel=%d pkt-clk-valid=%d dvb-card=%d\n", + "channel=%p n=%d tsin_num=%d, invert-ts-clk=%d\n\tserial-not-parallel=%d pkt-clk-valid=%d dvb-card=%d\n", fei->channel_data[index], index, tsin->tsin_id, tsin->invert_ts_clk, tsin->serial_not_parallel, tsin->async_not_sync, @@ -1045,8 +1042,8 @@ static void load_imem_segment(struct c8sectpfei *fei, Elf32_Phdr *phdr, */ dev_dbg(fei->dev, - "Loading IMEM segment %d 0x%08x\n\t" - " (0x%x bytes) -> 0x%p (0x%x bytes)\n", seg_num, + "Loading IMEM segment %d 0x%08x\n\t (0x%x bytes) -> 0x%p (0x%x bytes)\n", +seg_num, phdr->p_paddr, phdr->p_filesz, dest, phdr->p_memsz + phdr->p_memsz / 3); @@ -1075,8 +1072,7 @@ static void load_dmem_segment(struct c8sectpfei *fei, Elf32_Phdr *phdr, */ dev_dbg(fei->dev, - "Loading DMEM segment %d 0x%08x\n\t" - "(0x%x bytes) -> 0x%p (0x%x bytes)\n", + "Loading DMEM segment %d 0x%08x\n\t(0x%x bytes) -> 0x%p (0x%x bytes)\n", seg_num, phdr->p_paddr, phdr->p_filesz, dst, phdr->p_memsz); -- cgit v1.2.3 From 637d5ac51380b7021c711e183052b81afb89d160 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:11 -0200 Subject: [media] ti-vpe: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Acked-by: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 22 ++++++++++------------ drivers/media/platform/ti-vpe/vpe.c | 3 +-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 3e2e3a33e6ed..4aff05915051 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -466,10 +466,10 @@ static void dump_cfd(struct vpdma_cfd *cfd) pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr); - pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, " - "payload_len = %d\n", cfd_get_pkt_type(cfd), - cfd_get_direct(cfd), class, cfd_get_dest(cfd), - cfd_get_payload_len(cfd)); + pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, payload_len = %d\n", + cfd_get_pkt_type(cfd), + cfd_get_direct(cfd), class, cfd_get_dest(cfd), + cfd_get_payload_len(cfd)); } /* @@ -574,8 +574,7 @@ static void dump_dtd(struct vpdma_dtd *dtd) pr_debug("%s data transfer descriptor for channel %d\n", dir == DTD_DIR_OUT ? "outbound" : "inbound", chan); - pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, " - "even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n", + pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n", dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd), dtd_get_1d(dtd), dtd_get_even_line_skip(dtd), dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd)); @@ -586,17 +585,16 @@ static void dump_dtd(struct vpdma_dtd *dtd) pr_debug("word2: start_addr = %pad\n", &dtd->start_addr); - pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, " - "pri = %d, next_chan = %d\n", dtd_get_pkt_type(dtd), - dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd), - dtd_get_next_chan(dtd)); + pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, pri = %d, next_chan = %d\n", + dtd_get_pkt_type(dtd), + dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd), + dtd_get_next_chan(dtd)); if (dir == DTD_DIR_IN) pr_debug("word4: frame_width = %d, frame_height = %d\n", dtd_get_frame_width(dtd), dtd_get_frame_height(dtd)); else - pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, " - "drp_data = %d, use_desc_reg = %d\n", + pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, drp_data = %d, use_desc_reg = %d\n", dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd), dtd_get_drop_data(dtd), dtd_get_use_desc(dtd)); diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 0189f7f7cb03..1cf4a4c1b899 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1263,8 +1263,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) } if (irqst0 | irqst1) { - dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: " - "INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n", + dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n", irqst0, irqst1); } -- cgit v1.2.3 From cbfc90809862859a1df6a8b48c7b3c2ac48fdbcd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:12 -0200 Subject: [media] si470x: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 7 +++---- drivers/media/radio/si470x/radio-si470x-usb.c | 15 +++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index ee0470a3196b..9b81969d76b5 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -387,8 +387,8 @@ static int si470x_i2c_probe(struct i2c_client *client, radio->registers[DEVICEID], radio->registers[SI_CHIPID]); if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&client->dev, - "This driver is known to work with " - "firmware version %hu,\n", RADIO_FW_VERSION); + "This driver is known to work with firmware version %hu,\n", + RADIO_FW_VERSION); dev_warn(&client->dev, "but the device has firmware version %hu.\n", radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE); @@ -400,8 +400,7 @@ static int si470x_i2c_probe(struct i2c_client *client, dev_warn(&client->dev, "If you have some trouble using this driver,\n"); dev_warn(&client->dev, - "please report to V4L ML at " - "linux-media@vger.kernel.org\n"); + "please report to V4L ML at linux-media@vger.kernel.org\n"); } /* set initial frequency */ diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 4b132c29f290..1add136d37a3 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -351,8 +351,8 @@ static int si470x_get_scratch_page_versions(struct si470x_device *radio) retval = si470x_get_report(radio, radio->usb_buf, SCRATCH_REPORT_SIZE); if (retval < 0) - dev_warn(&radio->intf->dev, "si470x_get_scratch: " - "si470x_get_report returned %d\n", retval); + dev_warn(&radio->intf->dev, "si470x_get_scratch: si470x_get_report returned %d\n", + retval); else { radio->software_version = radio->usb_buf[1]; radio->hardware_version = radio->usb_buf[2]; @@ -688,8 +688,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, radio->registers[DEVICEID], radio->registers[SI_CHIPID]); if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&intf->dev, - "This driver is known to work with " - "firmware version %hu,\n", RADIO_FW_VERSION); + "This driver is known to work with firmware version %hu,\n", + RADIO_FW_VERSION); dev_warn(&intf->dev, "but the device has firmware version %hu.\n", radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE); @@ -705,8 +705,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, radio->software_version, radio->hardware_version); if (radio->hardware_version < RADIO_HW_VERSION) { dev_warn(&intf->dev, - "This driver is known to work with " - "hardware version %hu,\n", RADIO_HW_VERSION); + "This driver is known to work with hardware version %hu,\n", + RADIO_HW_VERSION); dev_warn(&intf->dev, "but the device has hardware version %hu.\n", radio->hardware_version); @@ -718,8 +718,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, dev_warn(&intf->dev, "If you have some trouble using this driver,\n"); dev_warn(&intf->dev, - "please report to V4L ML at " - "linux-media@vger.kernel.org\n"); + "please report to V4L ML at linux-media@vger.kernel.org\n"); } /* set led to connect state */ -- cgit v1.2.3 From 3c1e300966d7edc380e405b3ab70b6e3c813a121 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:12 -0200 Subject: [media] si4713: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index 0b04b56571da..bc2a8b5442ae 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -716,9 +716,9 @@ static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack, *power = val[5]; *antcap = val[6]; *noise = val[7]; - v4l2_dbg(1, debug, &sdev->sd, "%s: response: %d x 10 kHz " - "(power %d, antcap %d, rnl %d)\n", __func__, - *frequency, *power, *antcap, *noise); + v4l2_dbg(1, debug, &sdev->sd, + "%s: response: %d x 10 kHz (power %d, antcap %d, rnl %d)\n", + __func__, *frequency, *power, *antcap, *noise); } return err; @@ -758,10 +758,9 @@ static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb, v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]); *cbleft = (s8)val[2] - val[3]; - v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts" - " 0x%02x cb avail: %d cb used %d fifo avail" - " %d fifo used %d\n", __func__, val[1], - val[2], val[3], val[4], val[5]); + v4l2_dbg(1, debug, &sdev->sd, + "%s: response: interrupts 0x%02x cb avail: %d cb used %d fifo avail %d fifo used %d\n", + __func__, val[1], val[2], val[3], val[4], val[5]); } return err; -- cgit v1.2.3 From e84541f0fbf354e989caec58990ac9d543251433 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:12 -0200 Subject: [media] wl128x: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/wl128x/fmdrv_common.c | 30 +++++++++++++----------------- drivers/media/radio/wl128x/fmdrv_rx.c | 8 ++++---- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 642b89c66bcb..6f254e80ffa6 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -230,10 +230,10 @@ inline void dump_rx_skb_data(struct sk_buff *skb) struct fm_event_msg_hdr *evt_hdr; evt_hdr = (struct fm_event_msg_hdr *)skb->data; - printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x " - "opcode:%02x type:%s dlen:%02x", evt_hdr->hdr, evt_hdr->len, - evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op, - (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen); + printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x opcode:%02x type:%s dlen:%02x", + evt_hdr->hdr, evt_hdr->len, + evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op, + (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen); len_org = skb->len - FM_EVT_MSG_HDR_SIZE; if (len_org > 0) { @@ -271,9 +271,9 @@ static void recv_tasklet(unsigned long arg) /* Process all packets in the RX queue */ while ((skb = skb_dequeue(&fmdev->rx_q))) { if (skb->len < sizeof(struct fm_event_msg_hdr)) { - fmerr("skb(%p) has only %d bytes, " - "at least need %zu bytes to decode\n", skb, - skb->len, sizeof(struct fm_event_msg_hdr)); + fmerr("skb(%p) has only %d bytes, at least need %zu bytes to decode\n", + skb, + skb->len, sizeof(struct fm_event_msg_hdr)); kfree_skb(skb); continue; } @@ -472,8 +472,7 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, if (!wait_for_completion_timeout(&fmdev->maintask_comp, FM_DRV_TX_TIMEOUT)) { - fmerr("Timeout(%d sec),didn't get reg" - "completion signal from RX tasklet\n", + fmerr("Timeout(%d sec),didn't get regcompletion signal from RX tasklet\n", jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); return -ETIMEDOUT; } @@ -523,8 +522,7 @@ static inline int check_cmdresp_status(struct fmdev *fmdev, fm_evt_hdr = (void *)(*skb)->data; if (fm_evt_hdr->status != 0) { - fmerr("irq: opcode %x response status is not zero " - "Initiating irq recovery process\n", + fmerr("irq: opcode %x response status is not zero Initiating irq recovery process\n", fm_evt_hdr->op); mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT); @@ -564,8 +562,7 @@ static void int_timeout_handler(unsigned long data) * reset stage index & retry count values */ fmirq->stage = 0; fmirq->retry = 0; - fmerr("Recovery action failed during" - "irq processing, max retry reached\n"); + fmerr("Recovery action failed duringirq processing, max retry reached\n"); return; } fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX); @@ -1516,14 +1513,13 @@ int fmc_prepare(struct fmdev *fmdev) if (!wait_for_completion_timeout(&wait_for_fmdrv_reg_comp, FM_ST_REG_TIMEOUT)) { - fmerr("Timeout(%d sec), didn't get reg " - "completion signal from ST\n", + fmerr("Timeout(%d sec), didn't get reg completion signal from ST\n", jiffies_to_msecs(FM_ST_REG_TIMEOUT) / 1000); return -ETIMEDOUT; } if (fmdev->streg_cbdata != 0) { - fmerr("ST reg comp CB called with error " - "status %d\n", fmdev->streg_cbdata); + fmerr("ST reg comp CB called with error status %d\n", + fmdev->streg_cbdata); return -EAGAIN; } diff --git a/drivers/media/radio/wl128x/fmdrv_rx.c b/drivers/media/radio/wl128x/fmdrv_rx.c index cfaeb2417fbb..e7455f82fadc 100644 --- a/drivers/media/radio/wl128x/fmdrv_rx.c +++ b/drivers/media/radio/wl128x/fmdrv_rx.c @@ -120,8 +120,8 @@ int fm_rx_set_freq(struct fmdev *fmdev, u32 freq) curr_frq_in_khz = (fmdev->rx.region.bot_freq + ((u32)curr_frq * FM_FREQ_MUL)); if (curr_frq_in_khz != freq) { - pr_info("Frequency is set to (%d) but " - "requested freq is (%d)\n", curr_frq_in_khz, freq); + pr_info("Frequency is set to (%d) but requested freq is (%d)\n", + curr_frq_in_khz, freq); } /* Update local cache */ @@ -390,8 +390,8 @@ int fm_rx_set_region(struct fmdev *fmdev, u8 region_to_set) new_frq = fmdev->rx.region.top_freq; if (new_frq) { - fmdbg("Current freq is not within band limit boundary," - "switching to %d KHz\n", new_frq); + fmdbg("Current freq is not within band limit boundary,switching to %d KHz\n", + new_frq); /* Current RX frequency is not in range. So, update it */ ret = fm_rx_set_freq(fmdev, new_frq); } -- cgit v1.2.3 From 22990690b1881fc2ae2b2c54f042b323a039d741 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:13 -0200 Subject: [media] au0828: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-video.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 85dd9a8e83ff..7a10eaa38f67 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -253,8 +253,7 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets, dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->isoc_ctl.transfer_buffer[i]) { - printk("unable to allocate %i bytes for transfer" - " buffer %i%s\n", + printk("unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); au0828_uninit_isoc(dev); -- cgit v1.2.3 From 4a58d39075e1e2bc5ca8b379278659d95f072363 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:13 -0200 Subject: [media] b2c2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/b2c2/flexcop-usb.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c index 52bc42da8a4c..788c73803138 100644 --- a/drivers/media/usb/b2c2/flexcop-usb.c +++ b/drivers/media/usb/b2c2/flexcop-usb.c @@ -33,8 +33,7 @@ static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2," - "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); #undef DEBSTATUS #define deb_info(args...) dprintk(0x01, args) @@ -433,8 +432,8 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) frame_size, i, j, ret; int buffer_offset = 0; - deb_ts("creating %d iso-urbs with %d frames " - "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, + deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", + B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); fc_usb->iso_buffer = usb_alloc_coherent(fc_usb->udev, @@ -459,8 +458,8 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { int frame_offset = 0; struct urb *urb = fc_usb->iso_urb[i]; - deb_ts("initializing and submitting urb no. %d " - "(buf_offset: %d).\n", i, buffer_offset); + deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n", + i, buffer_offset); urb->dev = fc_usb->udev; urb->context = fc_usb; -- cgit v1.2.3 From ca852dcd88bed6c6139362432e12bfd8526ccd56 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:14 -0200 Subject: [media] cpia2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cpia2/cpia2_usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index e9100a235831..37f9b30b0abc 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -759,9 +759,7 @@ int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate) cam->params.camera_state.stream_mode = old_alt; ret2 = set_alternate(cam, USBIF_CMDONLY); if (ret2 < 0) { - ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already " - "failed. Then tried to call " - "set_alternate(USBIF_CMDONLY) = %d.\n", + ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already failed. Then tried to call set_alternate(USBIF_CMDONLY) = %d.\n", alternate, ret, ret2); } } else { -- cgit v1.2.3 From ba1da97e0a9de6dee40f30dd2e2d72e3ebbc99e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:14 -0200 Subject: [media] cx231xx: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-core.c | 10 ++++------ drivers/media/usb/cx231xx/cx231xx-dvb.c | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 8b099fe1d592..550ec932f931 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -241,8 +241,7 @@ static int __usb_control_msg(struct cx231xx *dev, unsigned int pipe, int rc, i; if (reg_debug) { - printk(KERN_DEBUG "%s: (pipe 0x%08x): " - "%s: %02x %02x %02x %02x %02x %02x %02x %02x ", + printk(KERN_DEBUG "%s: (pipe 0x%08x): %s: %02x %02x %02x %02x %02x %02x %02x %02x ", dev->name, pipe, (requesttype & USB_DIR_IN) ? "IN" : "OUT", @@ -441,8 +440,7 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf, if (reg_debug) { int byte; - cx231xx_isocdbg("(pipe 0x%08x): " - "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", + cx231xx_isocdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", pipe, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, req, 0, val, reg & 0xff, @@ -600,8 +598,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) return -1; } - cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u," - "Interface = %d\n", alt, max_pkt_size, + cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u,Interface = %d\n", + alt, max_pkt_size, usb_interface_index); if (usb_interface_index > 0) { diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 1417515d30eb..2868546999ca 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -377,8 +377,8 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) cfg.i2c_addr = addr; if (!dev->dvb->frontend) { - dev_err(dev->dev, "%s/2: dvb frontend not attached. " - "Can't attach xc5000\n", dev->name); + dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n", + dev->name); return -EINVAL; } -- cgit v1.2.3 From f319ed911cc8a64ea4a4ddb53633ec1964729108 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:15 -0200 Subject: [media] dvb-usb: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cinergyT2-core.c | 6 ++---- drivers/media/usb/dvb-usb/dib0700_core.c | 5 +---- drivers/media/usb/dvb-usb/dib0700_devices.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 6 ++---- drivers/media/usb/dvb-usb/dw2102.c | 10 ++-------- drivers/media/usb/dvb-usb/friio.c | 4 ++-- drivers/media/usb/dvb-usb/gp8psk.c | 3 +-- drivers/media/usb/dvb-usb/opera1.c | 3 +-- drivers/media/usb/dvb-usb/technisat-usb2.c | 3 +-- 10 files changed, 14 insertions(+), 32 deletions(-) diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c index 8ac825413d5a..1a198d07e30e 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -34,8 +34,7 @@ int dvb_usb_cinergyt2_debug; module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " - "(or-able))."); +MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 (or-able))."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -94,8 +93,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); if (ret < 0) { - deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " - "state info\n"); + deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n"); } mutex_unlock(&st->data_mutex); diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index 92d5408684ac..47df7135e960 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -16,10 +16,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-ab static int nb_packet_buffer_size = 21; module_param(nb_packet_buffer_size, int, 0644); MODULE_PARM_DESC(nb_packet_buffer_size, - "Set the dib0700 driver data buffer size. This parameter " - "corresponds to the number of TS packets. The actual size of " - "the data buffer corresponds to this parameter " - "multiplied by 188 (default: 21)"); + "Set the dib0700 driver data buffer size. This parameter corresponds to the number of TS packets. The actual size of the data buffer corresponds to this parameter multiplied by 188 (default: 21)"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index ef1b8ee75c57..b29d4894c2f1 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -26,8 +26,7 @@ static int force_lna_activation; module_param(force_lna_activation, int, 0644); -MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), " - "if applicable for the device (default: 0=automatic/off)."); +MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), if applicable for the device (default: 0=automatic/off)."); struct dib0700_adapter_state { int (*set_param_save) (struct dvb_frontend *); diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index a04c0a250625..e5675da286cb 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -277,8 +277,7 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) for (i = 0; i < adap->props.num_frontends; i++) { if (adap->props.fe[i].frontend_attach == NULL) { - err("strange: '%s' #%d,%d " - "doesn't want to attach a frontend.", + err("strange: '%s' #%d,%d doesn't want to attach a frontend.", adap->dev->desc->name, adap->id, i); return 0; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c index dd048a7c461c..f0023dbb7276 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c @@ -49,8 +49,7 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); if (ret != hx.len) { - err("error while transferring firmware " - "(transferred size: %d, block size: %d)", + err("error while transferring firmware (transferred size: %d, block size: %d)", ret,hx.len); ret = -EINVAL; break; @@ -81,8 +80,7 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_pro const struct firmware *fw = NULL; if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", + err("did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", props->firmware,ret); return ret; } diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 2c720cb2fb00..38794ab8874e 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -86,8 +86,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." /* demod probe */ static int demod_probe = 1; module_param_named(demod, demod_probe, int, 0644); -MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 " - "4=stv0903+stb6100(or-able))."); +MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able))."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -2343,12 +2342,7 @@ static struct usb_driver dw2102_driver = { module_usb_driver(dw2102_driver); MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); -MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," - " DVB-C 3101 USB2.0," - " TeVii S421, S480, S482, S600, S630, S632, S650," - " TeVii S660, S662, Prof 1100, 7500 USB2.0," - " Geniatech SU3000, T220," - " TechnoTrend S2-4600, Terratec Cinergy S2 devices"); +MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101 USB2.0, TeVii S421, S480, S482, S600, S630, S632, S650, TeVii S660, S662, Prof 1100, 7500 USB2.0, Geniatech SU3000, T220, TechnoTrend S2-4600, Terratec Cinergy S2 devices"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(DW2101_FIRMWARE); diff --git a/drivers/media/usb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c index 474a17e4db0c..62abe6c43a32 100644 --- a/drivers/media/usb/dvb-usb/friio.c +++ b/drivers/media/usb/dvb-usb/friio.c @@ -320,8 +320,8 @@ restart: */ if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */ if (++retry > 3) { - deb_info("failed to get the correct" - " FE demod status:0x%02x\n", rbuf[0]); + deb_info("failed to get the correct FE demod status:0x%02x\n", + rbuf[0]); goto error; } msleep(100); diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c index adfd76491451..db9e9a9721a0 100644 --- a/drivers/media/usb/dvb-usb/gp8psk.c +++ b/drivers/media/usb/dvb-usb/gp8psk.c @@ -131,8 +131,7 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) u8 *buf; if ((ret = request_firmware(&fw, bcm4500_firmware, &d->udev->dev)) != 0) { - err("did not find the bcm4500 firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", + err("did not find the bcm4500 firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", bcm4500_firmware,ret); return ret; } diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c index 2566d2f1c2ad..946a5ccc8f1a 100644 --- a/drivers/media/usb/dvb-usb/opera1.c +++ b/drivers/media/usb/dvb-usb/opera1.c @@ -453,8 +453,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, info("start downloading fpga firmware %s",filename); if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems.", + err("did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems.", filename); return ret; } else { diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 4706628a3ed5..02c3bee6f83b 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -50,8 +50,7 @@ MODULE_PARM_DESC(debug, static int disable_led_control; module_param(disable_led_control, int, 0444); MODULE_PARM_DESC(disable_led_control, - "disable LED control of the device " - "(default: 0 - LED control is active)."); + "disable LED control of the device (default: 0 - LED control is active)."); /* device private data */ struct technisat_usb2_state { -- cgit v1.2.3 From 4ab3200608760981c0d64c42d85edf34eb2659dd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:15 -0200 Subject: [media] dvb-usb-v2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c | 12 +++++------- drivers/media/usb/dvb-usb-v2/mxl111sf.c | 10 ++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c index 283495c84ba3..6427137a09ef 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c @@ -666,8 +666,8 @@ static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state, if (rd_status[i] == 0x04) { if (i < 7) { - mxl_i2c("i2c fifo empty!" - " @ %d", i); + mxl_i2c("i2c fifo empty! @ %d", + i); msg->buf[(index*8)+i] = i2c_r_data[(i*3)+1]; /* read again */ @@ -692,8 +692,7 @@ static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state, } goto stop_copy; } else { - mxl_i2c("readagain " - "ERROR!"); + mxl_i2c("readagain ERROR!"); } } else { msg->buf[(index*8)+i] = @@ -827,9 +826,8 @@ int mxl111sf_i2c_xfer(struct i2c_adapter *adap, mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) : mxl111sf_i2c_sw_xfer_msg(state, &msg[i]); if (mxl_fail(ret)) { - mxl_debug_adv("failed with error %d on i2c " - "transaction %d of %d, %sing %d bytes " - "to/from 0x%02x", ret, i+1, num, + mxl_debug_adv("failed with error %d on i2c transaction %d of %d, %sing %d bytes to/from 0x%02x", + ret, i+1, num, (msg[i].flags & I2C_M_RD) ? "read" : "writ", msg[i].len, msg[i].addr); diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index 5d676b533a3a..80c635980526 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c @@ -29,8 +29,7 @@ int dvb_usb_mxl111sf_debug; module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level " - "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able))."); +MODULE_PARM_DESC(debug, "set debugging level (1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able))."); static int dvb_usb_mxl111sf_isoc; module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644); @@ -137,8 +136,8 @@ int mxl111sf_write_reg_mask(struct mxl111sf_state *state, #if 1 /* dont know why this usually errors out on the first try */ if (mxl_fail(ret)) - pr_err("error writing addr: 0x%02x, mask: 0x%02x, " - "data: 0x%02x, retrying...", addr, mask, data); + pr_err("error writing addr: 0x%02x, mask: 0x%02x, data: 0x%02x, retrying...", + addr, mask, data); ret = mxl111sf_read_reg(state, addr, &val); #endif @@ -946,8 +945,7 @@ static int mxl111sf_init(struct dvb_usb_device *d) case 138001: break; default: - printk(KERN_WARNING "%s: warning: " - "unknown hauppauge model #%d\n", + printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", __func__, state->tv.model); } #endif -- cgit v1.2.3 From c558d13c216d3baff033025a9ddc6c70a1767031 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:15 -0200 Subject: [media] em28xx: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index bcd6ac61d9f8..898fab136534 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -1561,8 +1561,7 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker " - "/ Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U", + .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U", .tuner_type = TUNER_ABSENT, /* capture only board */ .decoder = EM28XX_SAA711X, .input = { { -- cgit v1.2.3 From 1ddc9f75a4c95dd284cd33783b72ed0ae4709a09 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:16 -0200 Subject: [media] gspca: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/gspca.c | 3 +-- drivers/media/usb/gspca/m5602/m5602_core.c | 11 ++++------- drivers/media/usb/gspca/mr97310a.c | 3 +-- drivers/media/usb/gspca/ov519.c | 3 +-- drivers/media/usb/gspca/pac207.c | 4 ++-- drivers/media/usb/gspca/pac7302.c | 3 +-- drivers/media/usb/gspca/sn9c20x.c | 6 ++---- drivers/media/usb/gspca/sq905.c | 3 +-- drivers/media/usb/gspca/sq905c.c | 4 ++-- drivers/media/usb/gspca/stv06xx/stv06xx.c | 9 +++------ drivers/media/usb/gspca/sunplus.c | 3 +-- drivers/media/usb/gspca/topro.c | 3 +-- drivers/media/usb/gspca/zc3xx.c | 3 +-- 13 files changed, 21 insertions(+), 37 deletions(-) diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index af2395a76d8b..fa2cbb981905 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -201,8 +201,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, buffer_len = le16_to_cpu(ep->wMaxPacketSize); interval = ep->bInterval; - PDEBUG(D_CONF, "found int in endpoint: 0x%x, " - "buffer_len=%u, interval=%u", + PDEBUG(D_CONF, "found int in endpoint: 0x%x, buffer_len=%u, interval=%u", ep->bEndpointAddress, buffer_len, interval); dev = gspca_dev->dev; diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c index e4a0658e3f83..f1dcd9021983 100644 --- a/drivers/media/usb/gspca/m5602/m5602_core.c +++ b/drivers/media/usb/gspca/m5602/m5602_core.c @@ -154,8 +154,8 @@ int m5602_read_sensor(struct sd *sd, const u8 address, err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - PDEBUG(D_CONF, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); + PDEBUG(D_CONF, "Reading sensor register 0x%x containing 0x%x ", + address, *i2c_data); } return err; } @@ -441,13 +441,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(force_sensor, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(force_sensor, - "forces detection of a sensor, " - "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, " - "4 = MT9M111, 5 = PO1030, 6 = OV7660"); + "forces detection of a sensor, 1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030, 6 = OV7660"); module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers " - "at startup providing a sensor is found"); +MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers at startup providing a sensor is found"); diff --git a/drivers/media/usb/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c index f006e29ca019..6dfb364094ec 100644 --- a/drivers/media/usb/gspca/mr97310a.c +++ b/drivers/media/usb/gspca/mr97310a.c @@ -72,8 +72,7 @@ #define MR97310A_MIN_CLOCKDIV_MAX 8 #define MR97310A_MIN_CLOCKDIV_DEFAULT 3 -MODULE_AUTHOR("Kyle Guinn ," - "Theodore Kilgore "); +MODULE_AUTHOR("Kyle Guinn ,Theodore Kilgore "); MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index 965372a5ff2f..4dbca54cf2a8 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c @@ -4326,8 +4326,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, /* Frame end */ if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width || (in[10] + 1) * 8 != gspca_dev->pixfmt.height) { - PERR("Invalid frame size, got: %dx%d," - " requested: %dx%d\n", + PERR("Invalid frame size, got: %dx%d, requested: %dx%d\n", (in[9] + 1) * 8, (in[10] + 1) * 8, gspca_dev->pixfmt.width, gspca_dev->pixfmt.height); diff --git a/drivers/media/usb/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c index 07529e5a0c56..51e11248bbb8 100644 --- a/drivers/media/usb/gspca/pac207.c +++ b/drivers/media/usb/gspca/pac207.c @@ -179,8 +179,8 @@ static int sd_config(struct gspca_dev *gspca_dev, } PDEBUG(D_PROBE, - "Pixart PAC207BCA Image Processor and Control Chip detected" - " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); + "Pixart PAC207BCA Image Processor and Control Chip detected (vid/pid 0x%04X:0x%04X)", + id->idVendor, id->idProduct); cam = &gspca_dev->cam; cam->cam_mode = sif_mode; diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c index 8b08bd0172f4..be07a24c4518 100644 --- a/drivers/media/usb/gspca/pac7302.c +++ b/drivers/media/usb/gspca/pac7302.c @@ -105,8 +105,7 @@ #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */ #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ -MODULE_AUTHOR("Jean-Francois Moine , " - "Thomas Kaiser thomas@kaiser-linux.li"); +MODULE_AUTHOR("Jean-Francois Moine , Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7302"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c index 10269dad9d20..e7430b06526a 100644 --- a/drivers/media/usb/gspca/sn9c20x.c +++ b/drivers/media/usb/gspca/sn9c20x.c @@ -29,8 +29,7 @@ #include -MODULE_AUTHOR("Brian Johnson , " - "microdia project "); +MODULE_AUTHOR("Brian Johnson , microdia project "); MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1948,8 +1947,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); if (intf->num_altsetting != 9) { - pr_warn("sn9c20x camera with unknown number of alt " - "settings (%d), please report!\n", + pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n", intf->num_altsetting); gspca_dev->alt = intf->num_altsetting; return 0; diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index a7ae0ec9fa91..9424c33f0ddb 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -41,8 +41,7 @@ #include #include "gspca.h" -MODULE_AUTHOR("Adam Baker , " - "Theodore Kilgore "); +MODULE_AUTHOR("Adam Baker , Theodore Kilgore "); MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c index aa21edc9502d..e02b8c1d06a2 100644 --- a/drivers/media/usb/gspca/sq905c.c +++ b/drivers/media/usb/gspca/sq905c.c @@ -210,8 +210,8 @@ static int sd_config(struct gspca_dev *gspca_dev, int ret; PDEBUG(D_PROBE, - "SQ9050 camera detected" - " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); + "SQ9050 camera detected (vid/pid 0x%04X:0x%04X)", + id->idVendor, id->idProduct); ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0); if (ret < 0) { diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 6ac93d8db427..562ddb050cfd 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -412,8 +412,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, len -= 4; if (len < chunk_len) { - PERR("URB packet length is smaller" - " than the specified chunk length"); + PERR("URB packet length is smaller than the specified chunk length"); gspca_dev->last_packet_type = DISCARD_PACKET; return; } @@ -455,8 +454,7 @@ frame_data: sd->to_skip = gspca_dev->pixfmt.width * 4; if (chunk_len) - PERR("Chunk length is " - "non-zero on a SOF"); + PERR("Chunk length is non-zero on a SOF"); break; case 0x8002: @@ -469,8 +467,7 @@ frame_data: NULL, 0); if (chunk_len) - PERR("Chunk length is " - "non-zero on a EOF"); + PERR("Chunk length is non-zero on a EOF"); break; case 0x0005: diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index 46c9f2229a18..38dc9e7aa313 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -368,8 +368,7 @@ static void spca504_read_info(struct gspca_dev *gspca_dev) info[i] = gspca_dev->usb_buf[0]; } PDEBUG(D_STREAM, - "Read info: %d %d %d %d %d %d." - " Should be 1,0,2,2,0,0", + "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0", info[0], info[1], info[2], info[3], info[4], info[5]); } diff --git a/drivers/media/usb/gspca/topro.c b/drivers/media/usb/gspca/topro.c index 15eb069ab60b..983fc6b500af 100644 --- a/drivers/media/usb/gspca/topro.c +++ b/drivers/media/usb/gspca/topro.c @@ -24,8 +24,7 @@ #include "gspca.h" MODULE_DESCRIPTION("Topro TP6800/6810 gspca webcam driver"); -MODULE_AUTHOR("Jean-Francois Moine , " - "Anders Blomdell "); +MODULE_AUTHOR("Jean-Francois Moine , Anders Blomdell "); MODULE_LICENSE("GPL"); static int force_sensor = -1; diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c index 5f7254d2bc9a..d5d8c7e81762 100644 --- a/drivers/media/usb/gspca/zc3xx.c +++ b/drivers/media/usb/gspca/zc3xx.c @@ -25,8 +25,7 @@ #include "gspca.h" #include "jpeg.h" -MODULE_AUTHOR("Jean-Francois Moine , " - "Serge A. Suchkov "); +MODULE_AUTHOR("Jean-Francois Moine , Serge A. Suchkov "); MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4d5ded751e8651707d5b6b59bcd45576c1b04bff Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:17 -0200 Subject: [media] hdpvr: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/hdpvr/hdpvr-core.c | 9 +++------ drivers/media/usb/hdpvr/hdpvr-i2c.c | 7 +++---- drivers/media/usb/hdpvr/hdpvr-video.c | 4 +--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index a61d8fd63c12..15f016ad5b89 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -41,13 +41,11 @@ MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); static uint default_video_input = HDPVR_VIDEO_INPUTS; module_param(default_video_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " - "1=S-Video / 2=Composite"); +MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / 1=S-Video / 2=Composite"); static uint default_audio_input = HDPVR_AUDIO_INPUTS; module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " - "1=RCA front / 2=S/PDIF"); +MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / 1=RCA front / 2=S/PDIF"); static bool boost_audio; module_param(boost_audio, bool, S_IRUGO|S_IWUSR); @@ -165,8 +163,7 @@ static int device_authorization(struct hdpvr_device *dev) dev->flags |= HDPVR_FLAG_AC3_CAP; break; default: - v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might" - " not work.\n"); + v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might not work.\n"); if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3) dev->flags |= HDPVR_FLAG_AC3_CAP; else diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c index 9b641c4d4431..fcab55038d99 100644 --- a/drivers/media/usb/hdpvr/hdpvr-i2c.c +++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c @@ -145,15 +145,14 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, msgs[0].len); } else if (num == 2) { if (msgs[0].addr != msgs[1].addr) { - v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer " - "with conflicting target addresses\n"); + v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer with conflicting target addresses\n"); retval = -EINVAL; goto out; } if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) { - v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with " - "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD, + v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with r0=%d, r1=%d\n", + msgs[0].flags & I2C_M_RD, msgs[1].flags & I2C_M_RD); retval = -EINVAL; goto out; diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 474c11e1d495..e3e7682d0f0e 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -336,9 +336,7 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) buf = kmalloc(dev->bulk_in_size, GFP_KERNEL); if (!buf) - v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer " - "for emptying the internal device buffer. " - "Next capture start will be slow\n"); + v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer for emptying the internal device buffer. Next capture start will be slow\n"); dev->status = STATUS_SHUTTING_DOWN; hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); -- cgit v1.2.3 From 96292c89cf1fa700ba086fd7c0e431ac90adba10 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:18 -0200 Subject: [media] pvrusb2: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-audio.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-debugifc.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-eeprom.c | 7 +- drivers/media/usb/pvrusb2/pvrusb2-encoder.c | 29 ++-- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 181 ++++++++---------------- drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 33 ++--- drivers/media/usb/pvrusb2/pvrusb2-io.c | 35 ++--- drivers/media/usb/pvrusb2/pvrusb2-ioread.c | 36 ++--- drivers/media/usb/pvrusb2/pvrusb2-std.c | 3 +- drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 10 +- drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-wm8775.c | 3 +- 14 files changed, 118 insertions(+), 239 deletions(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-audio.c b/drivers/media/usb/pvrusb2/pvrusb2-audio.c index 5f953d837bf1..3bac50a248d4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-audio.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-audio.c @@ -74,9 +74,7 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) input = sp->def[hdw->input_val]; } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev msp3400 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", + "*** WARNING *** subdev msp3400 set_input: Invalid routing scheme (%u) and/or input (%d)", sid, hdw->input_val); return; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c index f82f0f0f2c04..7f29a0464f36 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c @@ -72,9 +72,7 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) (hdw->input_val < 0) || (hdw->input_val >= sp->cnt)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", + "*** WARNING *** subdev v4l2 set_input: Invalid routing scheme (%u) and/or input (%d)", sid, hdw->input_val); return; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c index 7d675fae1846..30eef97ef2ef 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -137,9 +137,7 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) (hdw->input_val < 0) || (hdw->input_val >= sp->cnt)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev cx2584x set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", + "*** WARNING *** subdev cx2584x set_input: Invalid routing scheme (%u) and/or input (%d)", sid, hdw->input_val); return; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c index e4022bcb155b..58ec706ebdb3 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c @@ -176,9 +176,7 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, pvr2_stream_get_stats(sp, &stats, 0); ccnt = scnprintf( buf,acnt, - "Bytes streamed=%u" - " URBs: queued=%u idle=%u ready=%u" - " processed=%u failed=%u\n", + "Bytes streamed=%u URBs: queued=%u idle=%u ready=%u processed=%u failed=%u\n", stats.bytes_processed, stats.buffers_in_queue, stats.buffers_in_idle, diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c index e1907cd0c3b7..276b17fb9aad 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c @@ -56,8 +56,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); if (!eeprom) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); + "Failed to allocate memory required to read eeprom"); return NULL; } @@ -74,8 +73,8 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) strange but it's what they do) */ mode16 = (addr & 1); eepromSize = (mode16 ? 4096 : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, + trace_eeprom("Examining %d byte eeprom at location 0x%x using %d bit addressing", + eepromSize, addr, mode16 ? 16 : 8); msg[0].addr = addr; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c index 593b3e9b6bfd..f0483621d2a3 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c @@ -188,9 +188,7 @@ static int pvr2_encoder_cmd(void *ctxt, if (arg_cnt_send > (ARRAY_SIZE(wrData) - 4)) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many input arguments" - " (was given %u limit %lu)", + "Failed to write cx23416 command - too many input arguments (was given %u limit %lu)", arg_cnt_send, (long unsigned) ARRAY_SIZE(wrData) - 4); return -EINVAL; } @@ -198,9 +196,7 @@ static int pvr2_encoder_cmd(void *ctxt, if (arg_cnt_recv > (ARRAY_SIZE(rdData) - 4)) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many return arguments" - " (was given %u limit %lu)", + "Failed to write cx23416 command - too many return arguments (was given %u limit %lu)", arg_cnt_recv, (long unsigned) ARRAY_SIZE(rdData) - 4); return -EINVAL; } @@ -248,14 +244,12 @@ static int pvr2_encoder_cmd(void *ctxt, retry_flag = !0; pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Encoder timed out waiting for us" - "; arranging to retry"); + "Encoder timed out waiting for us; arranging to retry"); } else { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "***WARNING*** device's encoder" - " appears to be stuck" - " (status=0x%08x)",rdData[0]); + "***WARNING*** device's encoder appears to be stuck (status=0x%08x)", +rdData[0]); } pvr2_trace( PVR2_TRACE_ERROR_LEGS, @@ -293,11 +287,7 @@ static int pvr2_encoder_cmd(void *ctxt, } pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Giving up on command." - " This is normally recovered via a firmware" - " reload and re-initialization; concern" - " is only warranted if this happens repeatedly" - " and rapidly."); + "Giving up on command. This is normally recovered via a firmware reload and re-initialization; concern is only warranted if this happens repeatedly and rapidly."); break; } wrData[0] = 0x7; @@ -325,9 +315,7 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, if (args > ARRAY_SIZE(data)) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many arguments" - " (was given %u limit %lu)", + "Failed to write cx23416 command - too many arguments (was given %u limit %lu)", args, (long unsigned) ARRAY_SIZE(data)); return -EINVAL; } @@ -433,8 +421,7 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) { int ret; int val; - pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" - " (cx2341x module)"); + pvr2_trace(PVR2_TRACE_ENCODER, "pvr2_encoder_configure (cx2341x module)"); hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; hdw->enc_ctl_state.width = hdw->res_hor_val; hdw->enc_ctl_state.height = hdw->res_ver_val; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 1eb4f7ba2967..e3ed8ffee9f7 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -1371,8 +1371,7 @@ static int pvr2_locate_firmware(struct pvr2_hdw *hdw, fwnames[idx], &hdw->usb_dev->dev); if (!ret) { - trace_firmware("Located %s firmware: %s;" - " uploading...", + trace_firmware("Located %s firmware: %s; uploading...", fwtypename, fwnames[idx]); return idx; @@ -1383,21 +1382,17 @@ static int pvr2_locate_firmware(struct pvr2_hdw *hdw, return ret; } pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device %s firmware" - " seems to be missing.", + "***WARNING*** Device %s firmware seems to be missing.", fwtypename); pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware files" - " in their proper location?"); + "Did you install the pvrusb2 firmware files in their proper location?"); if (fwcount == 1) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "request_firmware unable to locate %s file %s", fwtypename,fwnames[0]); } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate" - " one of the following %s files:", + "request_firmware unable to locate one of the following %s files:", fwtypename); for (idx = 0; idx < fwcount; idx++) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, @@ -1431,8 +1426,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) if (!hdw->hdw_desc->fx2_firmware.cnt) { hdw->fw1_state = FW1_STATE_OK; pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Connected device type defines" - " no firmware to upload; ignoring firmware"); + "Connected device type defines no firmware to upload; ignoring firmware"); return -ENOTTY; } @@ -1457,13 +1451,11 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) { if (hdw->hdw_desc->flag_fx2_16kb) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Wrong fx2 firmware size" - " (expected 8192 or 16384, got %u)", + "Wrong fx2 firmware size (expected 8192 or 16384, got %u)", fwsize); } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Wrong fx2 firmware size" - " (expected 8192, got %u)", + "Wrong fx2 firmware size (expected 8192, got %u)", fwsize); } release_firmware(fw_entry); @@ -1585,8 +1577,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) if (fw_len % sizeof(u32)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "size of %s firmware" - " must be a multiple of %zu bytes", + "size of %s firmware must be a multiple of %zu bytes", fw_files[fwidx],sizeof(u32)); release_firmware(fw_entry); ret = -EINVAL; @@ -1887,8 +1878,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); pvr2_trace(PVR2_TRACE_STD, - "Supported video standard(s) reported available" - " in hardware: %.*s", + "Supported video standard(s) reported available in hardware: %.*s", bcnt,buf); hdw->std_mask_avail = hdw->std_mask_eeprom; @@ -1897,8 +1887,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) if (std2) { bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); pvr2_trace(PVR2_TRACE_STD, - "Expanding supported video standards" - " to include: %.*s", + "Expanding supported video standards to include: %.*s", bcnt,buf); hdw->std_mask_avail |= std2; } @@ -1917,8 +1906,8 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) if (std3) { bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3); pvr2_trace(PVR2_TRACE_STD, - "Initial video standard" - " (determined by device type): %.*s",bcnt,buf); + "Initial video standard (determined by device type): %.*s", + bcnt, buf); hdw->std_mask_cur = std3; hdw->std_dirty = !0; return; @@ -1980,8 +1969,7 @@ static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw) } pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Executing cx25840 VBI hack", + "Module ID %u: Executing cx25840 VBI hack", hdw->decoder_client_id); memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; @@ -2007,8 +1995,7 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; if (!fname) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u for device %s has no name?" - " The driver might have a configuration problem.", + "Module ID %u for device %s has no name? The driver might have a configuration problem.", mid, hdw->hdw_desc->description); return -EINVAL; @@ -2027,32 +2014,27 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, ARRAY_SIZE(i2caddr)); if (i2ccnt) { pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Using default i2c address list", + "Module ID %u: Using default i2c address list", mid); } } if (!i2ccnt) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s:" - " No i2c addresses." - " The driver might have a configuration problem.", + "Module ID %u (%s) for device %s: No i2c addresses. The driver might have a configuration problem.", mid, fname, hdw->hdw_desc->description); return -EINVAL; } if (i2ccnt == 1) { pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with specified i2c address 0x%x", + "Module ID %u: Setting up with specified i2c address 0x%x", mid, i2caddr[0]); sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, fname, i2caddr[0], NULL); } else { pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with address probe list", + "Module ID %u: Setting up with address probe list", mid); sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, fname, 0, i2caddr); @@ -2060,9 +2042,7 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, if (!sd) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s failed to load." - " Possible missing sub-device kernel module or" - " initialization failure within module.", + "Module ID %u (%s) for device %s failed to load. Possible missing sub-device kernel module or initialization failure within module.", mid, fname, hdw->hdw_desc->description); return -EIO; } @@ -2124,18 +2104,14 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) == 0); if (reloadFl) { pvr2_trace(PVR2_TRACE_INIT, - "USB endpoint config looks strange" - "; possibly firmware needs to be" - " loaded"); + "USB endpoint config looks strange; possibly firmware needs to be loaded"); } } if (!reloadFl) { reloadFl = !pvr2_hdw_check_firmware(hdw); if (reloadFl) { pvr2_trace(PVR2_TRACE_INIT, - "Check for FX2 firmware failed" - "; possibly firmware needs to be" - " loaded"); + "Check for FX2 firmware failed; possibly firmware needs to be loaded"); } } if (reloadFl) { @@ -2200,8 +2176,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; if (ret < 0) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to determine location of eeprom," - " skipping"); + "Unable to determine location of eeprom, skipping"); } else { hdw->eeprom_addr = ret; pvr2_eeprom_analyze(hdw); @@ -2254,8 +2229,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) idx = get_default_error_tolerance(hdw); if (idx) { pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream %p" - " setting tolerance %u", + "pvr2_hdw_setup: video stream %p setting tolerance %u", hdw->vid_stream,idx); } pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, @@ -2285,16 +2259,13 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw) if (hdw->flag_init_ok) { pvr2_trace( PVR2_TRACE_INFO, - "Device initialization" - " completed successfully."); + "Device initialization completed successfully."); break; } if (hdw->fw1_state == FW1_STATE_RELOAD) { pvr2_trace( PVR2_TRACE_INFO, - "Device microcontroller firmware" - " (re)loaded; it should now reset" - " and reconnect."); + "Device microcontroller firmware (re)loaded; it should now reset and reconnect."); break; } pvr2_trace( @@ -2303,48 +2274,35 @@ static void pvr2_hdw_setup(struct pvr2_hdw *hdw) if (hdw->fw1_state == FW1_STATE_MISSING) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Giving up since device" - " microcontroller firmware" - " appears to be missing."); + "Giving up since device microcontroller firmware appears to be missing."); break; } } if (hdw->flag_modulefail) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 driver initialization" - " failed due to the failure of one or more" - " sub-device kernel modules."); + "***WARNING*** pvrusb2 driver initialization failed due to the failure of one or more sub-device kernel modules."); pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "You need to resolve the failing condition" - " before this driver can function. There" - " should be some earlier messages giving more" - " information about the problem."); + "You need to resolve the failing condition before this driver can function. There should be some earlier messages giving more information about the problem."); break; } if (procreload) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Attempting pvrusb2 recovery by reloading" - " primary firmware."); + "Attempting pvrusb2 recovery by reloading primary firmware."); pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "If this works, device should disconnect" - " and reconnect in a sane state."); + "If this works, device should disconnect and reconnect in a sane state."); hdw->fw1_state = FW1_STATE_UNKNOWN; pvr2_upload_firmware1(hdw); } else { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 device hardware" - " appears to be jammed" - " and I can't clear it."); + "***WARNING*** pvrusb2 device hardware appears to be jammed and I can't clear it."); pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "You might need to power cycle" - " the pvrusb2 device" - " in order to recover."); + "You might need to power cycle the pvrusb2 device in order to recover."); } } while (0); pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); @@ -2396,12 +2354,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); if (hdw_desc == NULL) { - pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create:" - " No device description pointer," - " unable to continue."); - pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type," - " please contact Mike Isely " - " to get it included in the driver\n"); + pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create: No device description pointer, unable to continue."); + pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type, please contact Mike Isely to get it included in the driver\n"); goto fail; } @@ -2413,14 +2367,12 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, if (hdw_desc->flag_is_experimental) { pvr2_trace(PVR2_TRACE_INFO, "**********"); pvr2_trace(PVR2_TRACE_INFO, - "WARNING: Support for this device (%s) is" - " experimental.", hdw_desc->description); + "WARNING: Support for this device (%s) is experimental.", + hdw_desc->description); pvr2_trace(PVR2_TRACE_INFO, - "Important functionality might not be" - " entirely working."); + "Important functionality might not be entirely working."); pvr2_trace(PVR2_TRACE_INFO, - "Please consider contacting the driver author to" - " help with further stabilization of the driver."); + "Please consider contacting the driver author to help with further stabilization of the driver."); pvr2_trace(PVR2_TRACE_INFO, "**********"); } if (!hdw) goto fail; @@ -3375,8 +3327,7 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); if (!eeprom) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); + "Failed to allocate memory required to read eeprom"); return NULL; } @@ -3393,8 +3344,8 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) strange but it's what they do) */ mode16 = (addr & 1); eepromSize = (mode16 ? EEPROM_SIZE : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, + trace_eeprom("Examining %d byte eeprom at location 0x%x using %d bit addressing", + eepromSize, addr, mode16 ? 16 : 8); msg[0].addr = addr; @@ -3461,8 +3412,8 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, if (hdw->fw_cpu_flag) { hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000; pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware" - " (size=%u)", hdw->fw_size); + "Preparing to suck out CPU firmware (size=%u)", + hdw->fw_size); hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); if (!hdw->fw_buffer) { hdw->fw_size = 0; @@ -3620,21 +3571,18 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, struct timer_list timer; if (!hdw->ctl_lock_held) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " without lock!!"); + "Attempted to execute control transfer without lock!!"); return -EDEADLK; } if (!hdw->flag_ok && !probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when device not ok"); + "Attempted to execute control transfer when device not ok"); return -EIO; } if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { if (!probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when USB is disconnected"); + "Attempted to execute control transfer when USB is disconnected"); } return -ENOTTY; } @@ -3645,16 +3593,14 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, if (write_len > PVR2_CTL_BUFFSIZE) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-write transfer (limit=%d)", + "Attempted to execute %d byte control-write transfer (limit=%d)", write_len,PVR2_CTL_BUFFSIZE); return -EINVAL; } if (read_len > PVR2_CTL_BUFFSIZE) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-read transfer (limit=%d)", + "Attempted to execute %d byte control-read transfer (limit=%d)", write_len,PVR2_CTL_BUFFSIZE); return -EINVAL; } @@ -3703,8 +3649,8 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); if (status < 0) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit write-control" - " URB status=%d",status); + "Failed to submit write-control URB status=%d", +status); hdw->ctl_write_pend_flag = 0; goto done; } @@ -3727,8 +3673,8 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); if (status < 0) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit read-control" - " URB status=%d",status); + "Failed to submit read-control URB status=%d", +status); hdw->ctl_read_pend_flag = 0; goto done; } @@ -3770,8 +3716,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = hdw->ctl_write_urb->status; if (!probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB failure," - " status=%d", + "control-write URB failure, status=%d", status); } goto done; @@ -3781,8 +3726,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = -EIO; if (!probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB short," - " expected=%d got=%d", + "control-write URB short, expected=%d got=%d", write_len, hdw->ctl_write_urb->actual_length); } @@ -3800,8 +3744,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = hdw->ctl_read_urb->status; if (!probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB failure," - " status=%d", + "control-read URB failure, status=%d", status); } goto done; @@ -3811,8 +3754,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, status = -EIO; if (!probe_fl) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB short," - " expected=%d got=%d", + "control-read URB short, expected=%d got=%d", read_len, hdw->ctl_read_urb->actual_length); } @@ -4799,9 +4741,7 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, 0); return scnprintf( buf,acnt, - "Bytes streamed=%u" - " URBs: queued=%u idle=%u ready=%u" - " processed=%u failed=%u", + "Bytes streamed=%u URBs: queued=%u idle=%u ready=%u processed=%u failed=%u", stats.bytes_processed, stats.buffers_in_queue, stats.buffers_in_idle, @@ -5013,8 +4953,7 @@ int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val) if (ret) return ret; nval = (cval & ~msk) | (val & msk); pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing 0x%x:0x%x" - " from 0x%x to 0x%x", + "GPIO direction changing 0x%x:0x%x from 0x%x to 0x%x", msk,val,cval,nval); } else { nval = val; @@ -5057,9 +4996,7 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) now. (Of course, no sub-drivers seem to implement it either. But now it's a a chicken and egg problem...) */ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp); - pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll" - " type=%u strength=%u audio=0x%x cap=0x%x" - " low=%u hi=%u", + pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll type=%u strength=%u audio=0x%x cap=0x%x low=%u hi=%u", vtp->type, vtp->signal, vtp->rxsubchans, vtp->capability, vtp->rangelow, vtp->rangehigh); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c index 6da5fb544817..48d837e39a9c 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c @@ -62,8 +62,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ if (!data) length = 0; if (length > (sizeof(hdw->cmd_buffer) - 3)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C write to %u that is too large" - " (desired=%u limit=%u)", + "Killing an I2C write to %u that is too large (desired=%u limit=%u)", i2c_addr, length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); return -ENOTSUPP; @@ -90,8 +89,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ if (hdw->cmd_buffer[0] != 8) { ret = -EIO; if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_write[%d]: %d", + trace_i2c("unexpected status from i2_write[%d]: %d", i2c_addr,hdw->cmd_buffer[0]); } } @@ -116,16 +114,14 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ if (!data) dlen = 0; if (dlen > (sizeof(hdw->cmd_buffer) - 4)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has wlen too large" - " (desired=%u limit=%u)", + "Killing an I2C read to %u that has wlen too large (desired=%u limit=%u)", i2c_addr, dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4)); return -ENOTSUPP; } if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has rlen too large" - " (desired=%u limit=%u)", + "Killing an I2C read to %u that has rlen too large (desired=%u limit=%u)", i2c_addr, rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1)); return -ENOTSUPP; @@ -154,8 +150,7 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ if (hdw->cmd_buffer[0] != 8) { ret = -EIO; if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_read[%d]: %d", + trace_i2c("unexpected status from i2_read[%d]: %d", i2c_addr,hdw->cmd_buffer[0]); } } @@ -352,13 +347,11 @@ static int i2c_hack_cx25840(struct pvr2_hdw *hdw, if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Detected a wedged cx25840 chip;" - " the device will not work."); + "WARNING: Detected a wedged cx25840 chip; the device will not work."); pvr2_trace(PVR2_TRACE_ERROR_LEGS, "WARNING: Try power cycling the pvrusb2 device."); pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Disabling further access to the device" - " to prevent other foul-ups."); + "WARNING: Disabling further access to the device to prevent other foul-ups."); // This blocks all further communication with the part. hdw->i2c_func[0x44] = NULL; pvr2_hdw_render_useless(hdw); @@ -444,8 +437,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, } } else if (num == 2) { if (msgs[0].addr != msgs[1].addr) { - trace_i2c("i2c refusing 2 phase transfer with" - " conflicting target addresses"); + trace_i2c("i2c refusing 2 phase transfer with conflicting target addresses"); ret = -ENOTSUPP; goto done; } @@ -477,8 +469,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, ret = 2; goto done; } else { - trace_i2c("i2c refusing complex transfer" - " read0=%d read1=%d", + trace_i2c("i2c refusing complex transfer read0=%d read1=%d", (msgs[0].flags & I2C_M_RD), (msgs[1].flags & I2C_M_RD)); } @@ -492,8 +483,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, for (idx = 0; idx < num; idx++) { cnt = msgs[idx].len; printk(KERN_INFO - "pvrusb2 i2c xfer %u/%u:" - " addr=0x%x len=%d %s", + "pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s", idx+1,num, msgs[idx].addr, cnt, @@ -668,8 +658,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) the emulated IR receiver. */ if (do_i2c_probe(hdw, 0x71)) { pvr2_trace(PVR2_TRACE_INFO, - "Device has newer IR hardware;" - " disabling unneeded virtual IR device"); + "Device has newer IR hardware; disabling unneeded virtual IR device"); hdw->i2c_func[0x18] = NULL; /* Remember that this is a different device... */ hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c index e68ce24f27e3..e3103ecd4828 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-io.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c @@ -113,8 +113,7 @@ static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st) static void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg) { pvr2_trace(PVR2_TRACE_INFO, - "buffer%s%s %p state=%s id=%d status=%d" - " stream=%p purb=%p sig=0x%x", + "buffer%s%s %p state=%s id=%d status=%d stream=%p purb=%p sig=0x%x", (msg ? " " : ""), (msg ? msg : ""), bp, @@ -156,8 +155,7 @@ static void pvr2_buffer_remove(struct pvr2_buffer *bp) (*cnt)--; (*bcnt) -= ccnt; pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s dec cap=%07d cnt=%02d", + "/*---TRACE_FLOW---*/ bufferPool %8s dec cap=%07d cnt=%02d", pvr2_buffer_state_decode(bp->state),*bcnt,*cnt); bp->state = pvr2_buffer_state_none; } @@ -198,8 +196,7 @@ static int pvr2_buffer_set_ready(struct pvr2_buffer *bp) (sp->r_count)++; sp->r_bcount += bp->used_count; pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", + "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d", pvr2_buffer_state_decode(bp->state), sp->r_bcount,sp->r_count); spin_unlock_irqrestore(&sp->list_lock,irq_flags); @@ -224,8 +221,7 @@ static void pvr2_buffer_set_idle(struct pvr2_buffer *bp) (sp->i_count)++; sp->i_bcount += bp->max_count; pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", + "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d", pvr2_buffer_state_decode(bp->state), sp->i_bcount,sp->i_count); spin_unlock_irqrestore(&sp->list_lock,irq_flags); @@ -249,8 +245,7 @@ static void pvr2_buffer_set_queued(struct pvr2_buffer *bp) (sp->q_count)++; sp->q_bcount += bp->max_count; pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", + "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d", pvr2_buffer_state_decode(bp->state), sp->q_bcount,sp->q_count); spin_unlock_irqrestore(&sp->list_lock,irq_flags); @@ -293,8 +288,8 @@ static void pvr2_buffer_done(struct pvr2_buffer *bp) bp->signature = 0; bp->stream = NULL; usb_free_urb(bp->purb); - pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" - " bufferDone %p",bp); + pvr2_trace(PVR2_TRACE_BUF_POOL, "/*---TRACE_FLOW---*/ bufferDone %p", + bp); } static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) @@ -306,8 +301,7 @@ static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) if (cnt == sp->buffer_total_count) return 0; pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ poolResize " - " stream=%p cur=%d adj=%+d", + "/*---TRACE_FLOW---*/ poolResize stream=%p cur=%d adj=%+d", sp, sp->buffer_total_count, cnt-sp->buffer_total_count); @@ -374,8 +368,7 @@ static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp) if (sp->buffer_total_count == sp->buffer_target_count) return 0; pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/" - " poolCheck stream=%p cur=%d tgt=%d", + "/*---TRACE_FLOW---*/ poolCheck stream=%p cur=%d tgt=%d", sp,sp->buffer_total_count,sp->buffer_target_count); if (sp->buffer_total_count < sp->buffer_target_count) { @@ -454,8 +447,8 @@ static void buffer_complete(struct urb *urb) bp->used_count = urb->actual_length; if (sp->fail_count) { pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p transfer ok" - " - fail count reset",sp); + "stream %p transfer ok - fail count reset", + sp); sp->fail_count = 0; } } else if (sp->fail_count < sp->fail_tolerance) { @@ -464,8 +457,7 @@ static void buffer_complete(struct urb *urb) (sp->fail_count)++; (sp->buffers_failed)++; pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p ignoring error %d" - " - fail count increased to %u", + "stream %p ignoring error %d - fail count increased to %u", sp,urb->status,sp->fail_count); } else { (sp->buffers_failed)++; @@ -666,8 +658,7 @@ int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) bp->max_count = cnt; bp->stream->i_bcount += bp->max_count; pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferPool " - " %8s cap cap=%07d cnt=%02d", + "/*---TRACE_FLOW---*/ bufferPool %8s cap cap=%07d cnt=%02d", pvr2_buffer_state_decode( pvr2_buffer_state_idle), bp->stream->i_bcount,bp->stream->i_count); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c index 614d55767a4e..70b8a052eb5b 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c @@ -169,9 +169,7 @@ static int pvr2_ioread_start(struct pvr2_ioread *cp) stat = pvr2_buffer_queue(bp); if (stat < 0) { pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_start id=%p" - " error=%d", + "/*---TRACE_READ---*/ pvr2_ioread_start id=%p error=%d", cp,stat); pvr2_ioread_stop(cp); return stat; @@ -209,8 +207,8 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) do { if (cp->stream) { pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (tear-down) id=%p",cp); + "/*---TRACE_READ---*/ pvr2_ioread_setup (tear-down) id=%p", + cp); pvr2_ioread_stop(cp); pvr2_stream_kill(cp->stream); if (pvr2_stream_get_buffer_count(cp->stream)) { @@ -220,8 +218,8 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) } if (sp) { pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (setup) id=%p",cp); + "/*---TRACE_READ---*/ pvr2_ioread_setup (setup) id=%p", + cp); pvr2_stream_kill(sp); ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT); if (ret < 0) { @@ -270,9 +268,7 @@ static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) if (stat < 0) { // Streaming error... pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " queue_error=%d", + "/*---TRACE_READ---*/ pvr2_ioread_read id=%p queue_error=%d", cp,stat); pvr2_ioread_stop(cp); return 0; @@ -292,9 +288,7 @@ static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) if (stat < 0) { // Streaming error... pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " buffer_error=%d", + "/*---TRACE_READ---*/ pvr2_ioread_read id=%p buffer_error=%d", cp,stat); pvr2_ioread_stop(cp); // Give up. @@ -347,8 +341,7 @@ static void pvr2_ioread_filter(struct pvr2_ioread *cp) if (cp->sync_buf_offs >= cp->sync_key_len) { cp->sync_trashed_count -= cp->sync_key_len; pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 2 (skipped %u bytes)", + "/*---TRACE_READ---*/ sync_state <== 2 (skipped %u bytes)", cp->sync_trashed_count); cp->sync_state = 2; cp->sync_buf_offs = 0; @@ -358,8 +351,7 @@ static void pvr2_ioread_filter(struct pvr2_ioread *cp) if (cp->c_data_offs < cp->c_data_len) { // Sanity check - should NEVER get here pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ERROR: pvr2_ioread filter sync problem" - " len=%u offs=%u", + "ERROR: pvr2_ioread filter sync problem len=%u offs=%u", cp->c_data_len,cp->c_data_offs); // Get out so we don't get stuck in an infinite // loop. @@ -418,8 +410,8 @@ int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) if (!cnt) { pvr2_trace(PVR2_TRACE_TRAP, - "/*---TRACE_READ---*/ pvr2_ioread_read id=%p" - " ZERO Request? Returning zero.",cp); + "/*---TRACE_READ---*/ pvr2_ioread_read id=%p ZERO Request? Returning zero.", +cp); return 0; } @@ -477,8 +469,7 @@ int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) // Consumed entire key; switch mode // to normal. pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 0"); + "/*---TRACE_READ---*/ sync_state <== 0"); cp->sync_state = 0; } } else { @@ -502,8 +493,7 @@ int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) } pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ pvr2_ioread_read" - " id=%p request=%d result=%d", + "/*---TRACE_READ---*/ pvr2_ioread_read id=%p request=%d result=%d", cp,req_cnt,ret); return ret; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-std.c b/drivers/media/usb/pvrusb2/pvrusb2-std.c index 9a596a3a4c27..cd7bc18a1ba2 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-std.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-std.c @@ -357,8 +357,7 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " Failed to classify the following standard(s): %.*s", + "WARNING: Failed to classify the following standard(s): %.*s", bcnt,buf); } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 2cc4d2b6f810..bbbe18d5275a 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -949,8 +949,8 @@ static long pvr2_v4l2_ioctl(struct file *file, if (ret < 0) { if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%ld" - " command was:", ret); + "pvr2_v4l2_do_ioctl failure, ret=%ld command was:", +ret); v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); } } else { @@ -1254,8 +1254,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, nr_ptr = video_nr; if (!dip->stream) { pr_err(KBUILD_MODNAME - ": Failed to set up pvrusb2 v4l video dev" - " due to missing stream instance\n"); + ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n"); return; } break; @@ -1272,8 +1271,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, break; default: /* Bail out (this should be impossible) */ - pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev" - " due to unrecognized config\n"); + pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev due to unrecognized config\n"); return; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c index 105123ab36aa..6fee367139aa 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c @@ -91,9 +91,7 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) (hdw->input_val < 0) || (hdw->input_val >= sp->cnt)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", + "*** WARNING *** subdev v4l2 set_input: Invalid routing scheme (%u) and/or input (%d)", sid, hdw->input_val); return; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c index f1df94a2436f..7993983de5a6 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c @@ -49,8 +49,7 @@ void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) input = 2; break; } - pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775" - " set_input(val=%d route=0x%x)", + pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775 set_input(val=%d route=0x%x)", hdw->input_val, input); sd->ops->audio->s_routing(sd, input, 0, 0); -- cgit v1.2.3 From c91e42f5efea7f2828d6f24165ada97f65f9e7e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:18 -0200 Subject: [media] pwc: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pwc/pwc-if.c | 4 ++-- drivers/media/usb/pwc/pwc-v4l.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index ff657644b6b3..22420c14ac98 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c @@ -238,8 +238,8 @@ static void pwc_frame_complete(struct pwc_device *pdev) } else { /* Check for underflow first */ if (fbuf->filled < pdev->frame_total_size) { - PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" - " discarded.\n", fbuf->filled); + PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes); discarded.\n", + fbuf->filled); } else { fbuf->vb.field = V4L2_FIELD_NONE; fbuf->vb.sequence = pdev->vframe_count; diff --git a/drivers/media/usb/pwc/pwc-v4l.c b/drivers/media/usb/pwc/pwc-v4l.c index 3d987984602f..92f04db6bbae 100644 --- a/drivers/media/usb/pwc/pwc-v4l.c +++ b/drivers/media/usb/pwc/pwc-v4l.c @@ -406,8 +406,7 @@ static void pwc_vidioc_fill_fmt(struct v4l2_format *f, f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2; f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; - PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " - "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", + PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.bytesperline, @@ -473,8 +472,7 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) pixelformat = f->fmt.pix.pixelformat; - PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " - "format=%c%c%c%c\n", + PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d format=%c%c%c%c\n", f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, (pixelformat)&255, (pixelformat>>8)&255, -- cgit v1.2.3 From 67390d21fe8fefbf961395274f8d67a071306d9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:19 -0200 Subject: [media] siano: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/siano/smsusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index c2e25876e93b..a4dcaec31d02 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -604,8 +604,8 @@ static int smsusb_resume(struct usb_interface *intf) intf->cur_altsetting->desc. bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO "%s usb_set_interface failed, " - "rc %d\n", __func__, rc); + printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", + __func__, rc); return rc; } } -- cgit v1.2.3 From b4b3f99c8d77e2edd02fdfc791c194641f3e9fc3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:19 -0200 Subject: [media] stkwebcam: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-sensor.c | 4 ++-- drivers/media/usb/stkwebcam/stk-webcam.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c index e546b014d7ad..13ad8fdf05bb 100644 --- a/drivers/media/usb/stkwebcam/stk-sensor.c +++ b/drivers/media/usb/stkwebcam/stk-sensor.c @@ -391,8 +391,8 @@ int stk_sensor_init(struct stk_camera *dev) } stk_sensor_write_regvals(dev, ov_initvals); msleep(10); - STK_INFO("OmniVision sensor detected, id %02X%02X" - " at address %x\n", idh, idl, SENSOR_ADDRESS); + STK_INFO("OmniVision sensor detected, id %02X%02X at address %x\n", + idh, idl, SENSOR_ADDRESS); return 0; } diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 22a9aae16291..e2e7d0f7a43c 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -372,8 +372,7 @@ static void stk_isoc_handler(struct urb *urb) if (fb->v4lbuf.bytesused != 0 && fb->v4lbuf.bytesused != dev->frame_size) { (void) (printk_ratelimit() && - STK_ERROR("frame %d, " - "bytesused=%d, skipping\n", + STK_ERROR("frame %d, bytesused=%d, skipping\n", i, fb->v4lbuf.bytesused)); fb->v4lbuf.bytesused = 0; fill = fb->buffer; -- cgit v1.2.3 From 68616504573945c24fe8f21466967b0d8a5cabf0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:19 -0200 Subject: [media] tm6000: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tm6000/tm6000-alsa.c | 4 +--- drivers/media/usb/tm6000/tm6000-core.c | 14 ++++++-------- drivers/media/usb/tm6000/tm6000-dvb.c | 16 +++++----------- drivers/media/usb/tm6000/tm6000-i2c.c | 3 +-- drivers/media/usb/tm6000/tm6000-stds.c | 3 +-- drivers/media/usb/tm6000/tm6000-video.c | 18 ++++++++---------- 6 files changed, 22 insertions(+), 36 deletions(-) diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c index f16fbd1f9f51..422322541af6 100644 --- a/drivers/media/usb/tm6000/tm6000-alsa.c +++ b/drivers/media/usb/tm6000/tm6000-alsa.c @@ -58,9 +58,7 @@ MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s)."); MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards"); MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Trident,tm5600}," - "{{Trident,tm6000}," - "{{Trident,tm6010}"); +MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},{{Trident,tm6000},{{Trident,tm6010}"); static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); diff --git a/drivers/media/usb/tm6000/tm6000-core.c b/drivers/media/usb/tm6000/tm6000-core.c index 7c32353c59db..8d104e5c4be3 100644 --- a/drivers/media/usb/tm6000/tm6000-core.c +++ b/drivers/media/usb/tm6000/tm6000-core.c @@ -602,8 +602,8 @@ int tm6000_init(struct tm6000_core *dev) for (i = 0; i < size; i++) { rc = tm6000_set_reg(dev, tab[i].req, tab[i].reg, tab[i].val); if (rc < 0) { - printk(KERN_ERR "Error %i while setting req %d, " - "reg %d to value %d\n", rc, + printk(KERN_ERR "Error %i while setting req %d, reg %d to value %d\n", + rc, tab[i].req, tab[i].reg, tab[i].val); return rc; } @@ -761,9 +761,8 @@ int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute) if (dev->dev_type == TM6010) tm6010_set_mute_sif(dev, mute); else { - printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has" - " SIF audio inputs. Please check the %s" - " configuration.\n", dev->name); + printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has SIF audio inputs. Please check the %s configuration.\n", + dev->name); return -EINVAL; } break; @@ -822,9 +821,8 @@ void tm6000_set_volume(struct tm6000_core *dev, int vol) if (dev->dev_type == TM6010) tm6010_set_volume_sif(dev, vol); else - printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has" - " SIF audio inputs. Please check the %s" - " configuration.\n", dev->name); + printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has SIF audio inputs. Please check the %s configuration.\n", + dev->name); break; case TM6000_AMUX_ADC1: case TM6000_AMUX_ADC2: diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c index 0426b210383b..70dbaec1219e 100644 --- a/drivers/media/usb/tm6000/tm6000-dvb.c +++ b/drivers/media/usb/tm6000/tm6000-dvb.c @@ -35,9 +35,7 @@ MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV ca MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Trident, tm5600}," - "{{Trident, tm6000}," - "{{Trident, tm6010}"); +MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},{{Trident, tm6000},{{Trident, tm6010}"); static int debug; @@ -292,13 +290,11 @@ static int register_dvb(struct tm6000_core *dev) } if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { - printk(KERN_ERR "tm6000: couldn't register " - "frontend (xc3028)\n"); + printk(KERN_ERR "tm6000: couldn't register frontend (xc3028)\n"); ret = -EINVAL; goto frontend_err; } - printk(KERN_INFO "tm6000: XC2028/3028 asked to be " - "attached to frontend!\n"); + printk(KERN_INFO "tm6000: XC2028/3028 asked to be attached to frontend!\n"); break; } case TUNER_XC5000: { @@ -315,13 +311,11 @@ static int register_dvb(struct tm6000_core *dev) } if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { - printk(KERN_ERR "tm6000: couldn't register " - "frontend (xc5000)\n"); + printk(KERN_ERR "tm6000: couldn't register frontend (xc5000)\n"); ret = -EINVAL; goto frontend_err; } - printk(KERN_INFO "tm6000: XC5000 asked to be " - "attached to frontend!\n"); + printk(KERN_INFO "tm6000: XC5000 asked to be attached to frontend!\n"); break; } } diff --git a/drivers/media/usb/tm6000/tm6000-i2c.c b/drivers/media/usb/tm6000/tm6000-i2c.c index c7e23e3dd75e..b01d3ee56e77 100644 --- a/drivers/media/usb/tm6000/tm6000-i2c.c +++ b/drivers/media/usb/tm6000/tm6000-i2c.c @@ -173,8 +173,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, * immediately after a 1 or 2 byte write to select * a register. We cannot fulfil this request. */ - i2c_dprintk(2, " read without preceding write not" - " supported"); + i2c_dprintk(2, " read without preceding write not supported"); rc = -EOPNOTSUPP; goto err; } else if (i + 1 < num && msgs[i].len <= 2 && diff --git a/drivers/media/usb/tm6000/tm6000-stds.c b/drivers/media/usb/tm6000/tm6000-stds.c index 93a4b2434b6e..4064a5e8fae1 100644 --- a/drivers/media/usb/tm6000/tm6000-stds.c +++ b/drivers/media/usb/tm6000/tm6000-stds.c @@ -464,8 +464,7 @@ static int tm6000_load_std(struct tm6000_core *dev, struct tm6000_reg_settings * for (i = 0; set[i].req; i++) { rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value); if (rc < 0) { - printk(KERN_ERR "Error %i while setting " - "req %d, reg %d to value %d\n", + printk(KERN_ERR "Error %i while setting req %d, reg %d to value %d\n", rc, set[i].req, set[i].reg, set[i].value); return rc; } diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index dee7e7d3d47d..d9f3fa5db8dd 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -615,8 +615,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev) return -ENOMEM; } - dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets" - " (%d bytes) of %d bytes each to handle %u size\n", + dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets (%d bytes) of %d bytes each to handle %u size\n", max_packets, num_bufs, sb_size, dev->isoc_in.maxsize, size); @@ -939,8 +938,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, fmt = format_by_fourcc(f->fmt.pix.pixelformat); if (NULL == fmt) { - dprintk(dev, 2, "Fourcc format (0x%08x)" - " invalid.\n", f->fmt.pix.pixelformat); + dprintk(dev, 2, "Fourcc format (0x%08x) invalid.\n", + f->fmt.pix.pixelformat); return -EINVAL; } @@ -1366,14 +1365,13 @@ static int __tm6000_open(struct file *file) fh->width = dev->width; fh->height = dev->height; - dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, " - "dev->vidq=0x%08lx\n", + dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n", (unsigned long)fh, (unsigned long)dev, (unsigned long)&dev->vidq); - dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "queued=%d\n", list_empty(&dev->vidq.queued)); - dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "active=%d\n", list_empty(&dev->vidq.active)); + dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty queued=%d\n", + list_empty(&dev->vidq.queued)); + dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty active=%d\n", + list_empty(&dev->vidq.active)); /* initialize hardware on analog mode */ rc = tm6000_init_analog_mode(dev); -- cgit v1.2.3 From 80ebec68ec02a1d03e1dd64248978a91bc93f504 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:20 -0200 Subject: [media] ttusb-budget: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index d52d4a8d39ad..361e40b56045 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -767,8 +767,7 @@ static void ttusb_iso_irq(struct urb *urb) for (i = 0; i < urb->number_of_packets; ++i) { numpkt++; if (time_after_eq(jiffies, lastj + HZ)) { - dprintk("frames/s: %lu (ts: %d, stuff %d, " - "sec: %d, invalid: %d, all: %d)\n", + dprintk("frames/s: %lu (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", numpkt * HZ / (jiffies - lastj), numts, numstuff, numsec, numinvalid, numts + numstuff + numsec + numinvalid); -- cgit v1.2.3 From bf769a4e68d1d56674171ab601c23d2db46c6f7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:20 -0200 Subject: [media] ttusb-dec: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 35d5003ff809..559c823a4fe8 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -708,8 +708,8 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, dec->packet_payload_length = 2; dec->packet_state = 7; } else { - printk("%s: unknown packet type: " - "%02x%02x\n", __func__, + printk("%s: unknown packet type: %02x%02x\n", + __func__, dec->packet[0], dec->packet[1]); dec->packet_state = 0; } @@ -961,8 +961,8 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) for (i = 0; i < ISO_BUF_COUNT; i++) { if ((result = usb_submit_urb(dec->iso_urb[i], GFP_ATOMIC))) { - printk("%s: failed urb submission %d: " - "error %d\n", __func__, i, result); + printk("%s: failed urb submission %d: error %d\n", + __func__, i, result); while (i) { usb_kill_urb(dec->iso_urb[i - 1]); @@ -1375,8 +1375,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) memcpy(&tmp, &firmware[56], 4); crc32_check = ntohl(tmp); if (crc32_csum != crc32_check) { - printk("%s: crc32 check of DSP code failed (calculated " - "0x%08x != 0x%08x in file), file invalid.\n", + printk("%s: crc32 check of DSP code failed (calculated 0x%08x != 0x%08x in file), file invalid.\n", __func__, crc32_csum, crc32_check); release_firmware(fw_entry); return -ENOENT; @@ -1453,11 +1452,9 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) if (!mode) { if (version == 0xABCDEFAB) - printk(KERN_INFO "ttusb_dec: no version " - "info in Firmware\n"); + printk(KERN_INFO "ttusb_dec: no version info in Firmware\n"); else - printk(KERN_INFO "ttusb_dec: Firmware " - "%x.%02x%c%c\n", + printk(KERN_INFO "ttusb_dec: Firmware %x.%02x%c%c\n", version >> 24, (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); @@ -1481,8 +1478,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) ttusb_dec_set_model(dec, TTUSB_DEC2540T); break; default: - printk(KERN_ERR "%s: unknown model returned " - "by firmware (%08x) - please report\n", + printk(KERN_ERR "%s: unknown model returned by firmware (%08x) - please report\n", __func__, model); return -ENOENT; } -- cgit v1.2.3 From 02c539d3ea2f5eedf8e15750d924c2430c587111 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:21 -0200 Subject: [media] usbvision: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-core.c | 20 ++++++++++---------- drivers/media/usb/usbvision/usbvision-video.c | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c index c23bf73a68ea..bf041a9e69db 100644 --- a/drivers/media/usb/usbvision/usbvision-core.c +++ b/drivers/media/usb/usbvision/usbvision-core.c @@ -1656,8 +1656,8 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma (__u16) USBVISION_FILT_CONT, value, 2, HZ); if (rc < 0) { - printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - " - "reconnect or reload driver.\n", proc, rc); + printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - reconnect or reload driver.\n", + proc, rc); } usbvision->isoc_mode = format; return rc; @@ -1890,8 +1890,8 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision) (__u16) USBVISION_INTRA_CYC, value, 5, HZ); if (rc < 0) { - printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " - "reconnect or reload driver.\n", proc, rc); + printk(KERN_ERR "%sERROR=%d. USBVISION stopped - reconnect or reload driver.\n", + proc, rc); return rc; } @@ -1921,8 +1921,8 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision) (__u16) USBVISION_PCM_THR1, value, 6, HZ); if (rc < 0) { - printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " - "reconnect or reload driver.\n", proc, rc); + printk(KERN_ERR "%sERROR=%d. USBVISION stopped - reconnect or reload driver.\n", + proc, rc); } return rc; } @@ -1960,8 +1960,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision) rc = usbvision_write_reg(usbvision, USBVISION_VIN_REG1, value[0]); if (rc < 0) { - printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " - "reconnect or reload driver.\n", proc, rc); + printk(KERN_ERR "%sERROR=%d. USBVISION stopped - reconnect or reload driver.\n", + proc, rc); return rc; } @@ -2026,8 +2026,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0, (__u16) USBVISION_LXSIZE_I, value, 8, HZ); if (rc < 0) { - printk(KERN_ERR "%sERROR=%d. USBVISION stopped - " - "reconnect or reload driver.\n", proc, rc); + printk(KERN_ERR "%sERROR=%d. USBVISION stopped - reconnect or reload driver.\n", + proc, rc); return rc; } diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index c8b4eb2ee7a2..a7529196c327 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1456,8 +1456,8 @@ static int usbvision_probe(struct usb_interface *intf, } if (interface->desc.bNumEndpoints < 2) { - dev_err(&intf->dev, "interface %d has %d endpoints, but must" - " have minimum 2\n", ifnum, interface->desc.bNumEndpoints); + dev_err(&intf->dev, "interface %d has %d endpoints, but must have minimum 2\n", + ifnum, interface->desc.bNumEndpoints); ret = -ENODEV; goto err_usb; } -- cgit v1.2.3 From 3a611875d9719610668d99b9e79c716fd4488cd1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:22 -0200 Subject: [media] zr364xx: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/zr364xx/zr364xx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index cc128db85723..3950708cbb32 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -633,8 +633,7 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam, } else { if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) { dev_info(&cam->udev->dev, - "%s: buffer (%d bytes) too small to hold " - "frame data. Discarding frame data.\n", + "%s: buffer (%d bytes) too small to hold frame data. Discarding frame data.\n", __func__, MAX_FRAME_SIZE); } else { pdest += frm->cur_size; @@ -1373,8 +1372,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) &cam->buffer.frame[i], i, cam->buffer.frame[i].lpvbits); if (cam->buffer.frame[i].lpvbits == NULL) { - printk(KERN_INFO KBUILD_MODNAME ": out of memory. " - "Using less frames\n"); + printk(KERN_INFO KBUILD_MODNAME ": out of memory. Using less frames\n"); break; } } -- cgit v1.2.3 From 8720427c198b6d36be26d5cd45a487bf7bb49478 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:22 -0200 Subject: [media] v4l2-core: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 91 +++++++++-------------------- drivers/media/v4l2-core/videobuf-core.c | 3 +- drivers/media/v4l2-core/videobuf2-core.c | 25 ++++---- drivers/media/v4l2-core/videobuf2-v4l2.c | 10 ++-- drivers/media/v4l2-core/videobuf2-vmalloc.c | 3 +- 5 files changed, 43 insertions(+), 89 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index c52d94c018bb..26fe7aef1196 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -174,8 +174,7 @@ static void v4l_print_querycap(const void *arg, bool write_only) { const struct v4l2_capability *p = arg; - pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, " - "capabilities=0x%08x, device_caps=0x%08x\n", + pr_cont("driver=%.*s, card=%.*s, bus=%.*s, version=0x%08x, capabilities=0x%08x, device_caps=0x%08x\n", (int)sizeof(p->driver), p->driver, (int)sizeof(p->card), p->card, (int)sizeof(p->bus_info), p->bus_info, @@ -186,8 +185,7 @@ static void v4l_print_enuminput(const void *arg, bool write_only) { const struct v4l2_input *p = arg; - pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, " - "std=0x%08Lx, status=0x%x, capabilities=0x%x\n", + pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, tuner=%u, std=0x%08Lx, status=0x%x, capabilities=0x%x\n", p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, p->tuner, (unsigned long long)p->std, p->status, p->capabilities); @@ -197,8 +195,7 @@ static void v4l_print_enumoutput(const void *arg, bool write_only) { const struct v4l2_output *p = arg; - pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, " - "modulator=%u, std=0x%08Lx, capabilities=0x%x\n", + pr_cont("index=%u, name=%.*s, type=%u, audioset=0x%x, modulator=%u, std=0x%08Lx, capabilities=0x%x\n", p->index, (int)sizeof(p->name), p->name, p->type, p->audioset, p->modulator, (unsigned long long)p->std, p->capabilities); } @@ -256,11 +253,7 @@ static void v4l_print_format(const void *arg, bool write_only) case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: pix = &p->fmt.pix; - pr_cont(", width=%u, height=%u, " - "pixelformat=%c%c%c%c, field=%s, " - "bytesperline=%u, sizeimage=%u, colorspace=%d, " - "flags=0x%x, ycbcr_enc=%u, quantization=%u, " - "xfer_func=%u\n", + pr_cont(", width=%u, height=%u, pixelformat=%c%c%c%c, field=%s, bytesperline=%u, sizeimage=%u, colorspace=%d, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", pix->width, pix->height, (pix->pixelformat & 0xff), (pix->pixelformat >> 8) & 0xff, @@ -274,10 +267,7 @@ static void v4l_print_format(const void *arg, bool write_only) case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: mp = &p->fmt.pix_mp; - pr_cont(", width=%u, height=%u, " - "format=%c%c%c%c, field=%s, " - "colorspace=%d, num_planes=%u, flags=0x%x, " - "ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", + pr_cont(", width=%u, height=%u, format=%c%c%c%c, field=%s, colorspace=%d, num_planes=%u, flags=0x%x, ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", mp->width, mp->height, (mp->pixelformat & 0xff), (mp->pixelformat >> 8) & 0xff, @@ -306,8 +296,7 @@ static void v4l_print_format(const void *arg, bool write_only) case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_OUTPUT: vbi = &p->fmt.vbi; - pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, " - "sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n", + pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n", vbi->sampling_rate, vbi->offset, vbi->samples_per_line, (vbi->sample_format & 0xff), @@ -343,9 +332,7 @@ static void v4l_print_framebuffer(const void *arg, bool write_only) { const struct v4l2_framebuffer *p = arg; - pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, " - "height=%u, pixelformat=%c%c%c%c, " - "bytesperline=%u, sizeimage=%u, colorspace=%d\n", + pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, height=%u, pixelformat=%c%c%c%c, bytesperline=%u, sizeimage=%u, colorspace=%d\n", p->capability, p->flags, p->base, p->fmt.width, p->fmt.height, (p->fmt.pixelformat & 0xff), @@ -368,8 +355,7 @@ static void v4l_print_modulator(const void *arg, bool write_only) if (write_only) pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); else - pr_cont("index=%u, name=%.*s, capability=0x%x, " - "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", + pr_cont("index=%u, name=%.*s, capability=0x%x, rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", p->index, (int)sizeof(p->name), p->name, p->capability, p->rangelow, p->rangehigh, p->txsubchans); } @@ -381,9 +367,7 @@ static void v4l_print_tuner(const void *arg, bool write_only) if (write_only) pr_cont("index=%u, audmode=%u\n", p->index, p->audmode); else - pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, " - "rangelow=%u, rangehigh=%u, signal=%u, afc=%d, " - "rxsubchans=0x%x, audmode=%u\n", + pr_cont("index=%u, name=%.*s, type=%u, capability=0x%x, rangelow=%u, rangehigh=%u, signal=%u, afc=%d, rxsubchans=0x%x, audmode=%u\n", p->index, (int)sizeof(p->name), p->name, p->type, p->capability, p->rangelow, p->rangehigh, p->signal, p->afc, @@ -402,8 +386,8 @@ static void v4l_print_standard(const void *arg, bool write_only) { const struct v4l2_standard *p = arg; - pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, " - "framelines=%u\n", p->index, + pr_cont("index=%u, id=0x%Lx, name=%.*s, fps=%u/%u, framelines=%u\n", + p->index, (unsigned long long)p->id, (int)sizeof(p->name), p->name, p->frameperiod.numerator, p->frameperiod.denominator, @@ -419,8 +403,7 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only) { const struct v4l2_hw_freq_seek *p = arg; - pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, " - "rangelow=%u, rangehigh=%u\n", + pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, rangelow=%u, rangehigh=%u\n", p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, p->rangelow, p->rangehigh); } @@ -442,8 +425,7 @@ static void v4l_print_buffer(const void *arg, bool write_only) const struct v4l2_plane *plane; int i; - pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, " - "flags=0x%08x, field=%s, sequence=%d, memory=%s", + pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, field=%s, sequence=%d, memory=%s", p->timestamp.tv_sec / 3600, (int)(p->timestamp.tv_sec / 60) % 60, (int)(p->timestamp.tv_sec % 60), @@ -458,8 +440,7 @@ static void v4l_print_buffer(const void *arg, bool write_only) for (i = 0; i < p->length; ++i) { plane = &p->m.planes[i]; printk(KERN_DEBUG - "plane %d: bytesused=%d, data_offset=0x%08x, " - "offset/userptr=0x%lx, length=%d\n", + "plane %d: bytesused=%d, data_offset=0x%08x, offset/userptr=0x%lx, length=%d\n", i, plane->bytesused, plane->data_offset, plane->m.userptr, plane->length); } @@ -468,8 +449,7 @@ static void v4l_print_buffer(const void *arg, bool write_only) p->bytesused, p->m.userptr, p->length); } - printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, " - "flags=0x%08x, frames=%d, userbits=0x%08x\n", + printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, flags=0x%08x, frames=%d, userbits=0x%08x\n", tc->hours, tc->minutes, tc->seconds, tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); } @@ -503,8 +483,7 @@ static void v4l_print_streamparm(const void *arg, bool write_only) p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { const struct v4l2_captureparm *c = &p->parm.capture; - pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, " - "extendedmode=%d, readbuffers=%d\n", + pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, extendedmode=%d, readbuffers=%d\n", c->capability, c->capturemode, c->timeperframe.numerator, c->timeperframe.denominator, c->extendedmode, c->readbuffers); @@ -512,8 +491,7 @@ static void v4l_print_streamparm(const void *arg, bool write_only) p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { const struct v4l2_outputparm *c = &p->parm.output; - pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, " - "extendedmode=%d, writebuffers=%d\n", + pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, extendedmode=%d, writebuffers=%d\n", c->capability, c->outputmode, c->timeperframe.numerator, c->timeperframe.denominator, c->extendedmode, c->writebuffers); @@ -526,8 +504,7 @@ static void v4l_print_queryctrl(const void *arg, bool write_only) { const struct v4l2_queryctrl *p = arg; - pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, " - "step=%d, default=%d, flags=0x%08x\n", + pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%d/%d, step=%d, default=%d, flags=0x%08x\n", p->id, p->type, (int)sizeof(p->name), p->name, p->minimum, p->maximum, p->step, p->default_value, p->flags); @@ -537,9 +514,7 @@ static void v4l_print_query_ext_ctrl(const void *arg, bool write_only) { const struct v4l2_query_ext_ctrl *p = arg; - pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, " - "step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, " - "nr_of_dims=%u, dims=%u,%u,%u,%u\n", + pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, nr_of_dims=%u, dims=%u,%u,%u,%u\n", p->id, p->type, (int)sizeof(p->name), p->name, p->minimum, p->maximum, p->step, p->default_value, p->flags, @@ -583,9 +558,7 @@ static void v4l_print_cropcap(const void *arg, bool write_only) { const struct v4l2_cropcap *p = arg; - pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, " - "defrect wxh=%dx%d, x,y=%d,%d, " - "pixelaspect %d/%d\n", + pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, defrect wxh=%dx%d, x,y=%d,%d, pixelaspect %d/%d\n", prt_names(p->type, v4l2_type_names), p->bounds.width, p->bounds.height, p->bounds.left, p->bounds.top, @@ -618,8 +591,7 @@ static void v4l_print_jpegcompression(const void *arg, bool write_only) { const struct v4l2_jpegcompression *p = arg; - pr_cont("quality=%d, APPn=%d, APP_len=%d, " - "COM_len=%d, jpeg_markers=0x%x\n", + pr_cont("quality=%d, APPn=%d, APP_len=%d, COM_len=%d, jpeg_markers=0x%x\n", p->quality, p->APPn, p->APP_len, p->COM_len, p->jpeg_markers); } @@ -686,14 +658,7 @@ static void v4l_print_dv_timings(const void *arg, bool write_only) switch (p->type) { case V4L2_DV_BT_656_1120: - pr_cont("type=bt-656/1120, interlaced=%u, " - "pixelclock=%llu, " - "width=%u, height=%u, polarities=0x%x, " - "hfrontporch=%u, hsync=%u, " - "hbackporch=%u, vfrontporch=%u, " - "vsync=%u, vbackporch=%u, " - "il_vfrontporch=%u, il_vsync=%u, " - "il_vbackporch=%u, standards=0x%x, flags=0x%x\n", + pr_cont("type=bt-656/1120, interlaced=%u, pixelclock=%llu, width=%u, height=%u, polarities=0x%x, hfrontporch=%u, hsync=%u, hbackporch=%u, vfrontporch=%u, vsync=%u, vbackporch=%u, il_vfrontporch=%u, il_vsync=%u, il_vbackporch=%u, standards=0x%x, flags=0x%x\n", p->bt.interlaced, p->bt.pixelclock, p->bt.width, p->bt.height, p->bt.polarities, p->bt.hfrontporch, @@ -723,8 +688,7 @@ static void v4l_print_dv_timings_cap(const void *arg, bool write_only) switch (p->type) { case V4L2_DV_BT_656_1120: - pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, " - "pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", + pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", p->bt.min_width, p->bt.max_width, p->bt.min_height, p->bt.max_height, p->bt.min_pixelclock, p->bt.max_pixelclock, @@ -805,8 +769,7 @@ static void v4l_print_event(const void *arg, bool write_only) const struct v4l2_event *p = arg; const struct v4l2_event_ctrl *c; - pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, " - "timestamp=%lu.%9.9lu\n", + pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n", p->type, p->pending, p->sequence, p->id, p->timestamp.tv_sec, p->timestamp.tv_nsec); switch (p->type) { @@ -822,8 +785,7 @@ static void v4l_print_event(const void *arg, bool write_only) pr_cont("value64=%lld, ", c->value64); else pr_cont("value=%d, ", c->value); - pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, " - "default_value=%d\n", + pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, default_value=%d\n", c->flags, c->minimum, c->maximum, c->step, c->default_value); break; @@ -859,8 +821,7 @@ static void v4l_print_freq_band(const void *arg, bool write_only) { const struct v4l2_frequency_band *p = arg; - pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, " - "rangelow=%u, rangehigh=%u, modulation=0x%x\n", + pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, rangelow=%u, rangehigh=%u, modulation=0x%x\n", p->tuner, p->type, p->index, p->capability, p->rangelow, p->rangehigh, p->modulation); diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c index def84753c4c3..1dbf6f7785bb 100644 --- a/drivers/media/v4l2-core/videobuf-core.c +++ b/drivers/media/v4l2-core/videobuf-core.c @@ -572,8 +572,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) switch (b->memory) { case V4L2_MEMORY_MMAP: if (0 == buf->baddr) { - dprintk(1, "qbuf: mmap requested " - "but buffer addr is zero!\n"); + dprintk(1, "qbuf: mmap requested but buffer addr is zero!\n"); goto done; } if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 21900202ff83..7c1d390ea438 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -358,8 +358,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, if (memory == VB2_MEMORY_MMAP) { ret = __vb2_buf_mem_alloc(vb); if (ret) { - dprintk(1, "failed allocating memory for " - "buffer %d\n", buffer); + dprintk(1, "failed allocating memory for buffer %d\n", + buffer); q->bufs[vb->index] = NULL; kfree(vb); break; @@ -372,8 +372,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, */ ret = call_vb_qop(vb, buf_init, vb); if (ret) { - dprintk(1, "buffer %d %p initialization" - " failed\n", buffer, vb); + dprintk(1, "buffer %d %p initialization failed\n", + buffer, vb); __vb2_buf_mem_free(vb); q->bufs[vb->index] = NULL; kfree(vb); @@ -997,13 +997,12 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb) && vb->planes[plane].length == planes[plane].length) continue; - dprintk(3, "userspace address for plane %d changed, " - "reacquiring memory\n", plane); + dprintk(3, "userspace address for plane %d changed, reacquiring memory\n", + plane); /* Check if the provided plane buffer is large enough */ if (planes[plane].length < vb->planes[plane].min_length) { - dprintk(1, "provided buffer size %u is less than " - "setup size %u for plane %d\n", + dprintk(1, "provided buffer size %u is less than setup size %u for plane %d\n", planes[plane].length, vb->planes[plane].min_length, plane); @@ -1032,8 +1031,8 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb) planes[plane].m.userptr, planes[plane].length, dma_dir); if (IS_ERR(mem_priv)) { - dprintk(1, "failed acquiring userspace " - "memory for plane %d\n", plane); + dprintk(1, "failed acquiring userspace memory for plane %d\n", + plane); ret = PTR_ERR(mem_priv); goto err; } @@ -1123,8 +1122,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb) planes[plane].length = dbuf->size; if (planes[plane].length < vb->planes[plane].min_length) { - dprintk(1, "invalid dmabuf length %u for plane %d, " - "minimum length %u\n", + dprintk(1, "invalid dmabuf length %u for plane %d, minimum length %u\n", planes[plane].length, plane, vb->planes[plane].min_length); dma_buf_put(dbuf); @@ -1472,8 +1470,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) } if (nonblocking) { - dprintk(1, "nonblocking and no buffers to dequeue, " - "will not wait\n"); + dprintk(1, "nonblocking and no buffers to dequeue, will not wait\n"); return -EAGAIN; } diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index 52ef8833f6b6..3529849d2218 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c @@ -60,14 +60,13 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer /* Is memory for copying plane information present? */ if (b->m.planes == NULL) { - dprintk(1, "multi-planar buffer passed but " - "planes array not provided\n"); + dprintk(1, "multi-planar buffer passed but planes array not provided\n"); return -EINVAL; } if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) { - dprintk(1, "incorrect planes array length, " - "expected %d, got %d\n", vb->num_planes, b->length); + dprintk(1, "incorrect planes array length, expected %d, got %d\n", + vb->num_planes, b->length); return -EINVAL; } @@ -316,8 +315,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, * that just says that it is either a top or a bottom field, * but not which of the two it is. */ - dprintk(1, "the field is incorrectly set to ALTERNATE " - "for an output buffer\n"); + dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n"); return -EINVAL; } vb->timestamp = 0; diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index ab3227b75c84..3f778147cdef 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -151,8 +151,7 @@ static void *vb2_vmalloc_vaddr(void *buf_priv) struct vb2_vmalloc_buf *buf = buf_priv; if (!buf->vaddr) { - pr_err("Address of an unallocated plane requested " - "or cannot map user pointer\n"); + pr_err("Address of an unallocated plane requested or cannot map user pointer\n"); return NULL; } -- cgit v1.2.3 From 4bd69e7b9c1b8c1a5b6cfc50a126ae0a1d926e57 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:22 -0200 Subject: [media] dvb-frontends: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/au8522_common.c | 4 ++-- drivers/media/dvb-frontends/cx24110.c | 4 ++-- drivers/media/dvb-frontends/cx24113.c | 4 ++-- drivers/media/dvb-frontends/cx24116.c | 8 ++++---- drivers/media/dvb-frontends/cx24117.c | 4 ++-- drivers/media/dvb-frontends/cx24123.c | 4 ++-- drivers/media/dvb-frontends/ds3000.c | 15 +++++++-------- drivers/media/dvb-frontends/lgdt330x.c | 3 +-- drivers/media/dvb-frontends/m88rs2000.c | 11 +++++------ drivers/media/dvb-frontends/mt312.c | 7 +++---- drivers/media/dvb-frontends/nxt200x.c | 11 +++++------ drivers/media/dvb-frontends/or51132.c | 6 ++---- drivers/media/dvb-frontends/or51211.c | 3 +-- drivers/media/dvb-frontends/s5h1409.c | 4 ++-- drivers/media/dvb-frontends/s5h1411.c | 4 ++-- drivers/media/dvb-frontends/s5h1432.c | 4 ++-- drivers/media/dvb-frontends/s921.c | 4 ++-- drivers/media/dvb-frontends/si21xx.c | 8 ++++---- drivers/media/dvb-frontends/sp887x.c | 3 +-- drivers/media/dvb-frontends/stv0288.c | 11 +++++------ drivers/media/dvb-frontends/stv0297.c | 4 ++-- drivers/media/dvb-frontends/stv0299.c | 7 +++---- drivers/media/dvb-frontends/stv0900_sw.c | 3 +-- drivers/media/dvb-frontends/tda10021.c | 3 +-- drivers/media/dvb-frontends/tda10023.c | 6 ++---- drivers/media/dvb-frontends/tda10048.c | 12 ++++-------- drivers/media/dvb-frontends/ves1820.c | 8 ++++---- drivers/media/dvb-frontends/zl10036.c | 4 ++-- drivers/media/dvb-frontends/zl10039.c | 3 +-- 29 files changed, 76 insertions(+), 96 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c index f135126bc373..cf4ac240a01f 100644 --- a/drivers/media/dvb-frontends/au8522_common.c +++ b/drivers/media/dvb-frontends/au8522_common.c @@ -50,8 +50,8 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); + printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 6cb81ec12847..92a08c7bf794 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c @@ -120,8 +120,8 @@ static int cx24110_writereg (struct cx24110_state* state, int reg, int data) int err; if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); + dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", + __func__, err, reg, data); return -EREMOTEIO; } diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c index 3883c3b31aef..3812ef8cac08 100644 --- a/drivers/media/dvb-frontends/cx24113.c +++ b/drivers/media/dvb-frontends/cx24113.c @@ -108,8 +108,8 @@ static int cx24113_writereg(struct cx24113_state *state, int reg, int data) .flags = 0, .buf = buf, .len = 2 }; int err = i2c_transfer(state->i2c, &msg, 1); if (err != 1) { - printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); + printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x, data == 0x%02x)\n", + __func__, err, reg, data); return err; } diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index 8814f36d53fb..ae5a7f9f5a72 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -209,8 +209,8 @@ static int cx24116_writereg(struct cx24116_state *state, int reg, int data) err = i2c_transfer(state->i2c, &msg, 1); if (err != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," - " value == 0x%02x)\n", __func__, err, reg, data); + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n", + __func__, err, reg, data); return -EREMOTEIO; } @@ -498,8 +498,8 @@ static int cx24116_firmware_ondemand(struct dvb_frontend *fe) printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { - printk(KERN_ERR "%s: No firmware uploaded " - "(timeout or file not found?)\n", __func__); + printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", + __func__); return ret; } diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index a3f7eb4e609d..bc3cd698303f 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c @@ -474,8 +474,8 @@ static int cx24117_firmware_ondemand(struct dvb_frontend *fe) "%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { dev_err(&state->priv->i2c->dev, - "%s: No firmware uploaded " - "(timeout or file not found?)\n", __func__); + "%s: No firmware uploaded (timeout or file not found?)\n", +__func__); return ret; } diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index 113b0949408a..b1287de98e86 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -255,8 +255,8 @@ static int cx24123_i2c_writereg(struct cx24123_state *state, err = i2c_transfer(state->i2c, &msg, 1); if (err != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); + printk("%s: writereg error(err == %i, reg == 0x%02x, data == 0x%02x)\n", + __func__, err, reg, data); return err; } diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c index 447b518e287a..6dc79d4528c2 100644 --- a/drivers/media/dvb-frontends/ds3000.c +++ b/drivers/media/dvb-frontends/ds3000.c @@ -248,8 +248,8 @@ static int ds3000_writereg(struct ds3000_state *state, int reg, int data) err = i2c_transfer(state->i2c, &msg, 1); if (err != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," - " value == 0x%02x)\n", __func__, err, reg, data); + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n", + __func__, err, reg, data); return -EREMOTEIO; } @@ -296,8 +296,8 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) { - printk(KERN_ERR "%s: write error(err == %i, " - "reg == 0x%02x\n", __func__, ret, reg); + printk(KERN_ERR "%s: write error(err == %i, reg == 0x%02x\n", + __func__, ret, reg); ret = -EREMOTEIO; goto error; } @@ -364,8 +364,8 @@ static int ds3000_firmware_ondemand(struct dvb_frontend *fe) state->i2c->dev.parent); printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { - printk(KERN_ERR "%s: No firmware uploaded (timeout or file not " - "found?)\n", __func__); + printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", + __func__); return ret; } @@ -1144,8 +1144,7 @@ static struct dvb_frontend_ops ds3000_ops = { module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); -MODULE_DESCRIPTION("DVB Frontend module for Montage Technology " - "DS3000 hardware"); +MODULE_DESCRIPTION("DVB Frontend module for Montage Technology DS3000 hardware"); MODULE_AUTHOR("Konstantin Dimitrov "); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE); diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c index 96bf254da21e..8cb6c56d220a 100644 --- a/drivers/media/dvb-frontends/lgdt330x.c +++ b/drivers/media/dvb-frontends/lgdt330x.c @@ -405,8 +405,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend *fe) return -1; } if (err < 0) - printk(KERN_WARNING "lgdt330x: %s: error blasting " - "bytes to lgdt3303 for modulation type(%d)\n", + printk(KERN_WARNING "lgdt330x: %s: error blasting bytes to lgdt3303 for modulation type(%d)\n", __func__, p->modulation); /* diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index ef79a4ec31e2..3669c906ba01 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -75,8 +75,8 @@ static int m88rs2000_writereg(struct m88rs2000_state *state, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); + deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -618,10 +618,9 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe) state->no_lock_count = 0; if (c->delivery_system != SYS_DVBS) { - deb_info("%s: unsupported delivery " - "system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; + deb_info("%s: unsupported delivery system selected (%d)\n", + __func__, c->delivery_system); + return -EOPNOTSUPP; } /* Set Tuner */ diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c index fc08429c99b7..fdee75b1b99a 100644 --- a/drivers/media/dvb-frontends/mt312.c +++ b/drivers/media/dvb-frontends/mt312.c @@ -457,8 +457,8 @@ static int mt312_read_status(struct dvb_frontend *fe, enum fe_status *s) if (ret < 0) return ret; - dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x," - " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]); + dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", + status[0], status[1], status[2]); if (status[0] & 0xc0) *s |= FE_HAS_SIGNAL; /* signal noise ratio */ @@ -827,8 +827,7 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config, state->freq_mult = 9; break; default: - printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313" - " are supported chips.\n"); + printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313 are supported chips.\n"); goto error; } diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 79c3040912ab..7c23f0499f23 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c @@ -289,8 +289,7 @@ static void nxt200x_microcontroller_stop (struct nxt200x_state* state) counter++; } - pr_warn("Timeout waiting for nxt200x to stop. This is ok after " - "firmware upload.\n"); + pr_warn("Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n"); return; } @@ -893,8 +892,8 @@ static int nxt2002_init(struct dvb_frontend* fe) state->i2c->dev.parent); pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { - pr_err("%s: No firmware uploaded (timeout or file not found?)" - "\n", __func__); + pr_err("%s: No firmware uploaded (timeout or file not found?)\n", + __func__); return ret; } @@ -960,8 +959,8 @@ static int nxt2004_init(struct dvb_frontend* fe) state->i2c->dev.parent); pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { - pr_err("%s: No firmware uploaded (timeout or file not found?)" - "\n", __func__); + pr_err("%s: No firmware uploaded (timeout or file not found?)\n", + __func__); return ret; } diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c index a165af990672..bacea20822ea 100644 --- a/drivers/media/dvb-frontends/or51132.c +++ b/drivers/media/dvb-frontends/or51132.c @@ -342,15 +342,13 @@ static int or51132_set_parameters(struct dvb_frontend *fe) fwname); ret = request_firmware(&fw, fwname, state->i2c->dev.parent); if (ret) { - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); + printk(KERN_WARNING "or51132: No firmware uploaded(timeout or file not found?)\n"); return ret; } ret = or51132_load_firmware(fe, fw); release_firmware(fw); if (ret) { - printk(KERN_WARNING "or51132: Writing firmware to " - "device failed!\n"); + printk(KERN_WARNING "or51132: Writing firmware to device failed!\n"); return ret; } printk("or51132: Firmware upload complete.\n"); diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c index e82413b975e6..839479eab3b3 100644 --- a/drivers/media/dvb-frontends/or51211.c +++ b/drivers/media/dvb-frontends/or51211.c @@ -377,8 +377,7 @@ static int or51211_init(struct dvb_frontend* fe) OR51211_DEFAULT_FIRMWARE); pr_info("Got Hotplug firmware\n"); if (ret) { - pr_warn("No firmware uploaded " - "(timeout or file not found?)\n"); + pr_warn("No firmware uploaded (timeout or file not found?)\n"); return ret; } diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c index c68965ad97c0..56c3fb442d6c 100644 --- a/drivers/media/dvb-frontends/s5h1409.c +++ b/drivers/media/dvb-frontends/s5h1409.c @@ -321,8 +321,8 @@ static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); + printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c index 90f86e82b087..a861854981b7 100644 --- a/drivers/media/dvb-frontends/s5h1411.c +++ b/drivers/media/dvb-frontends/s5h1411.c @@ -350,8 +350,8 @@ static int s5h1411_writereg(struct s5h1411_state *state, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " - "ret == %i)\n", __func__, addr, reg, data, ret); + printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, ret == %i)\n", + __func__, addr, reg, data, ret); return (ret != 1) ? -1 : 0; } diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c index 4215652f8eb7..5de79739cf63 100644 --- a/drivers/media/dvb-frontends/s5h1432.c +++ b/drivers/media/dvb-frontends/s5h1432.c @@ -63,8 +63,8 @@ static int s5h1432_writereg(struct s5h1432_state *state, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " - "ret == %i)\n", __func__, addr, reg, data, ret); + printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, ret == %i)\n", + __func__, addr, reg, data, ret); return (ret != 1) ? -1 : 0; } diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c index b5e3d90eba5e..98cceb149b91 100644 --- a/drivers/media/dvb-frontends/s921.c +++ b/drivers/media/dvb-frontends/s921.c @@ -214,8 +214,8 @@ static int s921_i2c_writereg(struct s921_state *state, rc = i2c_transfer(state->i2c, &msg, 1); if (rc != 1) { - printk("%s: writereg rcor(rc == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, rc, reg, data); + printk("%s: writereg rcor(rc == %i, reg == 0x%02x, data == 0x%02x)\n", + __func__, rc, reg, data); return rc; } diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c index 62ad7a7be9f8..32ebfb78bfdd 100644 --- a/drivers/media/dvb-frontends/si21xx.c +++ b/drivers/media/dvb-frontends/si21xx.c @@ -245,8 +245,8 @@ static int si21_writeregs(struct si21xx_state *state, u8 reg1, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg1, data[0], ret); + dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n", + __func__, reg1, data[0], ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -265,8 +265,8 @@ static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); + dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c index 4378fe1b978e..f9194b7b7fec 100644 --- a/drivers/media/dvb-frontends/sp887x.c +++ b/drivers/media/dvb-frontends/sp887x.c @@ -63,8 +63,7 @@ static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data) if (!(reg == 0xf1a && data == 0x000 && (ret == -EREMOTEIO || ret == -EFAULT))) { - printk("%s: writereg error " - "(reg %03x, data %03x, ret == %i)\n", + printk("%s: writereg error (reg %03x, data %03x, ret == %i)\n", __func__, reg & 0xffff, data & 0xffff, ret); return ret; } diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index c93d9a45f7f7..12f6a4205e3e 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -74,8 +74,8 @@ static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); + dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -465,10 +465,9 @@ static int stv0288_set_frontend(struct dvb_frontend *fe) dprintk("%s : FE_SET_FRONTEND\n", __func__); if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery " - "system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; + dprintk("%s: unsupported delivery system selected (%d)\n", + __func__, c->delivery_system); + return -EOPNOTSUPP; } if (state->config->set_ts_params) diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c index 81b27b7c0c96..73b4d4243b74 100644 --- a/drivers/media/dvb-frontends/stv0297.c +++ b/drivers/media/dvb-frontends/stv0297.c @@ -57,8 +57,8 @@ static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); + dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c index 7927fa925f2f..a9b28ceb80d8 100644 --- a/drivers/media/dvb-frontends/stv0299.c +++ b/drivers/media/dvb-frontends/stv0299.c @@ -88,8 +88,8 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) ret = i2c_transfer (state->i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); + dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -761,8 +761,7 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " - "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); +MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(stv0299_attach); diff --git a/drivers/media/dvb-frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c index fa63a9e929ce..bded82774f4b 100644 --- a/drivers/media/dvb-frontends/stv0900_sw.c +++ b/drivers/media/dvb-frontends/stv0900_sw.c @@ -1485,8 +1485,7 @@ static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) current_step++; direction *= -1; - dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started." - " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", + dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt); if ((timingcpt >= 5) && diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c index 806c56691ca5..4c514e6bffda 100644 --- a/drivers/media/dvb-frontends/tda10021.c +++ b/drivers/media/dvb-frontends/tda10021.c @@ -77,8 +77,7 @@ static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) ret = i2c_transfer (state->i2c, &msg, 1); if (ret != 1) - printk("DVB: TDA10021(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", + printk("DVB: TDA10021(%d): %s, writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", state->frontend.dvb->num, __func__, reg, data, ret); msleep(10); diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index 3b8c7e499d0d..0c416be76d65 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -72,8 +72,7 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) ret = i2c_transfer (state->i2c, msg, 2); if (ret != 2) { int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error " - "(reg == 0x%02x, ret == %i)\n", + printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error (reg == 0x%02x, ret == %i)\n", num, __func__, reg, ret); } return b1[0]; @@ -88,8 +87,7 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) ret = i2c_transfer (state->i2c, &msg, 1); if (ret != 1) { int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", + printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", num, __func__, reg, data, ret); } return (ret != 1) ? -EREMOTEIO : 0; diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c index c2bf89d0b0b0..7cb23f89a03b 100644 --- a/drivers/media/dvb-frontends/tda10048.c +++ b/drivers/media/dvb-frontends/tda10048.c @@ -1063,32 +1063,28 @@ static void tda10048_establish_defaults(struct dvb_frontend *fe) /* Validate/default the config */ if (config->dtv6_if_freq_khz == 0) { config->dtv6_if_freq_khz = TDA10048_IF_4300; - printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz " - "is not set (defaulting to %d)\n", + printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz is not set (defaulting to %d)\n", __func__, config->dtv6_if_freq_khz); } if (config->dtv7_if_freq_khz == 0) { config->dtv7_if_freq_khz = TDA10048_IF_4300; - printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz " - "is not set (defaulting to %d)\n", + printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz is not set (defaulting to %d)\n", __func__, config->dtv7_if_freq_khz); } if (config->dtv8_if_freq_khz == 0) { config->dtv8_if_freq_khz = TDA10048_IF_4300; - printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz " - "is not set (defaulting to %d)\n", + printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz is not set (defaulting to %d)\n", __func__, config->dtv8_if_freq_khz); } if (config->clk_freq_khz == 0) { config->clk_freq_khz = TDA10048_CLK_16000; - printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz " - "is not set (defaulting to %d)\n", + printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz is not set (defaulting to %d)\n", __func__, config->clk_freq_khz); } diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c index b09fe88c40f8..24ac54b3b967 100644 --- a/drivers/media/dvb-frontends/ves1820.c +++ b/drivers/media/dvb-frontends/ves1820.c @@ -65,8 +65,8 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) - printk("ves1820: %s(): writereg error (reg == 0x%02x, " - "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); + printk("ves1820: %s(): writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", + __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -84,8 +84,8 @@ static u8 ves1820_readreg(struct ves1820_state *state, u8 reg) ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) - printk("ves1820: %s(): readreg error (reg == 0x%02x, " - "ret == %i)\n", __func__, reg, ret); + printk("ves1820: %s(): readreg error (reg == 0x%02x, ret == %i)\n", + __func__, reg, ret); return b1[0]; } diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c index 7ed81315965f..df5d0fe24687 100644 --- a/drivers/media/dvb-frontends/zl10036.c +++ b/drivers/media/dvb-frontends/zl10036.c @@ -85,8 +85,8 @@ static int zl10036_read_status_reg(struct zl10036_state *state) deb_i2c("R(status): %02x [FL=%d]\n", status, (status & STATUS_FL) ? 1 : 0); if (status & STATUS_POR) - deb_info("%s: Power-On-Reset bit enabled - " - "need to initialize the tuner\n", __func__); + deb_info("%s: Power-On-Reset bit enabled - need to initialize the tuner\n", + __func__); return status; } diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c index f8c271be196c..d6ded11fee49 100644 --- a/drivers/media/dvb-frontends/zl10039.c +++ b/drivers/media/dvb-frontends/zl10039.c @@ -152,8 +152,7 @@ static int zl10039_init(struct dvb_frontend *fe) /* Reset logic */ ret = zl10039_writereg(state, GENERAL, 0x40); if (ret < 0) { - dprintk("Note: i2c write error normal when resetting the " - "tuner\n"); + dprintk("Note: i2c write error normal when resetting the tuner\n"); } /* Wake up */ ret = zl10039_writereg(state, GENERAL, 0x01); -- cgit v1.2.3 From 2a3edc5d55c23ee7e2c7fa662ac76cc41863c7a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:23 -0200 Subject: [media] common: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tveeprom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c index 47da0378cad8..e0e2cb706087 100644 --- a/drivers/media/common/tveeprom.c +++ b/drivers/media/common/tveeprom.c @@ -510,8 +510,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, len = eeprom_data[i] & 0x07; ++i; } else { - tveeprom_warn("Encountered bad packet header [%02x]. " - "Corrupt or not a Hauppauge eeprom.\n", + tveeprom_warn("Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); return; } -- cgit v1.2.3 From f96cffd77b014944fd0d855cf56b2b5724fafb0d Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 18 Oct 2016 20:53:35 -0200 Subject: [media] firewire: use dev_dbg() instead of printk() A structure for firedtv (struct firedtv) has a member for a pointer to struct device. In this case, we can use dev_dbg() for debug printing. This is more preferrable behaviour in device driver development. Signed-off-by: Takashi Sakamoto Acked-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/firewire/firedtv-rc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/firewire/firedtv-rc.c b/drivers/media/firewire/firedtv-rc.c index f82d4a93feb3..04dea2aac583 100644 --- a/drivers/media/firewire/firedtv-rc.c +++ b/drivers/media/firewire/firedtv-rc.c @@ -184,8 +184,9 @@ void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) else if (code >= 0x4540 && code <= 0x4542) code = oldtable[code - 0x4521]; else { - printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " - "from remote control\n", code); + dev_dbg(fdtv->device, + "invalid key code 0x%04x from remote control\n", + code); return; } -- cgit v1.2.3 From 4c481739afeb806f7ecfbfb2087f8c2afba00e74 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:23 -0200 Subject: [media] firewire: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Reviewed-by: Takashi Sakamoto Acked-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/firewire/firedtv-avc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c index 251a556112a9..5bde6c209cd7 100644 --- a/drivers/media/firewire/firedtv-avc.c +++ b/drivers/media/firewire/firedtv-avc.c @@ -1181,8 +1181,8 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) if (es_info_length > 0) { pmt_cmd_id = msg[read_pos++]; if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(fdtv->device, "invalid pmt_cmd_id %d " - "at stream level\n", pmt_cmd_id); + dev_err(fdtv->device, "invalid pmt_cmd_id %d at stream level\n", + pmt_cmd_id); if (es_info_length > sizeof(c->operand) - 4 - write_pos) { -- cgit v1.2.3 From 759a4ed4d8e068dd5dd38aa2f4f8651c5c205056 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:24 -0200 Subject: [media] platform: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Acked-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mx2_emmaprp.c | 10 +++++----- drivers/media/platform/pxa_camera.c | 6 ++---- drivers/media/platform/via-camera.c | 7 ++----- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index e68d271b10af..03e47e0f778d 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -724,10 +724,10 @@ static int emmaprp_buf_prepare(struct vb2_buffer *vb) q_data = get_q_data(ctx, vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { - dprintk(ctx->dev, "%s data will not fit into plane" - "(%lu < %lu)\n", __func__, - vb2_plane_size(vb, 0), - (long)q_data->sizeimage); + dprintk(ctx->dev, + "%s data will not fit into plane(%lu < %lu)\n", + __func__, vb2_plane_size(vb, 0), + (long)q_data->sizeimage); return -EINVAL; } @@ -937,7 +937,7 @@ static int emmaprp_probe(struct platform_device *pdev) snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name); pcdev->vfd = vfd; v4l2_info(&pcdev->v4l2_dev, EMMAPRP_MODULE_NAME - " Device registered as /dev/video%d\n", vfd->num); + " Device registered as /dev/video%d\n", vfd->num); platform_set_drvdata(pdev, pcdev); diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index c12209c701d3..bcdac4932fb1 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2347,8 +2347,7 @@ static int pxa_camera_probe(struct platform_device *pdev) * Platform hasn't set available data widths. This is bad. * Warn and use a default. */ - dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " - "data widths, using default 10 bit\n"); + dev_warn(&pdev->dev, "WARNING! Platform hasn't set available data widths, using default 10 bit\n"); pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; } if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8) @@ -2359,8 +2358,7 @@ static int pxa_camera_probe(struct platform_device *pdev) pcdev->width_flags |= 1 << 9; if (!pcdev->mclk) { dev_warn(&pdev->dev, - "mclk == 0! Please, fix your platform data. " - "Using default 20MHz\n"); + "mclk == 0! Please, fix your platform data. Using default 20MHz\n"); pcdev->mclk = 20000000; } diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 7ca12deba89c..e16f70a5df1d 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -39,15 +39,12 @@ MODULE_LICENSE("GPL"); static bool flip_image; module_param(flip_image, bool, 0444); MODULE_PARM_DESC(flip_image, - "If set, the sensor will be instructed to flip the image " - "vertically."); + "If set, the sensor will be instructed to flip the image vertically."); static bool override_serial; module_param(override_serial, bool, 0444); MODULE_PARM_DESC(override_serial, - "The camera driver will normally refuse to load if " - "the XO 1.5 serial port is enabled. Set this option " - "to force-enable the camera."); + "The camera driver will normally refuse to load if the XO 1.5 serial port is enabled. Set this option to force-enable the camera."); /* * The structure describing our camera. -- cgit v1.2.3 From 547633def7f5eb6deebf83400f61341b31eb7018 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:25 -0200 Subject: [media] radio: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-gemtek.c | 8 ++------ drivers/media/radio/radio-wl1273.c | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index cff1eb144a5c..ca051ccbc3e4 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -67,14 +67,10 @@ module_param(probe, bool, 0444); MODULE_PARM_DESC(probe, "Enable automatic device probing."); module_param(hardmute, bool, 0644); -MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may " - "reduce static noise."); +MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may reduce static noise."); module_param_array(io, int, NULL, 0444); -MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic " - "probing is disabled or fails. The most common I/O ports are: 0x20c " - "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to " - "work for the combined sound/radiocard)."); +MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic probing is disabled or fails. The most common I/O ports are: 0x20c 0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to work for the combined sound/radiocard)."); module_param_array(radio_nr, int, NULL, 0444); MODULE_PARM_DESC(radio_nr, "Radio device numbers"); diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index a93f681aa9d6..9ce4b12299b4 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -2068,8 +2068,7 @@ static int wl1273_fm_radio_probe(struct platform_device *pdev) goto err_request_irq; } } else { - dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ" - " not configured"); + dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ not configured"); r = -EINVAL; goto pdata_err; } -- cgit v1.2.3 From 25ec587c02c3008ead4046a998eb412ce41c72ec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:25 -0200 Subject: [media] rc: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/imon.c | 48 +++++++++++++++++------------------------- drivers/media/rc/ite-cir.c | 9 +++----- drivers/media/rc/mceusb.c | 4 +--- drivers/media/rc/rc-main.c | 3 +-- drivers/media/rc/redrat3.c | 18 ++++++---------- drivers/media/rc/streamzap.c | 11 +++++----- drivers/media/rc/winbond-cir.c | 9 +++----- 9 files changed, 40 insertions(+), 68 deletions(-) diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 9f5b59706741..0884b7dc0e71 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -527,8 +527,7 @@ static void ati_remote_input_report(struct urb *urb) remote_num = (data[3] >> 4) & 0x0f; if (channel_mask & (1 << (remote_num + 1))) { dbginfo(&ati_remote->interface->dev, - "Masked input from channel 0x%02x: data %02x, " - "mask= 0x%02lx\n", + "Masked input from channel 0x%02x: data %02x, mask= 0x%02lx\n", remote_num, data[2], channel_mask); return; } diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index d1c61cd035f6..bd5512e64aea 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1210,8 +1210,7 @@ MODULE_PARM_DESC(txsim, MODULE_DEVICE_TABLE(pnp, ene_ids); MODULE_DESCRIPTION - ("Infrared input driver for KB3926B/C/D/E/F " - "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); + ("Infrared input driver for KB3926B/C/D/E/F (aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); MODULE_AUTHOR("Maxim Levitsky"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index d62b1f38292c..bd807fa4cb9f 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -441,13 +441,11 @@ MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); /* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */ static int display_type; module_param(display_type, int, S_IRUGO); -MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, " - "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); +MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, 1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); static int pad_stabilize = 1; module_param(pad_stabilize, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD " - "presses in arrow key mode. 0=disable, 1=enable (default)."); +MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD presses in arrow key mode. 0=disable, 1=enable (default)."); /* * In certain use cases, mouse mode isn't really helpful, and could actually @@ -455,14 +453,12 @@ MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD " */ static bool nomouse; module_param(nomouse, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is " - "open. 0=don't disable, 1=disable. (default: don't disable)"); +MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is open. 0=don't disable, 1=disable. (default: don't disable)"); /* threshold at which a pad push registers as an arrow key in kbd mode */ static int pad_thresh; module_param(pad_thresh, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an " - "arrow key in kbd mode (default: 28)"); +MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an arrow key in kbd mode (default: 28)"); static void free_imon_context(struct imon_context *ictx) @@ -785,9 +781,7 @@ static ssize_t show_associate_remote(struct device *d, else strcpy(buf, "closed\n"); - dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for " - "instructions on how to associate your iMON 2.4G DT/LT " - "remote\n"); + dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n"); mutex_unlock(&ictx->lock); return strlen(buf); } @@ -1115,8 +1109,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; if (*rc_type && !(*rc_type & rc->allowed_protocols)) - dev_warn(dev, "Looks like you're trying to use an IR protocol " - "this device does not support\n"); + dev_warn(dev, "Looks like you're trying to use an IR protocol this device does not support\n"); if (*rc_type & RC_BIT_RC6_MCE) { dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); @@ -1129,8 +1122,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) /* ir_proto_packet[0] = 0x00; // already the default */ *rc_type = RC_BIT_OTHER; } else { - dev_warn(dev, "Unsupported IR protocol specified, overriding " - "to iMON IR protocol\n"); + dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); if (!pad_stabilize) dev_dbg(dev, "PAD stabilize functionality disabled\n"); /* ir_proto_packet[0] = 0x00; // already the default */ @@ -1719,8 +1711,8 @@ static void imon_incoming_packet(struct imon_context *ictx, not_input_data: if (len != 8) { - dev_warn(dev, "imon %s: invalid incoming packet " - "size (len = %d, intf%d)\n", __func__, len, intf); + dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n", + __func__, len, intf); return; } @@ -1876,8 +1868,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) allowed_protos = RC_BIT_RC6_MCE; break; default: - dev_info(ictx->dev, "Unknown 0xffdc device, " - "defaulting to VFD and iMON IR"); + dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); detected_display_type = IMON_DISPLAY_TYPE_VFD; /* We don't know which one it is, allow user to set the * RC6 one from userspace if OTHER wasn't correct. */ @@ -1934,8 +1925,8 @@ static void imon_set_display_type(struct imon_context *ictx) ictx->display_supported = false; else ictx->display_supported = true; - dev_info(ictx->dev, "%s: overriding display type to %d via " - "modparam\n", __func__, display_type); + dev_info(ictx->dev, "%s: overriding display type to %d via modparam\n", + __func__, display_type); } ictx->display_type = configured_display_type; @@ -2156,8 +2147,8 @@ static bool imon_find_endpoints(struct imon_context *ictx, if (!display_ep_found) { tx_control = true; display_ep_found = true; - dev_dbg(ictx->dev, "%s: device uses control endpoint, not " - "interface OUT endpoint\n", __func__); + dev_dbg(ictx->dev, "%s: device uses control endpoint, not interface OUT endpoint\n", + __func__); } /* @@ -2366,8 +2357,8 @@ static void imon_init_display(struct imon_context *ictx, /* set up sysfs entry for built-in clock */ ret = sysfs_create_group(&intf->dev.kobj, &imon_display_attr_group); if (ret) - dev_err(ictx->dev, "Could not create display sysfs " - "entries(%d)", ret); + dev_err(ictx->dev, "Could not create display sysfs entries(%d)", + ret); if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) ret = usb_register_dev(intf, &imon_lcd_class); @@ -2375,8 +2366,7 @@ static void imon_init_display(struct imon_context *ictx, ret = usb_register_dev(intf, &imon_vfd_class); if (ret) /* Not a fatal error, so ignore */ - dev_info(ictx->dev, "could not get a minor number for " - "display\n"); + dev_info(ictx->dev, "could not get a minor number for display\n"); } @@ -2456,8 +2446,8 @@ static int imon_probe(struct usb_interface *interface, mutex_unlock(&ictx->lock); } - dev_info(dev, "iMON device (%04x:%04x, intf%d) on " - "usb<%d:%d> initialized\n", vendor, product, ifnum, + dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n", + vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum); mutex_unlock(&driver_lock); diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 0f301903aa6f..c5e8e3885766 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -55,14 +55,12 @@ MODULE_PARM_DESC(debug, "Enable debugging output"); /* low limit for RX carrier freq, Hz, 0 for no RX demodulation */ static int rx_low_carrier_freq; module_param(rx_low_carrier_freq, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz, " - "0 for no RX demodulation"); +MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz, 0 for no RX demodulation"); /* high limit for RX carrier freq, Hz, 0 for no RX demodulation */ static int rx_high_carrier_freq; module_param(rx_high_carrier_freq, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, " - "Hz, 0 for no RX demodulation"); +MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, Hz, 0 for no RX demodulation"); /* override tx carrier frequency */ static int tx_carrier_freq; @@ -1484,8 +1482,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) { model_no = model_number; - ite_pr(KERN_NOTICE, "The model has been fixed by a module " - "parameter."); + ite_pr(KERN_NOTICE, "The model has been fixed by a module parameter."); } ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model); diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 4f8c7effdcee..f813b77c595d 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -604,9 +604,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_RSP_EQWAKEVERSION: if (!out) - dev_dbg(dev, "Wake version, proto: 0x%02x, " - "payload: 0x%02x, address: 0x%02x, " - "version: 0x%02x", + dev_dbg(dev, "Wake version, proto: 0x%02x, payload: 0x%02x, address: 0x%02x, version: 0x%02x", data1, data2, data3, data4); break; case MCE_RSP_GETPORTSTATUS: diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d9c1f2ff7119..b241e5f569ef 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -660,8 +660,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol, dev->last_toggle = toggle; dev->last_keycode = keycode; - IR_dprintk(1, "%s: key down event, " - "key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", + IR_dprintk(1, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", dev->input_name, keycode, protocol, scancode); input_report_key(dev->input_dev, keycode, 1); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 05ba47bc0b61..3b0ed1c3f2d8 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -265,8 +265,7 @@ static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code) /* Codes 0x20 through 0x2f are IR Firmware Errors */ case 0x20: - pr_cont("Initial signal pulse not long enough " - "to measure carrier frequency\n"); + pr_cont("Initial signal pulse not long enough to measure carrier frequency\n"); break; case 0x21: pr_cont("Not enough length values allocated for signal\n"); @@ -278,18 +277,15 @@ static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code) pr_cont("Too many signal repeats\n"); break; case 0x28: - pr_cont("Insufficient memory available for IR signal " - "data memory allocation\n"); + pr_cont("Insufficient memory available for IR signal data memory allocation\n"); break; case 0x29: - pr_cont("Insufficient memory available " - "for IrDa signal data memory allocation\n"); + pr_cont("Insufficient memory available for IrDa signal data memory allocation\n"); break; /* Codes 0x30 through 0x3f are USB Firmware Errors */ case 0x30: - pr_cont("Insufficient memory available for bulk " - "transfer structure\n"); + pr_cont("Insufficient memory available for bulk transfer structure\n"); break; /* @@ -301,8 +297,7 @@ static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code) pr_cont("Signal capture has been terminated\n"); break; case 0x41: - pr_cont("Attempt to set/get and unknown signal I/O " - "algorithm parameter\n"); + pr_cont("Attempt to set/get and unknown signal I/O algorithm parameter\n"); break; case 0x42: pr_cont("Signal capture already started\n"); @@ -917,8 +912,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) goto out; } - snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s " - "Infrared Remote Transceiver (%04x:%04x)", + snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s Infrared Remote Transceiver (%04x:%04x)", prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "", le16_to_cpu(rr3->udev->descriptor.idVendor), prod); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 4004260a7c69..53f9b0af358a 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -297,8 +297,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) goto out; } - snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared " - "Receiver (%04x:%04x)", + snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared Receiver (%04x:%04x)", le16_to_cpu(sz->usbdev->descriptor.idVendor), le16_to_cpu(sz->usbdev->descriptor.idProduct)); usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); @@ -364,15 +363,15 @@ static int streamzap_probe(struct usb_interface *intf, sz->endpoint = &(iface_host->endpoint[0].desc); if (!usb_endpoint_dir_in(sz->endpoint)) { - dev_err(&intf->dev, "%s: endpoint doesn't match input device " - "02%02x\n", __func__, sz->endpoint->bEndpointAddress); + dev_err(&intf->dev, "%s: endpoint doesn't match input device 02%02x\n", + __func__, sz->endpoint->bEndpointAddress); retval = -ENODEV; goto free_sz; } if (!usb_endpoint_xfer_int(sz->endpoint)) { - dev_err(&intf->dev, "%s: endpoint attributes don't match xfer " - "02%02x\n", __func__, sz->endpoint->bmAttributes); + dev_err(&intf->dev, "%s: endpoint attributes don't match xfer 02%02x\n", + __func__, sz->endpoint->bmAttributes); retval = -ENODEV; goto free_sz; } diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 95ae60e659a1..cdcd6e38b295 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -227,8 +227,7 @@ struct wbcir_data { static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; module_param(protocol, uint, 0444); -MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command " - "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); +MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command (0 = RC5, 1 = NEC, 2 = RC6A, default)"); static bool invert; /* default = 0 */ module_param(invert, bool, 0444); @@ -244,8 +243,7 @@ MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); static unsigned int wake_rc6mode = 6; module_param(wake_rc6mode, uint, 0644); -MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command " - "(0 = 0, 6 = 6A, default)"); +MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command (0 = 0, 6 = 6A, default)"); @@ -1050,8 +1048,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_free_data; } - dev_dbg(&device->dev, "Found device " - "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", + dev_dbg(&device->dev, "Found device (w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", data->wbase, data->ebase, data->sbase, data->irq); data->led.name = "cir::activity"; -- cgit v1.2.3 From 8ca2e927eb29cdfb67439b5894307e7d3872f2ee Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 Oct 2016 17:44:26 -0200 Subject: [media] tuners: don't break long lines Due to the 80-cols restrictions, and latter due to checkpatch warnings, several strings were broken into multiple lines. This is not considered a good practice anymore, as it makes harder to grep for strings at the source code. As we're right now fixing other drivers due to KERN_CONT, we need to be able to identify what printk strings don't end with a "\n". It is a way easier to detect those if we don't break long lines. So, join those continuation lines. The patch was generated via the script below, and manually adjusted if needed. use Text::Tabs; while (<>) { if ($next ne "") { $c=$_; if ($c =~ /^\s+\"(.*)/) { $c2=$1; $next =~ s/\"\n$//; $n = expand($next); $funpos = index($n, '('); $pos = index($c2, '",'); if ($funpos && $pos > 0) { $s1 = substr $c2, 0, $pos + 2; $s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2; $s2 =~ s/^\s+//; $s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne ""); print unexpand("$next$s1\n"); print unexpand("$s2\n") if ($s2 ne ""); } else { print "$next$c2\n"; } $next=""; next; } else { print $next; } $next=""; } else { if (m/\"$/) { if (!m/\\n\"$/) { $next=$_; next; } } } print $_; } Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc0011.c | 7 ++---- drivers/media/tuners/mc44s803.c | 4 +-- drivers/media/tuners/tda18271-common.c | 4 +-- drivers/media/tuners/tda18271-fe.c | 3 +-- drivers/media/tuners/tda18271-maps.c | 6 +---- drivers/media/tuners/tda8290.c | 4 +-- drivers/media/tuners/tea5761.c | 6 ++--- drivers/media/tuners/tuner-simple.c | 45 ++++++++++++++-------------------- drivers/media/tuners/xc4000.c | 25 ++++++------------- 9 files changed, 39 insertions(+), 65 deletions(-) diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c index 3932aa81e18c..2dda8d993c14 100644 --- a/drivers/media/tuners/fc0011.c +++ b/drivers/media/tuners/fc0011.c @@ -262,8 +262,7 @@ static int fc0011_set_params(struct dvb_frontend *fe) regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M; break; default: - dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. " - "Using 6000 kHz.\n", + dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. Using 6000 kHz.\n", bandwidth); bandwidth = 6000; /* fallthrough */ @@ -435,9 +434,7 @@ static int fc0011_set_params(struct dvb_frontend *fe) if (err) return err; - dev_dbg(&priv->i2c->dev, "Tuned to " - "fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X " - "vcocal=%02X(%u) bw=%u\n", + dev_dbg(&priv->i2c->dev, "Tuned to fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X vcocal=%02X(%u) bw=%u\n", (unsigned int)regs[FC11_REG_FA], (unsigned int)regs[FC11_REG_FP], (unsigned int)regs[FC11_REG_XINHI], diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c index f1b764074661..d5681669d3cd 100644 --- a/drivers/media/tuners/mc44s803.c +++ b/drivers/media/tuners/mc44s803.c @@ -349,8 +349,8 @@ struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, id = MC44S803_REG_MS(reg, MC44S803_ID); if (id != 0x14) { - mc_printk(KERN_ERR, "unsupported ID " - "(%x should be 0x14)\n", id); + mc_printk(KERN_ERR, "unsupported ID (%x should be 0x14)\n", + id); goto error; } diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c index a26bb33102b8..7e81cd887c13 100644 --- a/drivers/media/tuners/tda18271-common.c +++ b/drivers/media/tuners/tda18271-common.c @@ -251,8 +251,8 @@ static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len, } if (ret != 1) - tda_err("ERROR: idx = 0x%x, len = %d, " - "i2c_transfer returned: %d\n", idx, max, ret); + tda_err("ERROR: idx = 0x%x, len = %d, i2c_transfer returned: %d\n", + idx, max, ret); return (ret == 1 ? 0 : ret); } diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c index 2d50e8b1dce1..a4730610c0c6 100644 --- a/drivers/media/tuners/tda18271-fe.c +++ b/drivers/media/tuners/tda18271-fe.c @@ -26,8 +26,7 @@ int tda18271_debug; module_param_named(debug, tda18271_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level " - "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))"); +MODULE_PARM_DESC(debug, "set debug level (info=1, map=2, reg=4, adv=8, cal=16 (or-able))"); static int tda18271_cal_on_startup = -1; module_param_named(cal, tda18271_cal_on_startup, int, 0644); diff --git a/drivers/media/tuners/tda18271-maps.c b/drivers/media/tuners/tda18271-maps.c index 1e89dd93c4bb..7d114677b4ca 100644 --- a/drivers/media/tuners/tda18271-maps.c +++ b/drivers/media/tuners/tda18271-maps.c @@ -1024,11 +1024,7 @@ int tda18271_lookup_rf_band(struct dvb_frontend *fe, u32 *freq, u8 *rf_band) while ((map[i].rfmax * 1000) < *freq) { if (tda18271_debug & DBG_ADV) - tda_map("(%d) rfmax = %d < freq = %d, " - "rf1_def = %d, rf2_def = %d, rf3_def = %d, " - "rf1 = %d, rf2 = %d, rf3 = %d, " - "rf_a1 = %d, rf_a2 = %d, " - "rf_b1 = %d, rf_b2 = %d\n", + tda_map("(%d) rfmax = %d < freq = %d, rf1_def = %d, rf2_def = %d, rf3_def = %d, rf1 = %d, rf2 = %d, rf3 = %d, rf_a1 = %d, rf_a2 = %d, rf_b1 = %d, rf_b2 = %d\n", i, map[i].rfmax * 1000, *freq, map[i].rf1_def, map[i].rf2_def, map[i].rf3_def, map[i].rf1, map[i].rf2, map[i].rf3, diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c index 998e82bba9c0..6b75415b75a5 100644 --- a/drivers/media/tuners/tda8290.c +++ b/drivers/media/tuners/tda8290.c @@ -617,8 +617,8 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) if (tuner_addrs == 0) { tuner_addrs = 0x60; - tuner_info("could not clearly identify tuner address, " - "defaulting to %x\n", tuner_addrs); + tuner_info("could not clearly identify tuner address, defaulting to %x\n", + tuner_addrs); } else { tuner_addrs = tuner_addrs & 0xff; tuner_info("setting tuner address to %x\n", tuner_addrs); diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c index 36b0b1e1d05b..12347aa95de3 100644 --- a/drivers/media/tuners/tea5761.c +++ b/drivers/media/tuners/tea5761.c @@ -274,13 +274,11 @@ int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) } if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) { - printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x." - " It is not a TEA5761\n", + printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n", buffer[13], buffer[14], buffer[15]); return -EINVAL; } - printk(KERN_WARNING "tea5761: TEA%02x%02x detected. " - "Manufacturer ID= 0x%02x\n", + printk(KERN_WARNING "tea5761: TEA%02x%02x detected. Manufacturer ID= 0x%02x\n", buffer[14], buffer[15], buffer[13]); return 0; diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c index 9ba9582e7765..315f45cd0778 100644 --- a/drivers/media/tuners/tuner-simple.c +++ b/drivers/media/tuners/tuner-simple.c @@ -275,8 +275,7 @@ static int simple_config_lookup(struct dvb_frontend *fe, *config = t_params->ranges[i].config; *cb = t_params->ranges[i].cb; - tuner_dbg("freq = %d.%02d (%d), range = %d, " - "config = 0x%02x, cb = 0x%02x\n", + tuner_dbg("freq = %d.%02d (%d), range = %d, config = 0x%02x, cb = 0x%02x\n", *frequency / 16, *frequency % 16 * 100 / 16, *frequency, i, *config, *cb); @@ -404,12 +403,12 @@ static int simple_std_setup(struct dvb_frontend *fe, i2c.addr = 0x0a; rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2); if (2 != rc) - tuner_warn("i2c i/o error: rc == %d " - "(should be 2)\n", rc); + tuner_warn("i2c i/o error: rc == %d (should be 2)\n", + rc); rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2); if (2 != rc) - tuner_warn("i2c i/o error: rc == %d " - "(should be 2)\n", rc); + tuner_warn("i2c i/o error: rc == %d (should be 2)\n", + rc); break; } } @@ -463,8 +462,8 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, rc = tuner_i2c_xfer_recv(&priv->i2c_props, &status_byte, 1); if (1 != rc) { - tuner_warn("i2c i/o read error: rc == %d " - "(should be 1)\n", rc); + tuner_warn("i2c i/o read error: rc == %d (should be 1)\n", + rc); break; } if (status_byte & TUNER_PLL_LOCKED) @@ -483,8 +482,8 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); if (4 != rc) - tuner_warn("i2c i/o error: rc == %d " - "(should be 4)\n", rc); + tuner_warn("i2c i/o error: rc == %d (should be 4)\n", + rc); break; } } @@ -499,8 +498,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) switch (priv->type) { case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: - tuner_dbg("This tuner doesn't have FM. " - "Most cards have a TEA5767 for FM\n"); + tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n"); return 0; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: @@ -586,8 +584,7 @@ static int simple_set_tv_freq(struct dvb_frontend *fe, div = params->frequency + IFPCoff + offset; - tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, " - "Offset=%d.%02d MHz, div=%0d\n", + tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", params->frequency / 16, params->frequency % 16 * 100 / 16, IFPCoff / 16, IFPCoff % 16 * 100 / 16, offset / 16, offset % 16 * 100 / 16, div); @@ -858,8 +855,7 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, if (!tun->stepsize) { /* tuner-core was loaded before the digital tuner was * configured and somehow picked the wrong tuner type */ - tuner_err("attempt to treat tuner %d (%s) as digital tuner " - "without stepsize defined.\n", + tuner_err("attempt to treat tuner %d (%s) as digital tuner without stepsize defined.\n", priv->type, priv->tun->name); return 0; /* failure */ } @@ -1077,8 +1073,7 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 1); if (1 != i2c_transfer(i2c_adap, &msg, 1)) - printk(KERN_WARNING "tuner-simple %d-%04x: " - "unable to probe %s, proceeding anyway.", + printk(KERN_WARNING "tuner-simple %d-%04x: unable to probe %s, proceeding anyway.", i2c_adapter_id(i2c_adap), i2c_addr, tuners[type].name); @@ -1123,18 +1118,16 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, if ((debug) || ((atv_input[priv->nr] > 0) || (dtv_input[priv->nr] > 0))) { if (0 == atv_input[priv->nr]) - tuner_info("tuner %d atv rf input will be " - "autoselected\n", priv->nr); + tuner_info("tuner %d atv rf input will be autoselected\n", + priv->nr); else - tuner_info("tuner %d atv rf input will be " - "set to input %d (insmod option)\n", + tuner_info("tuner %d atv rf input will be set to input %d (insmod option)\n", priv->nr, atv_input[priv->nr]); if (0 == dtv_input[priv->nr]) - tuner_info("tuner %d dtv rf input will be " - "autoselected\n", priv->nr); + tuner_info("tuner %d dtv rf input will be autoselected\n", + priv->nr); else - tuner_info("tuner %d dtv rf input will be " - "set to input %d (insmod option)\n", + tuner_info("tuner %d dtv rf input will be set to input %d (insmod option)\n", priv->nr, dtv_input[priv->nr]); } diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c index d95c7e082ccf..ac98dea985c8 100644 --- a/drivers/media/tuners/xc4000.c +++ b/drivers/media/tuners/xc4000.c @@ -43,14 +43,11 @@ MODULE_PARM_DESC(debug, "Debugging level (0 to 2, default: 0 (off))."); static int no_poweroff; module_param(no_poweroff, int, 0644); -MODULE_PARM_DESC(no_poweroff, "Power management (1: disabled, 2: enabled, " - "0 (default): use device-specific default mode)."); +MODULE_PARM_DESC(no_poweroff, "Power management (1: disabled, 2: enabled, 0 (default): use device-specific default mode)."); static int audio_std; module_param(audio_std, int, 0644); -MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly " - "needs to know what audio standard is needed for some video standards " - "with audio A2 or NICAM. The valid settings are a sum of:\n" +MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly needs to know what audio standard is needed for some video standards with audio A2 or NICAM. The valid settings are a sum of:\n" " 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n" " 2: use A2 instead of NICAM or BTSC\n" " 4: use SECAM/K3 instead of K1\n" @@ -60,8 +57,7 @@ MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly " static char firmware_name[30]; module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); -MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " - "default firmware name."); +MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the default firmware name."); static DEFINE_MUTEX(xc4000_list_mutex); static LIST_HEAD(hybrid_tuner_instance_list); @@ -290,8 +286,7 @@ static int xc4000_tuner_reset(struct dvb_frontend *fe) return -EREMOTEIO; } } else { - printk(KERN_ERR "xc4000: no tuner reset callback function, " - "fatal\n"); + printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n"); return -EINVAL; } return 0; @@ -679,8 +674,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, if (best_nr_diffs > 0U) { printk(KERN_WARNING - "Selecting best matching firmware (%u bits differ) for " - "type=(%x), id %016llx:\n", + "Selecting best matching firmware (%u bits differ) for type=(%x), id %016llx:\n", best_nr_diffs, type, (unsigned long long)*id); i = best_i; } @@ -800,8 +794,7 @@ static int xc4000_fwupload(struct dvb_frontend *fe) n++; if (n >= n_array) { - printk(KERN_ERR "More firmware images in file than " - "were expected!\n"); + printk(KERN_ERR "More firmware images in file than were expected!\n"); goto corrupt; } @@ -1055,8 +1048,7 @@ check_device: goto fail; } - dprintk(1, "Device is Xceive %d version %d.%d, " - "firmware version %d.%d\n", + dprintk(1, "Device is Xceive %d version %d.%d, firmware version %d.%d\n", hwmodel, hw_major, hw_minor, fw_major, fw_minor); /* Check firmware version against what we downloaded. */ @@ -1076,8 +1068,7 @@ check_device: } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel || priv->hwvers != ((hw_major << 8) | hw_minor)) { printk(KERN_WARNING - "Read invalid device hardware information - tuner " - "hung?\n"); + "Read invalid device hardware information - tuner hung?\n"); goto fail; } -- cgit v1.2.3 From 7cda4c5bae46ffca3abeadc4c1882d9325ee3102 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 10:51:20 -0300 Subject: [media] tveeprom: use dev_foo() for printk messages Instead of calling a V4L-specific macro, do the right thing and use the dev_foo() macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tveeprom.c | 76 +++++++++++++---------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c index e0e2cb706087..e7d0d86f19aa 100644 --- a/drivers/media/common/tveeprom.c +++ b/drivers/media/common/tveeprom.c @@ -28,7 +28,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include @@ -45,22 +44,9 @@ MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); MODULE_AUTHOR("John Klar"); MODULE_LICENSE("GPL"); -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - #define STRM(array, i) \ (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown") -#define tveeprom_info(fmt, arg...) \ - v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg) -#define tveeprom_warn(fmt, arg...) \ - v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg) -#define tveeprom_dbg(fmt, arg...) do { \ - if (debug) \ - v4l_printk(KERN_DEBUG, "tveeprom", \ - c->adapter, c->addr, fmt , ## arg); \ - } while (0) /* * The Hauppauge eeprom uses an 8bit field to determine which @@ -510,18 +496,13 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, len = eeprom_data[i] & 0x07; ++i; } else { - tveeprom_warn("Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", + dev_warn(&c->dev, "Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); return; } - if (debug) { - tveeprom_info("Tag [%02x] + %d bytes:", - eeprom_data[i], len - 1); - for (j = 1; j < len; j++) - printk(KERN_CONT " %02x", eeprom_data[i + j]); - printk(KERN_CONT "\n"); - } + dev_dbg(&c->dev, "Tag [%02x] + %d bytes: %*ph\n", + eeprom_data[i], len - 1, len, &eeprom_data[i]); /* process by tag */ tag = eeprom_data[i]; @@ -661,14 +642,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, /* case 0x12: tag 'InfoBits' */ default: - tveeprom_dbg("Not sure what to do with tag [%02x]\n", + dev_dbg(&c->dev, "Not sure what to do with tag [%02x]\n", tag); /* dump the rest of the packet? */ } } if (!done) { - tveeprom_warn("Ran out of data!\n"); + dev_warn(&c->dev, "Ran out of data!\n"); return; } @@ -681,8 +662,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, } if (hasRadioTuner(tuner1) && !tvee->has_radio) { - tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); - tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); + dev_info(&c->dev, "The eeprom says no radio is present, but the tuner type\n"); + dev_info(&c->dev, "indicates otherwise. I will assume that radio is present.\n"); tvee->has_radio = 1; } @@ -717,46 +698,46 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, } } - tveeprom_info("Hauppauge model %d, rev %s, serial# %u\n", + dev_info(&c->dev, "Hauppauge model %d, rev %s, serial# %u\n", tvee->model, tvee->rev_str, tvee->serial_number); if (tvee->has_MAC_address == 1) - tveeprom_info("MAC address is %pM\n", tvee->MAC_address); - tveeprom_info("tuner model is %s (idx %d, type %d)\n", + dev_info(&c->dev, "MAC address is %pM\n", tvee->MAC_address); + dev_info(&c->dev, "tuner model is %s (idx %d, type %d)\n", t_name1, tuner1, tvee->tuner_type); - tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", + dev_info(&c->dev, "TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], t_format1); if (tuner2) - tveeprom_info("second tuner model is %s (idx %d, type %d)\n", + dev_info(&c->dev, "second tuner model is %s (idx %d, type %d)\n", t_name2, tuner2, tvee->tuner2_type); if (t_format2) - tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", + dev_info(&c->dev, "TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], t_format2); if (audioic < 0) { - tveeprom_info("audio processor is unknown (no idx)\n"); + dev_info(&c->dev, "audio processor is unknown (no idx)\n"); tvee->audio_processor = TVEEPROM_AUDPROC_OTHER; } else { if (audioic < ARRAY_SIZE(audio_ic)) - tveeprom_info("audio processor is %s (idx %d)\n", + dev_info(&c->dev, "audio processor is %s (idx %d)\n", audio_ic[audioic].name, audioic); else - tveeprom_info("audio processor is unknown (idx %d)\n", + dev_info(&c->dev, "audio processor is unknown (idx %d)\n", audioic); } if (tvee->decoder_processor) - tveeprom_info("decoder processor is %s (idx %d)\n", + dev_info(&c->dev, "decoder processor is %s (idx %d)\n", STRM(decoderIC, tvee->decoder_processor), tvee->decoder_processor); if (tvee->has_ir) - tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n", + dev_info(&c->dev, "has %sradio, has %sIR receiver, has %sIR transmitter\n", tvee->has_radio ? "" : "no ", (tvee->has_ir & 2) ? "" : "no ", (tvee->has_ir & 4) ? "" : "no "); else - tveeprom_info("has %sradio\n", + dev_info(&c->dev, "has %sradio\n", tvee->has_radio ? "" : "no "); } EXPORT_SYMBOL(tveeprom_hauppauge_analog); @@ -772,26 +753,17 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len) buf = 0; err = i2c_master_send(c, &buf, 1); if (err != 1) { - tveeprom_info("Huh, no eeprom present (err=%d)?\n", err); + dev_info(&c->dev, "Huh, no eeprom present (err=%d)?\n", err); return -1; } err = i2c_master_recv(c, eedata, len); if (err != len) { - tveeprom_warn("i2c eeprom read error (err=%d)\n", err); + dev_warn(&c->dev, "i2c eeprom read error (err=%d)\n", err); return -1; } - if (debug) { - int i; - - tveeprom_info("full 256-byte eeprom dump:\n"); - for (i = 0; i < len; i++) { - if (0 == (i % 16)) - tveeprom_info("%02x:", i); - printk(KERN_CONT " %02x", eedata[i]); - if (15 == (i % 16)) - printk(KERN_CONT "\n"); - } - } + + print_hex_dump_debug("full 256-byte eeprom dump:", DUMP_PREFIX_NONE, + 16, 1, eedata, len, true); return 0; } EXPORT_SYMBOL(tveeprom_read); -- cgit v1.2.3 From 3467c9a7e7f9209a9ecd8f9db65b04a323a13932 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 16 Sep 2016 03:14:33 -0300 Subject: [media] s5p-mfc: fix failure path of s5p_mfc_alloc_memdev() s5p_mfc_alloc_memdev() function lacks proper releasing of allocated device in case of reserved memory initialization failure. This results in NULL pointer dereference: [ 2.828457] Unable to handle kernel NULL pointer dereference at virtual address 00000001 [ 2.835089] pgd = c0004000 [ 2.837752] [00000001] *pgd=00000000 [ 2.844696] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [ 2.848680] Modules linked in: [ 2.851722] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.8.0-rc6-00002-gafa1b97 #878 [ 2.859357] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 2.865433] task: ef080000 task.stack: ef06c000 [ 2.869952] PC is at strcmp+0x0/0x30 [ 2.873508] LR is at platform_match+0x84/0xac [ 2.877847] pc : [] lr : [] psr: 20000013 [ 2.877847] sp : ef06dea0 ip : 00000000 fp : 00000000 [ 2.889303] r10: 00000000 r9 : c0b34848 r8 : c0b1e968 [ 2.894511] r7 : 00000000 r6 : 00000001 r5 : c086e7fc r4 : eeb8e010 [ 2.901021] r3 : 0000006d r2 : 00000000 r1 : c086e7fc r0 : 00000001 [ 2.907533] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 2.914649] Control: 10c5387d Table: 4000404a DAC: 00000051 [ 2.920378] Process swapper/0 (pid: 1, stack limit = 0xef06c210) [ 2.926367] Stack: (0xef06dea0 to 0xef06e000) [ 2.930711] dea0: eeb8e010 c0c2d91c c03f4a6c c03f4a8c 00000000 c0c2d91c c03f4a6c c03f2fc8 [ 2.938870] dec0: ef003274 ef10c4c0 c0c2d91c ef10cc80 c0c21270 c03f3fa4 c09c1be8 c0c2d91c [ 2.947028] dee0: 00000006 c0c2d91c 00000006 c0b3483c c0c47000 c03f5314 c0c2d908 c0b5fed8 [ 2.955188] df00: 00000006 c010178c 60000013 c0a4ef14 00000000 c06feaa0 ef080000 60000013 [ 2.963347] df20: 00000000 c0c095c8 efffca76 c0816b8c 000000d5 c0134098 c0b34848 c09d6cdc [ 2.971506] df40: c0a4de70 00000000 00000006 00000006 c0c09568 efffca40 c0b5fed8 00000006 [ 2.979665] df60: c0b3483c c0c47000 000000d5 c0b34848 c0b005a4 c0b00d84 00000006 00000006 [ 2.987824] df80: 00000000 c0b005a4 00000000 c06fb4d8 00000000 00000000 00000000 00000000 [ 2.995983] dfa0: 00000000 c06fb4e0 00000000 c01079b8 00000000 00000000 00000000 00000000 [ 3.004142] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 3.012302] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [ 3.020469] [] (strcmp) from [] (platform_match+0x84/0xac) [ 3.027672] [] (platform_match) from [] (__driver_attach+0x20/0xb0) [ 3.035654] [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [ 3.043812] [] (bus_for_each_dev) from [] (bus_add_driver+0xe8/0x1f4) [ 3.051971] [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [ 3.059958] [] (driver_register) from [] (do_one_initcall+0x3c/0x16c) [ 3.068123] [] (do_one_initcall) from [] (kernel_init_freeable+0x120/0x1ec) [ 3.076802] [] (kernel_init_freeable) from [] (kernel_init+0x8/0x118) [ 3.084958] [] (kernel_init) from [] (ret_from_fork+0x14/0x3c) [ 3.092506] Code: 1afffffb e12fff1e e1a03000 eafffff7 (e4d03001) [ 3.098618] ---[ end trace 511bf9d750810709 ]--- [ 3.103207] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b This patch fixes this issue. Fixes: c79667dd93b084fe412bcfe7fbf0ba43f7dec520 ("media: s5p-mfc: replace custom reserved memory handling code with generic one") CC: stable@vger.kernel.org # v4.7+ Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 0a5b8f5e011e..3436eda58855 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1082,6 +1082,7 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev, idx); if (ret == 0) return child; + device_del(child); } put_device(child); -- cgit v1.2.3 From e2818a59f7ca42e896869903239575cd36f52119 Mon Sep 17 00:00:00 2001 From: Andrew-CT Chen Date: Fri, 2 Sep 2016 09:19:52 -0300 Subject: [media] VPU: mediatek: Add decode support VPU driver add decode support [mchehab@s-opensource.org: fix a kernel-doc markup] Signed-off-by: Andrew-CT Chen Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 12 +++++++++ drivers/media/platform/mtk-vpu/mtk_vpu.h | 43 ++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index c9bf58c97878..63510de0147c 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -134,6 +134,8 @@ struct vpu_wdt { * * @signaled: the signal of vpu initialization completed * @fw_ver: VPU firmware version + * @dec_capability: decoder capability which is not used for now and + * the value is reserved for future use * @enc_capability: encoder capability which is not used for now and * the value is reserved for future use * @wq: wait queue for VPU initialization status @@ -141,6 +143,7 @@ struct vpu_wdt { struct vpu_run { u32 signaled; char fw_ver[VPU_FW_VER_LEN]; + unsigned int dec_capability; unsigned int enc_capability; wait_queue_head_t wq; }; @@ -415,6 +418,14 @@ int vpu_wdt_reg_handler(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(vpu_wdt_reg_handler); +unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev) +{ + struct mtk_vpu *vpu = platform_get_drvdata(pdev); + + return vpu->run.dec_capability; +} +EXPORT_SYMBOL_GPL(vpu_get_vdec_hw_capa); + unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev) { struct mtk_vpu *vpu = platform_get_drvdata(pdev); @@ -600,6 +611,7 @@ static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv) vpu->run.signaled = run->signaled; strncpy(vpu->run.fw_ver, run->fw_ver, VPU_FW_VER_LEN); + vpu->run.dec_capability = run->dec_capability; vpu->run.enc_capability = run->enc_capability; wake_up_interruptible(&vpu->run.wq); } diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.h b/drivers/media/platform/mtk-vpu/mtk_vpu.h index 5ab37f04bdfd..69da501afffa 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.h +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.h @@ -31,21 +31,36 @@ typedef void (*ipi_handler_t) (void *data, * enum ipi_id - the id of inter-processor interrupt * * @IPI_VPU_INIT: The interrupt from vpu is to notfiy kernel - VPU initialization completed. - IPI_VPU_INIT is sent from VPU when firmware is - loaded. AP doesn't need to send IPI_VPU_INIT - command to VPU. - For other IPI below, AP should send the request - to VPU to trigger the interrupt. + * VPU initialization completed. + * IPI_VPU_INIT is sent from VPU when firmware is + * loaded. AP doesn't need to send IPI_VPU_INIT + * command to VPU. + * For other IPI below, AP should send the request + * to VPU to trigger the interrupt. + * @IPI_VDEC_H264: The interrupt from vpu is to notify kernel to + * handle H264 vidoe decoder job, and vice versa. + * Decode output format is always MT21 no matter what + * the input format is. + * @IPI_VDEC_VP8: The interrupt from is to notify kernel to + * handle VP8 video decoder job, and vice versa. + * Decode output format is always MT21 no matter what + * the input format is. + * @IPI_VDEC_VP9: The interrupt from vpu is to notify kernel to + * handle VP9 video decoder job, and vice versa. + * Decode output format is always MT21 no matter what + * the input format is. * @IPI_VENC_H264: The interrupt from vpu is to notify kernel to - handle H264 video encoder job, and vice versa. + * handle H264 video encoder job, and vice versa. * @IPI_VENC_VP8: The interrupt fro vpu is to notify kernel to - handle VP8 video encoder job,, and vice versa. + * handle VP8 video encoder job,, and vice versa. * @IPI_MAX: The maximum IPI number */ enum ipi_id { IPI_VPU_INIT = 0, + IPI_VDEC_H264, + IPI_VDEC_VP8, + IPI_VDEC_VP9, IPI_VENC_H264, IPI_VENC_VP8, IPI_MAX, @@ -55,10 +70,12 @@ enum ipi_id { * enum rst_id - reset id to register reset function for VPU watchdog timeout * * @VPU_RST_ENC: encoder reset id + * @VPU_RST_DEC: decoder reset id * @VPU_RST_MAX: maximum reset id */ enum rst_id { VPU_RST_ENC, + VPU_RST_DEC, VPU_RST_MAX, }; @@ -125,6 +142,16 @@ struct platform_device *vpu_get_plat_device(struct platform_device *pdev); int vpu_wdt_reg_handler(struct platform_device *pdev, void vpu_wdt_reset_func(void *), void *priv, enum rst_id id); + +/** + * vpu_get_vdec_hw_capa - get video decoder hardware capability + * + * @pdev: VPU platform device + * + * Return: video decoder hardware capability + **/ +unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev); + /** * vpu_get_venc_hw_capa - get video encoder hardware capability * -- cgit v1.2.3 From f3ad804c9dda66fb0087c9e210a23af69377ecb4 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:19:53 -0300 Subject: [media] dt-bindings: Add a binding for Mediatek Video Decoder Add a DT binding documentation of Video Decoder for the MT8173 SoC from Mediatek. Signed-off-by: Tiffany Lin Acked-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/mediatek-vcodec.txt | 57 ++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt index 59a47a5b924b..46c15c54175d 100644 --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt @@ -1,25 +1,74 @@ Mediatek Video Codec Mediatek Video Codec is the video codec hw present in Mediatek SoCs which -supports high resolution encoding functionalities. +supports high resolution encoding and decoding functionalities. Required properties: - compatible : "mediatek,mt8173-vcodec-enc" for encoder + "mediatek,mt8173-vcodec-dec" for decoder. - reg : Physical base address of the video codec registers and length of memory mapped region. - interrupts : interrupt number to the cpu. - mediatek,larb : must contain the local arbiters in the current Socs. - clocks : list of clock specifiers, corresponding to entries in the clock-names property. -- clock-names: encoder must contain "venc_sel_src", "venc_sel", -- "venc_lt_sel_src", "venc_lt_sel". +- clock-names: encoder must contain "venc_sel_src", "venc_sel",, + "venc_lt_sel_src", "venc_lt_sel", decoder must contain "vcodecpll", + "univpll_d2", "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", + "venc_lt_sel", "vdec_bus_clk_src". - iommus : should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt for details. - mediatek,vpu : the node of video processor unit + Example: -vcodec_enc: vcodec@0x18002000 { + +vcodec_dec: vcodec@16000000 { + compatible = "mediatek,mt8173-vcodec-dec"; + reg = <0 0x16000000 0 0x100>, /*VDEC_SYS*/ + <0 0x16020000 0 0x1000>, /*VDEC_MISC*/ + <0 0x16021000 0 0x800>, /*VDEC_LD*/ + <0 0x16021800 0 0x800>, /*VDEC_TOP*/ + <0 0x16022000 0 0x1000>, /*VDEC_CM*/ + <0 0x16023000 0 0x1000>, /*VDEC_AD*/ + <0 0x16024000 0 0x1000>, /*VDEC_AV*/ + <0 0x16025000 0 0x1000>, /*VDEC_PP*/ + <0 0x16026800 0 0x800>, /*VP8_VD*/ + <0 0x16027000 0 0x800>, /*VP6_VD*/ + <0 0x16027800 0 0x800>, /*VP8_VL*/ + <0 0x16028400 0 0x400>; /*VP9_VD*/ + interrupts = ; + mediatek,larb = <&larb1>; + iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>, + <&iommu M4U_PORT_HW_VDEC_PP_EXT>, + <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>, + <&iommu M4U_PORT_HW_VDEC_UFO_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>; + mediatek,vpu = <&vpu>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>, + <&topckgen CLK_TOP_UNIVPLL_D2>, + <&topckgen CLK_TOP_CCI400_SEL>, + <&topckgen CLK_TOP_VDEC_SEL>, + <&topckgen CLK_TOP_VCODECPLL>, + <&apmixedsys CLK_APMIXED_VENCPLL>, + <&topckgen CLK_TOP_VENC_LT_SEL>, + <&topckgen CLK_TOP_VCODECPLL_370P5>; + clock-names = "vcodecpll", + "univpll_d2", + "clk_cci400_sel", + "vdec_sel", + "vdecpll", + "vencpll", + "venc_lt_sel", + "vdec_bus_clk_src"; + }; + + vcodec_enc: vcodec@0x18002000 { compatible = "mediatek,mt8173-vcodec-enc"; reg = <0 0x18002000 0 0x1000>, /*VENC_SYS*/ <0 0x19002000 0 0x1000>; /*VENC_LT_SYS*/ -- cgit v1.2.3 From 590577a4e5257ac3ed72999a94666ad6ba8f24bc Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:19:54 -0300 Subject: [media] vcodec: mediatek: Add Mediatek V4L2 Video Decoder Driver Add v4l2 layer decoder driver for MT8173 [mchehab@s-opensource.com: make checkpatch.pl happy] Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/Makefile | 12 +- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 1432 ++++++++++++++++++++ drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h | 88 ++ .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 394 ++++++ .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 204 +++ .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 28 + drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 62 +- .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 +- .../media/platform/mtk-vcodec/mtk_vcodec_intr.c | 3 +- .../media/platform/mtk-vcodec/mtk_vcodec_util.c | 33 +- .../media/platform/mtk-vcodec/mtk_vcodec_util.h | 5 + drivers/media/platform/mtk-vcodec/vdec_drv_base.h | 55 + drivers/media/platform/mtk-vcodec/vdec_drv_if.c | 112 ++ drivers/media/platform/mtk-vcodec/vdec_drv_if.h | 101 ++ drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h | 103 ++ drivers/media/platform/mtk-vcodec/vdec_vpu_if.c | 170 +++ drivers/media/platform/mtk-vcodec/vdec_vpu_if.h | 96 ++ 17 files changed, 2884 insertions(+), 22 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h create mode 100644 drivers/media/platform/mtk-vcodec/vdec_drv_base.h create mode 100644 drivers/media/platform/mtk-vcodec/vdec_drv_if.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec_drv_if.h create mode 100644 drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h create mode 100644 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec_vpu_if.h diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index dc5cb006d600..b54e82372b4c 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -1,7 +1,13 @@ - -obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-enc.o mtk-vcodec-common.o - +obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ + mtk-vcodec-enc.o \ + mtk-vcodec-common.o + +mtk-vcodec-dec-y := mtk_vcodec_dec_drv.o \ + vdec_drv_if.o \ + vdec_vpu_if.o \ + mtk_vcodec_dec.o \ + mtk_vcodec_dec_pm.o \ mtk-vcodec-enc-y := venc/venc_vp8_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c new file mode 100644 index 000000000000..7f7464a570cb --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -0,0 +1,1432 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec.h" +#include "mtk_vcodec_intr.h" +#include "mtk_vcodec_util.h" +#include "vdec_drv_if.h" +#include "mtk_vcodec_dec_pm.h" + +#define OUT_FMT_IDX 0 +#define CAP_FMT_IDX 0 + +#define MTK_VDEC_MIN_W 64U +#define MTK_VDEC_MIN_H 64U +#define DFT_CFG_WIDTH MTK_VDEC_MIN_W +#define DFT_CFG_HEIGHT MTK_VDEC_MIN_H + +static struct mtk_video_fmt mtk_video_formats[] = { + { + .fourcc = V4L2_PIX_FMT_H264, + .type = MTK_FMT_DEC, + .num_planes = 1, + }, + { + .fourcc = V4L2_PIX_FMT_VP8, + .type = MTK_FMT_DEC, + .num_planes = 1, + }, +}; + +static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { + { + .fourcc = V4L2_PIX_FMT_H264, + .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16, + MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8, + .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16, + MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 }, + }, +}; + +#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) +#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) + +static struct mtk_video_fmt *mtk_vdec_find_format(struct v4l2_format *f) +{ + struct mtk_video_fmt *fmt; + unsigned int k; + + for (k = 0; k < NUM_FORMATS; k++) { + fmt = &mtk_video_formats[k]; + if (fmt->fourcc == f->fmt.pix_mp.pixelformat) + return fmt; + } + + return NULL; +} + +static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, + enum v4l2_buf_type type) +{ + if (V4L2_TYPE_IS_OUTPUT(type)) + return &ctx->q_data[MTK_Q_DATA_SRC]; + + return &ctx->q_data[MTK_Q_DATA_DST]; +} + +/* + * This function tries to clean all display buffers, the buffers will return + * in display order. + * Note the buffers returned from codec driver may still be in driver's + * reference list. + */ +static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx) +{ + struct vdec_fb *disp_frame_buffer = NULL; + struct mtk_video_dec_buf *dstbuf; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + if (vdec_if_get_param(ctx, + GET_PARAM_DISP_FRAME_BUFFER, + &disp_frame_buffer)) { + mtk_v4l2_err("[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", + ctx->id); + return NULL; + } + + if (disp_frame_buffer == NULL) { + mtk_v4l2_debug(3, "No display frame buffer"); + return NULL; + } + + dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf, + frame_buffer); + mutex_lock(&ctx->lock); + if (dstbuf->used) { + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, + ctx->picinfo.y_bs_sz); + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, + ctx->picinfo.c_bs_sz); + + dstbuf->ready_to_display = true; + + mtk_v4l2_debug(2, + "[%d]status=%x queue id=%d to done_list %d", + ctx->id, disp_frame_buffer->status, + dstbuf->vb.vb2_buf.index, + dstbuf->queued_in_vb2); + + v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE); + ctx->decoded_frame_cnt++; + } + mutex_unlock(&ctx->lock); + return &dstbuf->vb.vb2_buf; +} + +/* + * This function tries to clean all capture buffers that are not used as + * reference buffers by codec driver any more + * In this case, we need re-queue buffer to vb2 buffer if user space + * already returns this buffer to v4l2 or this buffer is just the output of + * previous sps/pps/resolution change decode, or do nothing if user + * space still owns this buffer + */ +static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx) +{ + struct mtk_video_dec_buf *dstbuf; + struct vdec_fb *free_frame_buffer = NULL; + + if (vdec_if_get_param(ctx, + GET_PARAM_FREE_FRAME_BUFFER, + &free_frame_buffer)) { + mtk_v4l2_err("[%d] Error!! Cannot get param", ctx->id); + return NULL; + } + if (free_frame_buffer == NULL) { + mtk_v4l2_debug(3, " No free frame buffer"); + return NULL; + } + + mtk_v4l2_debug(3, "[%d] tmp_frame_addr = 0x%p", + ctx->id, free_frame_buffer); + + dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf, + frame_buffer); + + mutex_lock(&ctx->lock); + if (dstbuf->used) { + if ((dstbuf->queued_in_vb2) && + (dstbuf->queued_in_v4l2) && + (free_frame_buffer->status == FB_ST_FREE)) { + /* + * After decode sps/pps or non-display buffer, we don't + * need to return capture buffer to user space, but + * just re-queue this capture buffer to vb2 queue. + * This reduce overheads that dq/q unused capture + * buffer. In this case, queued_in_vb2 = true. + */ + mtk_v4l2_debug(2, + "[%d]status=%x queue id=%d to rdy_queue %d", + ctx->id, free_frame_buffer->status, + dstbuf->vb.vb2_buf.index, + dstbuf->queued_in_vb2); + v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); + } else if ((dstbuf->queued_in_vb2 == false) && + (dstbuf->queued_in_v4l2 == true)) { + /* + * If buffer in v4l2 driver but not in vb2 queue yet, + * and we get this buffer from free_list, it means + * that codec driver do not use this buffer as + * reference buffer anymore. We should q buffer to vb2 + * queue, so later work thread could get this buffer + * for decode. In this case, queued_in_vb2 = false + * means this buffer is not from previous decode + * output. + */ + mtk_v4l2_debug(2, + "[%d]status=%x queue id=%d to rdy_queue", + ctx->id, free_frame_buffer->status, + dstbuf->vb.vb2_buf.index); + v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); + dstbuf->queued_in_vb2 = true; + } else { + /* + * Codec driver do not need to reference this capture + * buffer and this buffer is not in v4l2 driver. + * Then we don't need to do any thing, just add log when + * we need to debug buffer flow. + * When this buffer q from user space, it could + * directly q to vb2 buffer + */ + mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d", + ctx->id, free_frame_buffer->status, + dstbuf->vb.vb2_buf.index, + dstbuf->queued_in_vb2, + dstbuf->queued_in_v4l2); + } + dstbuf->used = false; + } + mutex_unlock(&ctx->lock); + return &dstbuf->vb.vb2_buf; +} + +static void clean_display_buffer(struct mtk_vcodec_ctx *ctx) +{ + struct vb2_buffer *framptr; + + do { + framptr = get_display_buffer(ctx); + } while (framptr); +} + +static void clean_free_buffer(struct mtk_vcodec_ctx *ctx) +{ + struct vb2_buffer *framptr; + + do { + framptr = get_free_buffer(ctx); + } while (framptr); +} + +static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx) +{ + static const struct v4l2_event ev_src_ch = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = + V4L2_EVENT_SRC_CH_RESOLUTION, + }; + + mtk_v4l2_debug(1, "[%d]", ctx->id); + v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); +} + +static void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) +{ + bool res_chg; + int ret = 0; + + ret = vdec_if_decode(ctx, NULL, NULL, &res_chg); + if (ret) + mtk_v4l2_err("DecodeFinal failed, ret=%d", ret); + + clean_display_buffer(ctx); + clean_free_buffer(ctx); +} + +static void mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) +{ + unsigned int dpbsize = 0; + int ret; + + if (vdec_if_get_param(ctx, + GET_PARAM_PIC_INFO, + &ctx->last_decoded_picinfo)) { + mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", + ctx->id); + return; + } + + if (ctx->last_decoded_picinfo.pic_w == 0 || + ctx->last_decoded_picinfo.pic_h == 0 || + ctx->last_decoded_picinfo.buf_w == 0 || + ctx->last_decoded_picinfo.buf_h == 0) { + mtk_v4l2_err("Cannot get correct pic info"); + return; + } + + if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) || + (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)) + return; + + mtk_v4l2_debug(1, + "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", + ctx->id, ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->last_decoded_picinfo.buf_w, + ctx->last_decoded_picinfo.buf_h); + + ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); + if (dpbsize == 0) + mtk_v4l2_err("Incorrect dpb size, ret=%d", ret); + + ctx->dpb_size = dpbsize; +} + +static void mtk_vdec_worker(struct work_struct *work) +{ + struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, + decode_work); + struct mtk_vcodec_dev *dev = ctx->dev; + struct vb2_buffer *src_buf, *dst_buf; + struct mtk_vcodec_mem buf; + struct vdec_fb *pfb; + bool res_chg = false; + int ret; + struct mtk_video_dec_buf *dst_buf_info, *src_buf_info; + struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; + + src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); + if (src_buf == NULL) { + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id); + return; + } + + dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + if (dst_buf == NULL) { + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); + return; + } + + src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf); + src_buf_info = container_of(src_vb2_v4l2, struct mtk_video_dec_buf, vb); + + dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); + dst_buf_info = container_of(dst_vb2_v4l2, struct mtk_video_dec_buf, vb); + + buf.va = vb2_plane_vaddr(src_buf, 0); + buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); + buf.size = (size_t)src_buf->planes[0].bytesused; + if (!buf.va) { + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", + ctx->id, src_buf->index); + return; + } + + pfb = &dst_buf_info->frame_buffer; + pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0); + pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + pfb->base_y.size = ctx->picinfo.y_bs_sz + ctx->picinfo.y_len_sz; + + pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1); + pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1); + pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz; + pfb->status = 0; + mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); + mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", + ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf); + + mtk_v4l2_debug(3, + "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx", + dst_buf->index, pfb, + pfb->base_y.va, &pfb->base_y.dma_addr, + &pfb->base_c.dma_addr, pfb->base_y.size); + + if (src_buf_info->lastframe) { + /* update src buf status */ + src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + src_buf_info->lastframe = false; + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); + + /* update dst buf status */ + dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + dst_buf_info->used = false; + + vdec_if_decode(ctx, NULL, NULL, &res_chg); + clean_display_buffer(ctx); + vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0); + vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0); + v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE); + clean_free_buffer(ctx); + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + return; + } + dst_buf_info->vb.vb2_buf.timestamp + = src_buf_info->vb.vb2_buf.timestamp; + dst_buf_info->vb.timecode + = src_buf_info->vb.timecode; + mutex_lock(&ctx->lock); + dst_buf_info->used = true; + mutex_unlock(&ctx->lock); + src_buf_info->used = true; + + ret = vdec_if_decode(ctx, &buf, pfb, &res_chg); + + if (ret) { + mtk_v4l2_err( + " <===[%d], src_buf[%d]%d sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>", + ctx->id, + src_buf->index, + src_buf_info->lastframe, + buf.size, + src_buf_info->vb.vb2_buf.timestamp, + dst_buf->index, + ret, res_chg); + src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); + } else if (res_chg == false) { + /* + * we only return src buffer with VB2_BUF_STATE_DONE + * when decode success without resolution change + */ + src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); + } + + dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + clean_display_buffer(ctx); + clean_free_buffer(ctx); + + if (!ret && res_chg) { + mtk_vdec_pic_info_update(ctx); + /* + * On encountering a resolution change in the stream. + * The driver must first process and decode all + * remaining buffers from before the resolution change + * point, so call flush decode here + */ + mtk_vdec_flush_decoder(ctx); + /* + * After all buffers containing decoded frames from + * before the resolution change point ready to be + * dequeued on the CAPTURE queue, the driver sends a + * V4L2_EVENT_SOURCE_CHANGE event for source change + * type V4L2_EVENT_SRC_CH_RESOLUTION + */ + mtk_vdec_queue_res_chg_event(ctx); + } + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); +} + +void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx) +{ + mutex_unlock(&ctx->dev->dec_mutex); +} + +void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx) +{ + mutex_lock(&ctx->dev->dec_mutex); +} + +void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx) +{ + vdec_if_deinit(ctx); + ctx->state = MTK_STATE_FREE; +} + +void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) +{ + struct mtk_q_data *q_data; + + ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex; + ctx->fh.m2m_ctx = ctx->m2m_ctx; + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; + INIT_WORK(&ctx->decode_work, mtk_vdec_worker); + ctx->colorspace = V4L2_COLORSPACE_REC709; + ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + ctx->quantization = V4L2_QUANTIZATION_DEFAULT; + ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + q_data = &ctx->q_data[MTK_Q_DATA_SRC]; + memset(q_data, 0, sizeof(struct mtk_q_data)); + q_data->visible_width = DFT_CFG_WIDTH; + q_data->visible_height = DFT_CFG_HEIGHT; + q_data->fmt = &mtk_video_formats[OUT_FMT_IDX]; + q_data->field = V4L2_FIELD_NONE; + + q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT; + q_data->bytesperline[0] = 0; + + q_data = &ctx->q_data[MTK_Q_DATA_DST]; + memset(q_data, 0, sizeof(struct mtk_q_data)); + q_data->visible_width = DFT_CFG_WIDTH; + q_data->visible_height = DFT_CFG_HEIGHT; + q_data->coded_width = DFT_CFG_WIDTH; + q_data->coded_height = DFT_CFG_HEIGHT; + q_data->fmt = &mtk_video_formats[CAP_FMT_IDX]; + q_data->field = V4L2_FIELD_NONE; + + v4l_bound_align_image(&q_data->coded_width, + MTK_VDEC_MIN_W, + MTK_VDEC_MAX_W, 4, + &q_data->coded_height, + MTK_VDEC_MIN_H, + MTK_VDEC_MAX_H, 5, 6); + + q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height; + q_data->bytesperline[0] = q_data->coded_width; + q_data->sizeimage[1] = q_data->sizeimage[0] / 2; + q_data->bytesperline[1] = q_data->coded_width; +} + +static int vidioc_vdec_qbuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct vb2_queue *vq; + struct vb2_buffer *vb; + struct mtk_video_dec_buf *mtkbuf; + struct vb2_v4l2_buffer *vb2_v4l2; + + if (ctx->state == MTK_STATE_ABORT) { + mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", + ctx->id); + return -EIO; + } + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type); + vb = vq->bufs[buf->index]; + vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); + mtkbuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); + + if ((buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && + (buf->m.planes[0].bytesused == 0)) { + mtkbuf->lastframe = true; + mtk_v4l2_debug(1, "[%d] (%d) id=%d lastframe=%d (%d,%d, %d) vb=%p", + ctx->id, buf->type, buf->index, + mtkbuf->lastframe, buf->bytesused, + buf->m.planes[0].bytesused, buf->length, + vb); + } + + return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); +} + +static int vidioc_vdec_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + + if (ctx->state == MTK_STATE_ABORT) { + mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error", + ctx->id); + return -EIO; + } + + return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); +} + +static int vidioc_vdec_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + strlcpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver)); + strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); + strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); + + return 0; +} + +static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_EOS: + return v4l2_event_subscribe(fh, sub, 2, NULL); + case V4L2_EVENT_SOURCE_CHANGE: + return v4l2_src_change_event_subscribe(fh, sub); + default: + return v4l2_ctrl_subscribe_event(fh, sub); + } +} + +static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_video_fmt *fmt) +{ + struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; + int i; + + pix_fmt_mp->field = V4L2_FIELD_NONE; + + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + pix_fmt_mp->num_planes = 1; + pix_fmt_mp->plane_fmt[0].bytesperline = 0; + } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + int tmp_w, tmp_h; + + pix_fmt_mp->height = clamp(pix_fmt_mp->height, + MTK_VDEC_MIN_H, + MTK_VDEC_MAX_H); + pix_fmt_mp->width = clamp(pix_fmt_mp->width, + MTK_VDEC_MIN_W, + MTK_VDEC_MAX_W); + + /* + * Find next closer width align 64, heign align 64, size align + * 64 rectangle + * Note: This only get default value, the real HW needed value + * only available when ctx in MTK_STATE_HEADER state + */ + tmp_w = pix_fmt_mp->width; + tmp_h = pix_fmt_mp->height; + v4l_bound_align_image(&pix_fmt_mp->width, + MTK_VDEC_MIN_W, + MTK_VDEC_MAX_W, 6, + &pix_fmt_mp->height, + MTK_VDEC_MIN_H, + MTK_VDEC_MAX_H, 6, 9); + + if (pix_fmt_mp->width < tmp_w && + (pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W) + pix_fmt_mp->width += 64; + if (pix_fmt_mp->height < tmp_h && + (pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H) + pix_fmt_mp->height += 64; + + mtk_v4l2_debug(0, + "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d", + tmp_w, tmp_h, pix_fmt_mp->width, + pix_fmt_mp->height, + pix_fmt_mp->width * pix_fmt_mp->height); + + pix_fmt_mp->num_planes = fmt->num_planes; + pix_fmt_mp->plane_fmt[0].sizeimage = + pix_fmt_mp->width * pix_fmt_mp->height; + pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width; + + if (pix_fmt_mp->num_planes == 2) { + pix_fmt_mp->plane_fmt[1].sizeimage = + (pix_fmt_mp->width * pix_fmt_mp->height) / 2; + pix_fmt_mp->plane_fmt[1].bytesperline = + pix_fmt_mp->width; + } + } + + for (i = 0; i < pix_fmt_mp->num_planes; i++) + memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0, + sizeof(pix_fmt_mp->plane_fmt[0].reserved)); + + pix_fmt_mp->flags = 0; + memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved)); + return 0; +} + +static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_video_fmt *fmt; + + fmt = mtk_vdec_find_format(f); + if (!fmt) { + f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; + fmt = mtk_vdec_find_format(f); + } + + return vidioc_try_fmt(f, fmt); +} + +static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; + struct mtk_video_fmt *fmt; + + fmt = mtk_vdec_find_format(f); + if (!fmt) { + f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; + fmt = mtk_vdec_find_format(f); + } + + if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { + mtk_v4l2_err("sizeimage of output format must be given"); + return -EINVAL; + } + + return vidioc_try_fmt(f, fmt); +} + +static int vidioc_vdec_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct mtk_q_data *q_data; + + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + q_data = &ctx->q_data[MTK_Q_DATA_DST]; + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + s->r.left = 0; + s->r.top = 0; + s->r.width = ctx->picinfo.pic_w; + s->r.height = ctx->picinfo.pic_h; + break; + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + s->r.left = 0; + s->r.top = 0; + s->r.width = ctx->picinfo.buf_w; + s->r.height = ctx->picinfo.buf_h; + break; + case V4L2_SEL_TGT_COMPOSE: + if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) { + /* set to default value if header info not ready yet*/ + s->r.left = 0; + s->r.top = 0; + s->r.width = q_data->visible_width; + s->r.height = q_data->visible_height; + } + break; + default: + return -EINVAL; + } + + if (ctx->state < MTK_STATE_HEADER) { + /* set to default value if header info not ready yet*/ + s->r.left = 0; + s->r.top = 0; + s->r.width = q_data->visible_width; + s->r.height = q_data->visible_height; + return 0; + } + + return 0; +} + +static int vidioc_vdec_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE: + s->r.left = 0; + s->r.top = 0; + s->r.width = ctx->picinfo.pic_w; + s->r.height = ctx->picinfo.pic_h; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int vidioc_vdec_s_fmt(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct v4l2_pix_format_mplane *pix_mp; + struct mtk_q_data *q_data; + int ret = 0; + struct mtk_video_fmt *fmt; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + + q_data = mtk_vdec_get_q_data(ctx, f->type); + if (!q_data) + return -EINVAL; + + pix_mp = &f->fmt.pix_mp; + if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && + vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) { + mtk_v4l2_err("out_q_ctx buffers already requested"); + ret = -EBUSY; + } + + if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && + vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) { + mtk_v4l2_err("cap_q_ctx buffers already requested"); + ret = -EBUSY; + } + + fmt = mtk_vdec_find_format(f); + if (fmt == NULL) { + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + f->fmt.pix.pixelformat = + mtk_video_formats[OUT_FMT_IDX].fourcc; + fmt = mtk_vdec_find_format(f); + } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + f->fmt.pix.pixelformat = + mtk_video_formats[CAP_FMT_IDX].fourcc; + fmt = mtk_vdec_find_format(f); + } + } + + q_data->fmt = fmt; + vidioc_try_fmt(f, q_data->fmt); + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q_data->coded_width = pix_mp->width; + q_data->coded_height = pix_mp->height; + + ctx->colorspace = f->fmt.pix_mp.colorspace; + ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; + ctx->quantization = f->fmt.pix_mp.quantization; + ctx->xfer_func = f->fmt.pix_mp.xfer_func; + + if (ctx->state == MTK_STATE_FREE) { + ret = vdec_if_init(ctx, q_data->fmt->fourcc); + if (ret) { + mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d", + ctx->id, ret); + return -EINVAL; + } + ctx->state = MTK_STATE_INIT; + } + } + + return 0; +} + +static int vidioc_enum_framesizes(struct file *file, void *priv, + struct v4l2_frmsizeenum *fsize) +{ + int i = 0; + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + + if (fsize->index != 0) + return -EINVAL; + + for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) { + if (fsize->pixel_format != mtk_vdec_framesizes[i].fourcc) + continue; + + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise = mtk_vdec_framesizes[i].stepwise; + if (!(ctx->dev->dec_capability & + VCODEC_CAPABILITY_4K_DISABLED)) { + mtk_v4l2_debug(3, "4K is enabled"); + fsize->stepwise.max_width = + VCODEC_DEC_4K_CODED_WIDTH; + fsize->stepwise.max_height = + VCODEC_DEC_4K_CODED_HEIGHT; + } + mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d", + ctx->dev->dec_capability, + fsize->stepwise.min_width, + fsize->stepwise.max_width, + fsize->stepwise.step_width, + fsize->stepwise.min_height, + fsize->stepwise.max_height, + fsize->stepwise.step_height); + return 0; + } + + return -EINVAL; +} + +static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) +{ + struct mtk_video_fmt *fmt; + int i, j = 0; + + for (i = 0; i < NUM_FORMATS; i++) { + if (output_queue && (mtk_video_formats[i].type != MTK_FMT_DEC)) + continue; + if (!output_queue && + (mtk_video_formats[i].type != MTK_FMT_FRAME)) + continue; + + if (j == f->index) + break; + ++j; + } + + if (i == NUM_FORMATS) + return -EINVAL; + + fmt = &mtk_video_formats[i]; + f->pixelformat = fmt->fourcc; + + return 0; +} + +static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, + struct v4l2_fmtdesc *f) +{ + return vidioc_enum_fmt(f, false); +} + +static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return vidioc_enum_fmt(f, true); +} + +static int vidioc_vdec_g_fmt(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct vb2_queue *vq; + struct mtk_q_data *q_data; + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + if (!vq) { + mtk_v4l2_err("no vb2 queue for type=%d", f->type); + return -EINVAL; + } + + q_data = mtk_vdec_get_q_data(ctx, f->type); + + pix_mp->field = V4L2_FIELD_NONE; + pix_mp->colorspace = ctx->colorspace; + pix_mp->ycbcr_enc = ctx->ycbcr_enc; + pix_mp->quantization = ctx->quantization; + pix_mp->xfer_func = ctx->xfer_func; + + if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && + (ctx->state >= MTK_STATE_HEADER)) { + /* Until STREAMOFF is called on the CAPTURE queue + * (acknowledging the event), the driver operates as if + * the resolution hasn't changed yet. + * So we just return picinfo yet, and update picinfo in + * stop_streaming hook function + */ + q_data->sizeimage[0] = ctx->picinfo.y_bs_sz + + ctx->picinfo.y_len_sz; + q_data->sizeimage[1] = ctx->picinfo.c_bs_sz + + ctx->picinfo.c_len_sz; + q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w; + q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w; + q_data->coded_width = ctx->picinfo.buf_w; + q_data->coded_height = ctx->picinfo.buf_h; + + /* + * Width and height are set to the dimensions + * of the movie, the buffer is bigger and + * further processing stages should crop to this + * rectangle. + */ + pix_mp->width = q_data->coded_width; + pix_mp->height = q_data->coded_height; + + /* + * Set pixelformat to the format in which mt vcodec + * outputs the decoded frame + */ + pix_mp->num_planes = q_data->fmt->num_planes; + pix_mp->pixelformat = q_data->fmt->fourcc; + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; + pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1]; + pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1]; + + } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + /* + * This is run on OUTPUT + * The buffer contains compressed image + * so width and height have no meaning. + * Assign value here to pass v4l2-compliance test + */ + pix_mp->width = q_data->visible_width; + pix_mp->height = q_data->visible_height; + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; + pix_mp->pixelformat = q_data->fmt->fourcc; + pix_mp->num_planes = q_data->fmt->num_planes; + } else { + pix_mp->width = q_data->coded_width; + pix_mp->height = q_data->coded_height; + pix_mp->num_planes = q_data->fmt->num_planes; + pix_mp->pixelformat = q_data->fmt->fourcc; + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; + pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1]; + pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1]; + + mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!", + ctx->id, f->type, ctx->state); + } + + return 0; +} + +static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, + unsigned int *nplanes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq); + struct mtk_q_data *q_data; + unsigned int i; + + q_data = mtk_vdec_get_q_data(ctx, vq->type); + + if (q_data == NULL) { + mtk_v4l2_err("vq->type=%d err\n", vq->type); + return -EINVAL; + } + + if (*nplanes) { + for (i = 0; i < *nplanes; i++) { + if (sizes[i] < q_data->sizeimage[i]) + return -EINVAL; + } + } else { + if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + *nplanes = 2; + else + *nplanes = 1; + + for (i = 0; i < *nplanes; i++) + sizes[i] = q_data->sizeimage[i]; + } + + mtk_v4l2_debug(1, + "[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ", + ctx->id, vq->type, *nplanes, *nbuffers, + sizes[0], sizes[1]); + + return 0; +} + +static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) +{ + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_q_data *q_data; + int i; + + mtk_v4l2_debug(3, "[%d] (%d) id=%d", + ctx->id, vb->vb2_queue->type, vb->index); + + q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type); + + for (i = 0; i < q_data->fmt->num_planes; i++) { + if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { + mtk_v4l2_err("data will not fit into plane %d (%lu < %d)", + i, vb2_plane_size(vb, i), + q_data->sizeimage[i]); + } + } + + return 0; +} + +static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_buffer *src_buf; + struct mtk_vcodec_mem src_mem; + bool res_chg = false; + int ret = 0; + unsigned int dpbsize = 1; + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb, + struct vb2_v4l2_buffer, vb2_buf); + struct mtk_video_dec_buf *buf = container_of(vb2_v4l2, + struct mtk_video_dec_buf, vb); + + mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", + ctx->id, vb->vb2_queue->type, + vb->index, vb); + /* + * check if this buffer is ready to be used after decode + */ + if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + mutex_lock(&ctx->lock); + if (buf->used == false) { + v4l2_m2m_buf_queue(ctx->m2m_ctx, + to_vb2_v4l2_buffer(vb)); + buf->queued_in_vb2 = true; + buf->queued_in_v4l2 = true; + buf->ready_to_display = false; + } else { + buf->queued_in_vb2 = false; + buf->queued_in_v4l2 = true; + buf->ready_to_display = false; + } + mutex_unlock(&ctx->lock); + return; + } + + v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); + + if (ctx->state != MTK_STATE_INIT) { + mtk_v4l2_debug(3, "[%d] already init driver %d", + ctx->id, ctx->state); + return; + } + + src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); + if (!src_buf) { + mtk_v4l2_err("No src buffer"); + return; + } + + src_mem.va = vb2_plane_vaddr(src_buf, 0); + src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); + src_mem.size = (size_t)src_buf->planes[0].bytesused; + mtk_v4l2_debug(2, + "[%d] buf id=%d va=%p dma=%pad size=%zx", + ctx->id, src_buf->index, + src_mem.va, &src_mem.dma_addr, + src_mem.size); + + ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg); + if (ret || !res_chg) { + /* + * fb == NULL menas to parse SPS/PPS header or + * resolution info in src_mem. Decode can fail + * if there is no SPS header or picture info + * in bs + */ + int log_level = ret ? 0 : 1; + + src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), + VB2_BUF_STATE_DONE); + mtk_v4l2_debug(log_level, + "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", + ctx->id, src_buf->index, + src_mem.size, ret, res_chg); + return; + } + + if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) { + mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", + ctx->id); + return; + } + + ctx->last_decoded_picinfo = ctx->picinfo; + ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = + ctx->picinfo.y_bs_sz + + ctx->picinfo.y_len_sz; + ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = + ctx->picinfo.buf_w; + ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] = + ctx->picinfo.c_bs_sz + + ctx->picinfo.c_len_sz; + ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] = ctx->picinfo.buf_w; + mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", + ctx->id, + ctx->picinfo.buf_w, ctx->picinfo.buf_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->q_data[MTK_Q_DATA_DST].sizeimage[0], + ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]); + + ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); + if (dpbsize == 0) + mtk_v4l2_err("[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret); + + ctx->dpb_size = dpbsize; + ctx->state = MTK_STATE_HEADER; + mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size); +} + +static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) +{ + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2_v4l2; + struct mtk_video_dec_buf *buf; + + if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return; + + vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); + buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); + mutex_lock(&ctx->lock); + buf->queued_in_v4l2 = false; + buf->queued_in_vb2 = false; + mutex_unlock(&ctx->lock); +} + +static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb, + struct vb2_v4l2_buffer, vb2_buf); + struct mtk_video_dec_buf *buf = container_of(vb2_v4l2, + struct mtk_video_dec_buf, vb); + + if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + buf->used = false; + buf->ready_to_display = false; + buf->queued_in_v4l2 = false; + } else { + buf->lastframe = false; + } + + return 0; +} + +static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + + if (ctx->state == MTK_STATE_FLUSH) + ctx->state = MTK_STATE_HEADER; + + return 0; +} + +static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) +{ + struct vb2_buffer *src_buf = NULL, *dst_buf = NULL; + struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); + + mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d", + ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt); + + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), + VB2_BUF_STATE_ERROR); + return; + } + + if (ctx->state >= MTK_STATE_HEADER) { + + /* Until STREAMOFF is called on the CAPTURE queue + * (acknowledging the event), the driver operates + * as if the resolution hasn't changed yet, i.e. + * VIDIOC_G_FMT< etc. return previous resolution. + * So we update picinfo here + */ + ctx->picinfo = ctx->last_decoded_picinfo; + + mtk_v4l2_debug(2, + "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", + ctx->id, ctx->last_decoded_picinfo.pic_w, + ctx->last_decoded_picinfo.pic_h, + ctx->picinfo.pic_w, ctx->picinfo.pic_h, + ctx->last_decoded_picinfo.buf_w, + ctx->last_decoded_picinfo.buf_h); + + mtk_vdec_flush_decoder(ctx); + } + ctx->state = MTK_STATE_FLUSH; + + while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { + vb2_set_plane_payload(dst_buf, 0, 0); + vb2_set_plane_payload(dst_buf, 1, 0); + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), + VB2_BUF_STATE_ERROR); + } + +} + +static void m2mops_vdec_device_run(void *priv) +{ + struct mtk_vcodec_ctx *ctx = priv; + struct mtk_vcodec_dev *dev = ctx->dev; + + queue_work(dev->decode_workqueue, &ctx->decode_work); +} + +static int m2mops_vdec_job_ready(void *m2m_priv) +{ + struct mtk_vcodec_ctx *ctx = m2m_priv; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + + if (ctx->state == MTK_STATE_ABORT) + return 0; + + if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) || + (ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h)) + return 0; + + if (ctx->state != MTK_STATE_HEADER) + return 0; + + return 1; +} + +static void m2mops_vdec_job_abort(void *priv) +{ + struct mtk_vcodec_ctx *ctx = priv; + + ctx->state = MTK_STATE_ABORT; +} + +static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); + int ret = 0; + + switch (ctrl->id) { + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + if (ctx->state >= MTK_STATE_HEADER) { + ctrl->val = ctx->dpb_size; + } else { + mtk_v4l2_debug(0, "Seqinfo not ready"); + ctrl->val = 0; + } + break; + default: + ret = -EINVAL; + } + return ret; +} + +static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = { + .g_volatile_ctrl = mtk_vdec_g_v_ctrl, +}; + +int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) +{ + struct v4l2_ctrl *ctrl; + + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1); + + ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, + &mtk_vcodec_dec_ctrl_ops, + V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, + 0, 32, 1, 1); + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + + if (ctx->ctrl_hdl.error) { + mtk_v4l2_err("Adding control failed %d", + ctx->ctrl_hdl.error); + return ctx->ctrl_hdl.error; + } + + v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + return 0; +} + +static void m2mops_vdec_lock(void *m2m_priv) +{ + struct mtk_vcodec_ctx *ctx = m2m_priv; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + mutex_lock(&ctx->dev->dev_mutex); +} + +static void m2mops_vdec_unlock(void *m2m_priv) +{ + struct mtk_vcodec_ctx *ctx = m2m_priv; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + mutex_unlock(&ctx->dev->dev_mutex); +} + +const struct v4l2_m2m_ops mtk_vdec_m2m_ops = { + .device_run = m2mops_vdec_device_run, + .job_ready = m2mops_vdec_job_ready, + .job_abort = m2mops_vdec_job_abort, + .lock = m2mops_vdec_lock, + .unlock = m2mops_vdec_unlock, +}; + +static const struct vb2_ops mtk_vdec_vb2_ops = { + .queue_setup = vb2ops_vdec_queue_setup, + .buf_prepare = vb2ops_vdec_buf_prepare, + .buf_queue = vb2ops_vdec_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .buf_init = vb2ops_vdec_buf_init, + .buf_finish = vb2ops_vdec_buf_finish, + .start_streaming = vb2ops_vdec_start_streaming, + .stop_streaming = vb2ops_vdec_stop_streaming, +}; + +const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = { + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_qbuf = vidioc_vdec_qbuf, + .vidioc_dqbuf = vidioc_vdec_dqbuf, + + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane, + + .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt, + .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt, + .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt, + .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt, + + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + + .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane, + .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + + .vidioc_querycap = vidioc_vdec_querycap, + .vidioc_subscribe_event = vidioc_vdec_subscribe_evt, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_g_selection = vidioc_vdec_g_selection, + .vidioc_s_selection = vidioc_vdec_s_selection, +}; + +int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct mtk_vcodec_ctx *ctx = priv; + int ret = 0; + + mtk_v4l2_debug(3, "[%d]", ctx->id); + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; + src_vq->drv_priv = ctx; + src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf); + src_vq->ops = &mtk_vdec_vb2_ops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->dev->dev_mutex; + src_vq->dev = &ctx->dev->plat_dev->dev; + + ret = vb2_queue_init(src_vq); + if (ret) { + mtk_v4l2_err("Failed to initialize videobuf2 queue(output)"); + return ret; + } + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; + dst_vq->drv_priv = ctx; + dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf); + dst_vq->ops = &mtk_vdec_vb2_ops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->dev->dev_mutex; + dst_vq->dev = &ctx->dev->plat_dev->dev; + + ret = vb2_queue_init(dst_vq); + if (ret) { + vb2_queue_release(src_vq); + mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)"); + } + + return ret; +} diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h new file mode 100644 index 000000000000..362f5a85762e --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MTK_VCODEC_DEC_H_ +#define _MTK_VCODEC_DEC_H_ + +#include +#include + +#define VCODEC_CAPABILITY_4K_DISABLED 0x10 +#define VCODEC_DEC_4K_CODED_WIDTH 4096U +#define VCODEC_DEC_4K_CODED_HEIGHT 2304U +#define MTK_VDEC_MAX_W 2048U +#define MTK_VDEC_MAX_H 1088U + +#define MTK_VDEC_IRQ_STATUS_DEC_SUCCESS 0x10000 + +/** + * struct vdec_fb - decoder frame buffer + * @base_y : Y plane memory info + * @base_c : C plane memory info + * @status : frame buffer status (vdec_fb_status) + */ +struct vdec_fb { + struct mtk_vcodec_mem base_y; + struct mtk_vcodec_mem base_c; + unsigned int status; +}; + +/** + * struct mtk_video_dec_buf - Private data related to each VB2 buffer. + * @b: VB2 buffer + * @list: link list + * @used: Capture buffer contain decoded frame data and keep in + * codec data structure + * @ready_to_display: Capture buffer not display yet + * @queued_in_vb2: Capture buffer is queue in vb2 + * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 + * queue yet + * @lastframe: Intput buffer is last buffer - EOS + * @frame_buffer: Decode status, and buffer information of Capture buffer + * + * Note : These status information help us track and debug buffer state + */ +struct mtk_video_dec_buf { + struct vb2_v4l2_buffer vb; + struct list_head list; + + bool used; + bool ready_to_display; + bool queued_in_vb2; + bool queued_in_v4l2; + bool lastframe; + struct vdec_fb frame_buffer; +}; + +extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops; +extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops; + + +/* + * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to + * get/release lock before/after access decoder hw. + * mtk_vdec_lock get decoder hw lock and set curr_ctx + * to ctx instance that get lock + */ +void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx); +void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx); +int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq); +void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx); +void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx); +int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx); + + +#endif /* _MTK_VCODEC_DEC_H_ */ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c new file mode 100644 index 000000000000..70aa99329ce5 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec.h" +#include "mtk_vcodec_dec_pm.h" +#include "mtk_vcodec_intr.h" +#include "mtk_vcodec_util.h" +#include "mtk_vpu.h" + +#define VDEC_HW_ACTIVE 0x10 +#define VDEC_IRQ_CFG 0x11 +#define VDEC_IRQ_CLR 0x10 +#define VDEC_IRQ_CFG_REG 0xa4 + +module_param(mtk_v4l2_dbg_level, int, 0644); +module_param(mtk_vcodec_dbg, bool, 0644); + +/* Wake up context wait_queue */ +static void wake_up_ctx(struct mtk_vcodec_ctx *ctx) +{ + ctx->int_cond = 1; + wake_up_interruptible(&ctx->queue); +} + +static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) +{ + struct mtk_vcodec_dev *dev = priv; + struct mtk_vcodec_ctx *ctx; + u32 cg_status = 0; + unsigned int dec_done_status = 0; + void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] + + VDEC_IRQ_CFG_REG; + + ctx = mtk_vcodec_get_curr_ctx(dev); + + /* check if HW active or not */ + cg_status = readl(dev->reg_base[0]); + if ((cg_status & VDEC_HW_ACTIVE) != 0) { + mtk_v4l2_err("DEC ISR, VDEC active is not 0x0 (0x%08x)", + cg_status); + return IRQ_HANDLED; + } + + dec_done_status = readl(vdec_misc_addr); + ctx->irq_status = dec_done_status; + if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) != + MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) + return IRQ_HANDLED; + + /* clear interrupt */ + writel((readl(vdec_misc_addr) | VDEC_IRQ_CFG), + dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG); + writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR), + dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG); + + wake_up_ctx(ctx); + + mtk_v4l2_debug(3, + "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x", + ctx->id, dec_done_status); + + return IRQ_HANDLED; +} + +static void mtk_vcodec_dec_reset_handler(void *priv) +{ + struct mtk_vcodec_dev *dev = priv; + struct mtk_vcodec_ctx *ctx; + + mtk_v4l2_err("Watchdog timeout!!"); + + mutex_lock(&dev->dev_mutex); + list_for_each_entry(ctx, &dev->ctx_list, list) { + ctx->state = MTK_STATE_ABORT; + mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ERROR", + ctx->id); + } + mutex_unlock(&dev->dev_mutex); +} + +static int fops_vcodec_open(struct file *file) +{ + struct mtk_vcodec_dev *dev = video_drvdata(file); + struct mtk_vcodec_ctx *ctx = NULL; + int ret = 0; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + mutex_lock(&dev->dev_mutex); + ctx->id = dev->id_counter++; + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + INIT_LIST_HEAD(&ctx->list); + ctx->dev = dev; + init_waitqueue_head(&ctx->queue); + mutex_init(&ctx->lock); + + ctx->type = MTK_INST_DECODER; + ret = mtk_vcodec_dec_ctrls_setup(ctx); + if (ret) { + mtk_v4l2_err("Failed to setup mt vcodec controls"); + goto err_ctrls_setup; + } + ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx, + &mtk_vcodec_dec_queue_init); + if (IS_ERR((__force void *)ctx->m2m_ctx)) { + ret = PTR_ERR((__force void *)ctx->m2m_ctx); + mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)", + ret); + goto err_m2m_ctx_init; + } + mtk_vcodec_dec_set_default_params(ctx); + + if (v4l2_fh_is_singular(&ctx->fh)) { + mtk_vcodec_dec_pw_on(&dev->pm); + /* + * vpu_load_firmware checks if it was loaded already and + * does nothing in that case + */ + ret = vpu_load_firmware(dev->vpu_plat_dev); + if (ret < 0) { + /* + * Return 0 if downloading firmware successfully, + * otherwise it is failed + */ + mtk_v4l2_err("vpu_load_firmware failed!"); + goto err_load_fw; + } + + dev->dec_capability = + vpu_get_vdec_hw_capa(dev->vpu_plat_dev); + mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability); + } + + list_add(&ctx->list, &dev->ctx_list); + + mutex_unlock(&dev->dev_mutex); + mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev), + ctx->id); + return ret; + + /* Deinit when failure occurred */ +err_load_fw: + v4l2_m2m_ctx_release(ctx->m2m_ctx); +err_m2m_ctx_init: + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); +err_ctrls_setup: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + kfree(ctx); + mutex_unlock(&dev->dev_mutex); + + return ret; +} + +static int fops_vcodec_release(struct file *file) +{ + struct mtk_vcodec_dev *dev = video_drvdata(file); + struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data); + + mtk_v4l2_debug(0, "[%d] decoder", ctx->id); + mutex_lock(&dev->dev_mutex); + + /* + * Call v4l2_m2m_ctx_release before mtk_vcodec_dec_release. First, it + * makes sure the worker thread is not running after vdec_if_deinit. + * Second, the decoder will be flushed and all the buffers will be + * returned in stop_streaming. + */ + v4l2_m2m_ctx_release(ctx->m2m_ctx); + mtk_vcodec_dec_release(ctx); + + if (v4l2_fh_is_singular(&ctx->fh)) + mtk_vcodec_dec_pw_off(&dev->pm); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + + list_del_init(&ctx->list); + kfree(ctx); + mutex_unlock(&dev->dev_mutex); + return 0; +} + +static const struct v4l2_file_operations mtk_vcodec_fops = { + .owner = THIS_MODULE, + .open = fops_vcodec_open, + .release = fops_vcodec_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static int mtk_vcodec_probe(struct platform_device *pdev) +{ + struct mtk_vcodec_dev *dev; + struct video_device *vfd_dec; + struct resource *res; + int i, ret; + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + INIT_LIST_HEAD(&dev->ctx_list); + dev->plat_dev = pdev; + + dev->vpu_plat_dev = vpu_get_plat_device(dev->plat_dev); + if (dev->vpu_plat_dev == NULL) { + mtk_v4l2_err("[VPU] vpu device in not ready"); + return -EPROBE_DEFER; + } + + vpu_wdt_reg_handler(dev->vpu_plat_dev, mtk_vcodec_dec_reset_handler, + dev, VPU_RST_DEC); + + ret = mtk_vcodec_init_dec_pm(dev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to get mt vcodec clock source"); + return ret; + } + + for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (res == NULL) { + dev_err(&pdev->dev, "get memory resource failed."); + ret = -ENXIO; + goto err_res; + } + dev->reg_base[i] = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR((__force void *)dev->reg_base[i])) { + ret = PTR_ERR((__force void *)dev->reg_base); + goto err_res; + } + mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res == NULL) { + dev_err(&pdev->dev, "failed to get irq resource"); + ret = -ENOENT; + goto err_res; + } + + dev->dec_irq = platform_get_irq(pdev, 0); + ret = devm_request_irq(&pdev->dev, dev->dec_irq, + mtk_vcodec_dec_irq_handler, 0, pdev->name, dev); + if (ret) { + dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)", + dev->dec_irq, + ret); + goto err_res; + } + + disable_irq(dev->dec_irq); + mutex_init(&dev->dec_mutex); + mutex_init(&dev->dev_mutex); + spin_lock_init(&dev->irqlock); + + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", + "[/MTK_V4L2_VDEC]"); + + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); + if (ret) { + mtk_v4l2_err("v4l2_device_register err=%d", ret); + goto err_res; + } + + init_waitqueue_head(&dev->queue); + + vfd_dec = video_device_alloc(); + if (!vfd_dec) { + mtk_v4l2_err("Failed to allocate video device"); + ret = -ENOMEM; + goto err_dec_alloc; + } + vfd_dec->fops = &mtk_vcodec_fops; + vfd_dec->ioctl_ops = &mtk_vdec_ioctl_ops; + vfd_dec->release = video_device_release; + vfd_dec->lock = &dev->dev_mutex; + vfd_dec->v4l2_dev = &dev->v4l2_dev; + vfd_dec->vfl_dir = VFL_DIR_M2M; + vfd_dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | + V4L2_CAP_STREAMING; + + snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s", + MTK_VCODEC_DEC_NAME); + video_set_drvdata(vfd_dec, dev); + dev->vfd_dec = vfd_dec; + platform_set_drvdata(pdev, dev); + + dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops); + if (IS_ERR((__force void *)dev->m2m_dev_dec)) { + mtk_v4l2_err("Failed to init mem2mem dec device"); + ret = PTR_ERR((__force void *)dev->m2m_dev_dec); + goto err_dec_mem_init; + } + + dev->decode_workqueue = + alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME, + WQ_MEM_RECLAIM | WQ_FREEZABLE); + if (!dev->decode_workqueue) { + mtk_v4l2_err("Failed to create decode workqueue"); + ret = -EINVAL; + goto err_event_workq; + } + + ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 0); + if (ret) { + mtk_v4l2_err("Failed to register video device"); + goto err_dec_reg; + } + + mtk_v4l2_debug(0, "decoder registered as /dev/video%d", + vfd_dec->num); + + return 0; + +err_dec_reg: + destroy_workqueue(dev->decode_workqueue); +err_event_workq: + v4l2_m2m_release(dev->m2m_dev_dec); +err_dec_mem_init: + video_unregister_device(vfd_dec); +err_dec_alloc: + v4l2_device_unregister(&dev->v4l2_dev); +err_res: + mtk_vcodec_release_dec_pm(dev); + return ret; +} + +static const struct of_device_id mtk_vcodec_match[] = { + {.compatible = "mediatek,mt8173-vcodec-dec",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, mtk_vcodec_match); + +static int mtk_vcodec_dec_remove(struct platform_device *pdev) +{ + struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev); + + flush_workqueue(dev->decode_workqueue); + destroy_workqueue(dev->decode_workqueue); + if (dev->m2m_dev_dec) + v4l2_m2m_release(dev->m2m_dev_dec); + + if (dev->vfd_dec) + video_unregister_device(dev->vfd_dec); + + v4l2_device_unregister(&dev->v4l2_dev); + mtk_vcodec_release_dec_pm(dev); + return 0; +} + +static struct platform_driver mtk_vcodec_dec_driver = { + .probe = mtk_vcodec_probe, + .remove = mtk_vcodec_dec_remove, + .driver = { + .name = MTK_VCODEC_DEC_NAME, + .of_match_table = mtk_vcodec_match, + }, +}; + +module_platform_driver(mtk_vcodec_dec_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver"); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c new file mode 100644 index 000000000000..18182f5676d8 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "mtk_vcodec_dec_pm.h" +#include "mtk_vcodec_util.h" +#include "mtk_vpu.h" + +int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) +{ + struct device_node *node; + struct platform_device *pdev; + struct device *dev; + struct mtk_vcodec_pm *pm; + int ret = 0; + + pdev = mtkdev->plat_dev; + pm = &mtkdev->pm; + pm->mtkdev = mtkdev; + dev = &pdev->dev; + node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0); + if (!node) { + mtk_v4l2_err("of_parse_phandle mediatek,larb fail!"); + return -1; + } + + pdev = of_find_device_by_node(node); + if (WARN_ON(!pdev)) { + of_node_put(node); + return -1; + } + pm->larbvdec = &pdev->dev; + pdev = mtkdev->plat_dev; + pm->dev = &pdev->dev; + + pm->vcodecpll = devm_clk_get(&pdev->dev, "vcodecpll"); + if (IS_ERR(pm->vcodecpll)) { + mtk_v4l2_err("devm_clk_get vcodecpll fail"); + ret = PTR_ERR(pm->vcodecpll); + } + + pm->univpll_d2 = devm_clk_get(&pdev->dev, "univpll_d2"); + if (IS_ERR(pm->univpll_d2)) { + mtk_v4l2_err("devm_clk_get univpll_d2 fail"); + ret = PTR_ERR(pm->univpll_d2); + } + + pm->clk_cci400_sel = devm_clk_get(&pdev->dev, "clk_cci400_sel"); + if (IS_ERR(pm->clk_cci400_sel)) { + mtk_v4l2_err("devm_clk_get clk_cci400_sel fail"); + ret = PTR_ERR(pm->clk_cci400_sel); + } + + pm->vdec_sel = devm_clk_get(&pdev->dev, "vdec_sel"); + if (IS_ERR(pm->vdec_sel)) { + mtk_v4l2_err("devm_clk_get vdec_sel fail"); + ret = PTR_ERR(pm->vdec_sel); + } + + pm->vdecpll = devm_clk_get(&pdev->dev, "vdecpll"); + if (IS_ERR(pm->vdecpll)) { + mtk_v4l2_err("devm_clk_get vdecpll fail"); + ret = PTR_ERR(pm->vdecpll); + } + + pm->vencpll = devm_clk_get(&pdev->dev, "vencpll"); + if (IS_ERR(pm->vencpll)) { + mtk_v4l2_err("devm_clk_get vencpll fail"); + ret = PTR_ERR(pm->vencpll); + } + + pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel"); + if (IS_ERR(pm->venc_lt_sel)) { + mtk_v4l2_err("devm_clk_get venc_lt_sel fail"); + ret = PTR_ERR(pm->venc_lt_sel); + } + + pm->vdec_bus_clk_src = devm_clk_get(&pdev->dev, "vdec_bus_clk_src"); + if (IS_ERR(pm->vdec_bus_clk_src)) { + mtk_v4l2_err("devm_clk_get vdec_bus_clk_src"); + ret = PTR_ERR(pm->vdec_bus_clk_src); + } + + pm_runtime_enable(&pdev->dev); + + return ret; +} + +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) +{ + pm_runtime_disable(dev->pm.dev); +} + +void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) +{ + int ret; + + ret = pm_runtime_get_sync(pm->dev); + if (ret) + mtk_v4l2_err("pm_runtime_get_sync fail %d", ret); +} + +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) +{ + int ret; + + ret = pm_runtime_put_sync(pm->dev); + if (ret) + mtk_v4l2_err("pm_runtime_put_sync fail %d", ret); +} + +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) +{ + int ret; + + ret = clk_set_rate(pm->vcodecpll, 1482 * 1000000); + if (ret) + mtk_v4l2_err("clk_set_rate vcodecpll fail %d", ret); + + ret = clk_set_rate(pm->vencpll, 800 * 1000000); + if (ret) + mtk_v4l2_err("clk_set_rate vencpll fail %d", ret); + + ret = clk_prepare_enable(pm->vcodecpll); + if (ret) + mtk_v4l2_err("clk_prepare_enable vcodecpll fail %d", ret); + + ret = clk_prepare_enable(pm->vencpll); + if (ret) + mtk_v4l2_err("clk_prepare_enable vencpll fail %d", ret); + + ret = clk_prepare_enable(pm->vdec_bus_clk_src); + if (ret) + mtk_v4l2_err("clk_prepare_enable vdec_bus_clk_src fail %d", + ret); + + ret = clk_prepare_enable(pm->venc_lt_sel); + if (ret) + mtk_v4l2_err("clk_prepare_enable venc_lt_sel fail %d", ret); + + ret = clk_set_parent(pm->venc_lt_sel, pm->vdec_bus_clk_src); + if (ret) + mtk_v4l2_err("clk_set_parent venc_lt_sel vdec_bus_clk_src fail %d", + ret); + + ret = clk_prepare_enable(pm->univpll_d2); + if (ret) + mtk_v4l2_err("clk_prepare_enable univpll_d2 fail %d", ret); + + ret = clk_prepare_enable(pm->clk_cci400_sel); + if (ret) + mtk_v4l2_err("clk_prepare_enable clk_cci400_sel fail %d", ret); + + ret = clk_set_parent(pm->clk_cci400_sel, pm->univpll_d2); + if (ret) + mtk_v4l2_err("clk_set_parent clk_cci400_sel univpll_d2 fail %d", + ret); + + ret = clk_prepare_enable(pm->vdecpll); + if (ret) + mtk_v4l2_err("clk_prepare_enable vdecpll fail %d", ret); + + ret = clk_prepare_enable(pm->vdec_sel); + if (ret) + mtk_v4l2_err("clk_prepare_enable vdec_sel fail %d", ret); + + ret = clk_set_parent(pm->vdec_sel, pm->vdecpll); + if (ret) + mtk_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret); + + ret = mtk_smi_larb_get(pm->larbvdec); + if (ret) + mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret); + +} + +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) +{ + mtk_smi_larb_put(pm->larbvdec); + clk_disable_unprepare(pm->vdec_sel); + clk_disable_unprepare(pm->vdecpll); + clk_disable_unprepare(pm->univpll_d2); + clk_disable_unprepare(pm->clk_cci400_sel); + clk_disable_unprepare(pm->venc_lt_sel); + clk_disable_unprepare(pm->vdec_bus_clk_src); + clk_disable_unprepare(pm->vencpll); + clk_disable_unprepare(pm->vcodecpll); +} diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h new file mode 100644 index 000000000000..86a7825353e3 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MTK_VCODEC_DEC_PM_H_ +#define _MTK_VCODEC_DEC_PM_H_ + +#include "mtk_vcodec_drv.h" + +int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); + +void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); +void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); +void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm); +void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm); + +#endif /* _MTK_VCODEC_DEC_PM_H_ */ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index c8eaa41c00e6..d7eb8ef855d2 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -22,13 +22,13 @@ #include #include #include - +#include "mtk_vcodec_util.h" #define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv" +#define MTK_VCODEC_DEC_NAME "mtk-vcodec-dec" #define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc" #define MTK_PLATFORM_STR "platform:mt8173" - #define MTK_VCODEC_MAX_PLANES 3 #define MTK_V4L2_BENCHMARK 0 #define WAIT_INTR_TIMEOUT_MS 1000 @@ -179,6 +179,9 @@ struct mtk_enc_params { * struct mtk_vcodec_pm - Power management data structure */ struct mtk_vcodec_pm { + struct clk *vdec_bus_clk_src; + struct clk *vencpll; + struct clk *vcodecpll; struct clk *univpll_d2; struct clk *clk_cci400_sel; @@ -195,6 +198,32 @@ struct mtk_vcodec_pm { struct mtk_vcodec_dev *mtkdev; }; +/** + * struct vdec_pic_info - picture size information + * @pic_w: picture width + * @pic_h: picture height + * @buf_w: picture buffer width (64 aligned up from pic_w) + * @buf_h: picture buffer heiht (64 aligned up from pic_h) + * @y_bs_sz: Y bitstream size + * @c_bs_sz: CbCr bitstream size + * @y_len_sz: additional size required to store decompress information for y + * plane + * @c_len_sz: additional size required to store decompress information for cbcr + * plane + * E.g. suppose picture size is 176x144, + * buffer size will be aligned to 176x160. + */ +struct vdec_pic_info { + unsigned int pic_w; + unsigned int pic_h; + unsigned int buf_w; + unsigned int buf_h; + unsigned int y_bs_sz; + unsigned int c_bs_sz; + unsigned int y_len_sz; + unsigned int c_len_sz; +}; + /** * struct mtk_vcodec_ctx - Context (instance) private data. * @@ -209,9 +238,12 @@ struct mtk_vcodec_pm { * @state: state of the context * @param_change: indicate encode parameter type * @enc_params: encoding parameters + * @dec_if: hooked decoder driver interface * @enc_if: hoooked encoder driver interface * @drv_handle: driver handle for specific decode/encode instance * + * @picinfo: store picture info after header parsing + * @dpb_size: store dpb count after header parsing * @int_cond: variable used by the waitqueue * @int_type: type of the last interrupt * @queue: waitqueue that can be used to wait for this context to @@ -219,12 +251,16 @@ struct mtk_vcodec_pm { * @irq_status: irq status * * @ctrl_hdl: handler for v4l2 framework + * @decode_work: worker for the decoding * @encode_work: worker for the encoding + * @last_decoded_picinfo: pic information get from latest decode * * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization * @xfer_func: enum v4l2_xfer_func, colorspace transfer function + * @lock: protect variables accessed by V4L2 threads and worker thread such as + * mtk_video_dec_buf. */ struct mtk_vcodec_ctx { enum mtk_instance_type type; @@ -239,28 +275,40 @@ struct mtk_vcodec_ctx { enum mtk_encode_param param_change; struct mtk_enc_params enc_params; + const struct vdec_common_if *dec_if; const struct venc_common_if *enc_if; unsigned long drv_handle; + struct vdec_pic_info picinfo; + int dpb_size; + int int_cond; int int_type; wait_queue_head_t queue; unsigned int irq_status; struct v4l2_ctrl_handler ctrl_hdl; + struct work_struct decode_work; struct work_struct encode_work; + struct vdec_pic_info last_decoded_picinfo; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; enum v4l2_quantization quantization; enum v4l2_xfer_func xfer_func; + + int decoded_frame_cnt; + struct mutex lock; + }; /** * struct mtk_vcodec_dev - driver data * @v4l2_dev: V4L2 device to register video devices for. + * @vfd_dec: Video device for decoder * @vfd_enc: Video device for encoder. * + * @m2m_dev_dec: m2m device for decoder * @m2m_dev_enc: m2m device for encoder. * @plat_dev: platform device * @vpu_plat_dev: mtk vpu platform device @@ -271,7 +319,6 @@ struct mtk_vcodec_ctx { * @reg_base: Mapped address of MTK Vcodec registers. * * @id_counter: used to identify current opened instance - * @num_instances: counter of active MTK Vcodec instances * * @encode_workqueue: encode work queue * @@ -280,9 +327,11 @@ struct mtk_vcodec_ctx { * @dev_mutex: video_device lock * @queue: waitqueue for waiting for completion of device commands * + * @dec_irq: decoder irq resource * @enc_irq: h264 encoder irq resource * @enc_lt_irq: vp8 encoder irq resource * + * @dec_mutex: decoder hardware lock * @enc_mutex: encoder hardware lock. * * @pm: power management control @@ -291,8 +340,10 @@ struct mtk_vcodec_ctx { */ struct mtk_vcodec_dev { struct v4l2_device v4l2_dev; + struct video_device *vfd_dec; struct video_device *vfd_enc; + struct v4l2_m2m_dev *m2m_dev_dec; struct v4l2_m2m_dev *m2m_dev_enc; struct platform_device *plat_dev; struct platform_device *vpu_plat_dev; @@ -302,18 +353,19 @@ struct mtk_vcodec_dev { void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE]; unsigned long id_counter; - int num_instances; + struct workqueue_struct *decode_workqueue; struct workqueue_struct *encode_workqueue; - int int_cond; int int_type; struct mutex dev_mutex; wait_queue_head_t queue; + int dec_irq; int enc_irq; int enc_lt_irq; + struct mutex dec_mutex; struct mutex enc_mutex; struct mtk_vcodec_pm pm; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 5cd2151431bf..aa81f3ce9463 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -188,7 +188,6 @@ static int fops_vcodec_open(struct file *file) mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ", ctx->id, ctx, ctx->m2m_ctx); - dev->num_instances++; list_add(&ctx->list, &dev->ctx_list); mutex_unlock(&dev->dev_mutex); @@ -218,18 +217,13 @@ static int fops_vcodec_release(struct file *file) mtk_v4l2_debug(1, "[%d] encoder", ctx->id); mutex_lock(&dev->dev_mutex); - /* - * Call v4l2_m2m_ctx_release to make sure the worker thread is not - * running after venc_if_deinit. - */ - v4l2_m2m_ctx_release(ctx->m2m_ctx); mtk_vcodec_enc_release(ctx); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + v4l2_m2m_ctx_release(ctx->m2m_ctx); list_del_init(&ctx->list); - dev->num_instances--; kfree(ctx); mutex_unlock(&dev->dev_mutex); return 0; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c index 52e7e5c9afa0..113b2097f061 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c @@ -30,8 +30,7 @@ int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx, int command, timeout_jiff = msecs_to_jiffies(timeout_ms); ret = wait_event_interruptible_timeout(*waitqueue, - (ctx->int_cond && - (ctx->int_type == command)), + ctx->int_cond, timeout_jiff); if (!ret) { diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c index 5e3651372a3c..46768c056193 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c @@ -81,14 +81,37 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data, return; } - dma_free_coherent(dev, size, mem->va, mem->dma_addr); - mem->va = NULL; - mem->dma_addr = 0; - mem->size = 0; - mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va); mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id, (unsigned long)mem->dma_addr); mtk_v4l2_debug(3, "[%d] size = 0x%lx", ctx->id, size); + + dma_free_coherent(dev, size, mem->va, mem->dma_addr); + mem->va = NULL; + mem->dma_addr = 0; + mem->size = 0; } EXPORT_SYMBOL(mtk_vcodec_mem_free); + +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev, + struct mtk_vcodec_ctx *ctx) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->irqlock, flags); + dev->curr_ctx = ctx; + spin_unlock_irqrestore(&dev->irqlock, flags); +} +EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx); + +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev) +{ + unsigned long flags; + struct mtk_vcodec_ctx *ctx; + + spin_lock_irqsave(&dev->irqlock, flags); + ctx = dev->curr_ctx; + spin_unlock_irqrestore(&dev->irqlock, flags); + return ctx; +} +EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h index d6345fc04840..7d55975d3185 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h @@ -26,6 +26,7 @@ struct mtk_vcodec_mem { }; struct mtk_vcodec_ctx; +struct mtk_vcodec_dev; extern int mtk_v4l2_dbg_level; extern bool mtk_vcodec_dbg; @@ -84,4 +85,8 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data, struct mtk_vcodec_mem *mem); void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data, struct mtk_vcodec_mem *mem); +void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev, + struct mtk_vcodec_ctx *ctx); +struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev); + #endif /* _MTK_VCODEC_UTIL_H_ */ diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_base.h b/drivers/media/platform/mtk-vcodec/vdec_drv_base.h new file mode 100644 index 000000000000..ca022e3300d7 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_base.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _VDEC_DRV_BASE_ +#define _VDEC_DRV_BASE_ + +#include "mtk_vcodec_drv.h" + + +struct vdec_common_if { + /** + * (*init)() - initialize decode driver + * @ctx : [in] mtk v4l2 context + * @h_vdec : [out] driver handle + */ + int (*init)(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec); + + /** + * (*decode)() - trigger decode + * @h_vdec : [in] driver handle + * @bs : [in] input bitstream + * @fb : [in] frame buffer to store decoded frame + * @res_chg : [out] resolution change happen + */ + int (*decode)(unsigned long h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg); + + /** + * (*get_param)() - get driver's parameter + * @h_vdec : [in] driver handle + * @type : [in] input parameter type + * @out : [out] buffer to store query result + */ + int (*get_param)(unsigned long h_vdec, enum vdec_get_param_type type, + void *out); + + /** + * (*deinit)() - deinitialize driver. + * @h_vdec : [in] driver handle to be deinit + */ + void (*deinit)(unsigned long h_vdec); +}; + +#endif diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c new file mode 100644 index 000000000000..3cb04ef45144 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include "vdec_drv_if.h" +#include "mtk_vcodec_dec.h" +#include "vdec_drv_base.h" +#include "mtk_vcodec_dec_pm.h" +#include "mtk_vpu.h" + + +int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) +{ + int ret = 0; + + switch (fourcc) { + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_VP8: + default: + return -EINVAL; + } + + mtk_vdec_lock(ctx); + mtk_vcodec_dec_clock_on(&ctx->dev->pm); + ret = ctx->dec_if->init(ctx, &ctx->drv_handle); + mtk_vcodec_dec_clock_off(&ctx->dev->pm); + mtk_vdec_unlock(ctx); + + return ret; +} + +int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + int ret = 0; + + if (bs) { + if ((bs->dma_addr & 63) != 0) { + mtk_v4l2_err("bs dma_addr should 64 byte align"); + return -EINVAL; + } + } + + if (fb) { + if (((fb->base_y.dma_addr & 511) != 0) || + ((fb->base_c.dma_addr & 511) != 0)) { + mtk_v4l2_err("frame buffer dma_addr should 512 byte align"); + return -EINVAL; + } + } + + if (ctx->drv_handle == 0) + return -EIO; + + mtk_vdec_lock(ctx); + + mtk_vcodec_set_curr_ctx(ctx->dev, ctx); + mtk_vcodec_dec_clock_on(&ctx->dev->pm); + enable_irq(ctx->dev->dec_irq); + ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg); + disable_irq(ctx->dev->dec_irq); + mtk_vcodec_dec_clock_off(&ctx->dev->pm); + mtk_vcodec_set_curr_ctx(ctx->dev, NULL); + + mtk_vdec_unlock(ctx); + + return ret; +} + +int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type, + void *out) +{ + int ret = 0; + + if (ctx->drv_handle == 0) + return -EIO; + + mtk_vdec_lock(ctx); + ret = ctx->dec_if->get_param(ctx->drv_handle, type, out); + mtk_vdec_unlock(ctx); + + return ret; +} + +void vdec_if_deinit(struct mtk_vcodec_ctx *ctx) +{ + if (ctx->drv_handle == 0) + return; + + mtk_vdec_lock(ctx); + mtk_vcodec_dec_clock_on(&ctx->dev->pm); + ctx->dec_if->deinit(ctx->drv_handle); + mtk_vcodec_dec_clock_off(&ctx->dev->pm); + mtk_vdec_unlock(ctx); + + ctx->drv_handle = 0; +} diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h new file mode 100644 index 000000000000..db6b5205ffb1 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _VDEC_DRV_IF_H_ +#define _VDEC_DRV_IF_H_ + +#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_dec.h" +#include "mtk_vcodec_util.h" + + +/** + * struct vdec_fb_status - decoder frame buffer status + * @FB_ST_NORMAL : initial state + * @FB_ST_DISPLAY : frmae buffer is ready to be displayed + * @FB_ST_FREE : frame buffer is not used by decoder any more + */ +enum vdec_fb_status { + FB_ST_NORMAL = 0, + FB_ST_DISPLAY = (1 << 0), + FB_ST_FREE = (1 << 1) +}; + +/* For GET_PARAM_DISP_FRAME_BUFFER and GET_PARAM_FREE_FRAME_BUFFER, + * the caller does not own the returned buffer. The buffer will not be + * released before vdec_if_deinit. + * GET_PARAM_DISP_FRAME_BUFFER : get next displayable frame buffer, + * struct vdec_fb** + * GET_PARAM_FREE_FRAME_BUFFER : get non-referenced framebuffer, vdec_fb** + * GET_PARAM_PIC_INFO : get picture info, struct vdec_pic_info* + * GET_PARAM_CROP_INFO : get crop info, struct v4l2_crop* + * GET_PARAM_DPB_SIZE : get dpb size, unsigned int* + */ +enum vdec_get_param_type { + GET_PARAM_DISP_FRAME_BUFFER, + GET_PARAM_FREE_FRAME_BUFFER, + GET_PARAM_PIC_INFO, + GET_PARAM_CROP_INFO, + GET_PARAM_DPB_SIZE +}; + +/** + * struct vdec_fb_node - decoder frame buffer node + * @list : list to hold this node + * @fb : point to frame buffer (vdec_fb), fb could point to frame buffer and + * working buffer this is for maintain buffers in different state + */ +struct vdec_fb_node { + struct list_head list; + struct vdec_fb *fb; +}; + +/** + * vdec_if_init() - initialize decode driver + * @ctx : [in] v4l2 context + * @fourcc : [in] video format fourcc, V4L2_PIX_FMT_H264/VP8/VP9.. + */ +int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc); + +/** + * vdec_if_deinit() - deinitialize decode driver + * @ctx : [in] v4l2 context + * + */ +void vdec_if_deinit(struct mtk_vcodec_ctx *ctx); + +/** + * vdec_if_decode() - trigger decode + * @ctx : [in] v4l2 context + * @bs : [in] input bitstream + * @fb : [in] frame buffer to store decoded frame, when null menas parse + * header only + * @res_chg : [out] resolution change happens if current bs have different + * picture width/height + * Note: To flush the decoder when reaching EOF, set input bitstream as NULL. + */ +int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg); + +/** + * vdec_if_get_param() - get driver's parameter + * @ctx : [in] v4l2 context + * @type : [in] input parameter type + * @out : [out] buffer to store query result + */ +int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type, + void *out); + +#endif diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h new file mode 100644 index 000000000000..5a8a629f4ac9 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * + * This program is free software; you can redistribute it and/or + * modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _VDEC_IPI_MSG_H_ +#define _VDEC_IPI_MSG_H_ + +/** + * enum vdec_ipi_msgid - message id between AP and VPU + * @AP_IPIMSG_XXX : AP to VPU cmd message id + * @VPU_IPIMSG_XXX_ACK : VPU ack AP cmd message id + */ +enum vdec_ipi_msgid { + AP_IPIMSG_DEC_INIT = 0xA000, + AP_IPIMSG_DEC_START = 0xA001, + AP_IPIMSG_DEC_END = 0xA002, + AP_IPIMSG_DEC_DEINIT = 0xA003, + AP_IPIMSG_DEC_RESET = 0xA004, + + VPU_IPIMSG_DEC_INIT_ACK = 0xB000, + VPU_IPIMSG_DEC_START_ACK = 0xB001, + VPU_IPIMSG_DEC_END_ACK = 0xB002, + VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003, + VPU_IPIMSG_DEC_RESET_ACK = 0xB004, +}; + +/** + * struct vdec_ap_ipi_cmd - generic AP to VPU ipi command format + * @msg_id : vdec_ipi_msgid + * @vpu_inst_addr : VPU decoder instance address + */ +struct vdec_ap_ipi_cmd { + uint32_t msg_id; + uint32_t vpu_inst_addr; +}; + +/** + * struct vdec_vpu_ipi_ack - generic VPU to AP ipi command format + * @msg_id : vdec_ipi_msgid + * @status : VPU exeuction result + * @ap_inst_addr : AP video decoder instance address + */ +struct vdec_vpu_ipi_ack { + uint32_t msg_id; + int32_t status; + uint64_t ap_inst_addr; +}; + +/** + * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT + * @msg_id : AP_IPIMSG_DEC_INIT + * @reserved : Reserved field + * @ap_inst_addr : AP video decoder instance address + */ +struct vdec_ap_ipi_init { + uint32_t msg_id; + uint32_t reserved; + uint64_t ap_inst_addr; +}; + +/** + * struct vdec_ap_ipi_dec_start - for AP_IPIMSG_DEC_START + * @msg_id : AP_IPIMSG_DEC_START + * @vpu_inst_addr : VPU decoder instance address + * @data : Header info + * H264 decoder [0]:buf_sz [1]:nal_start + * VP8 decoder [0]:width/height + * VP9 decoder [0]:profile, [1][2] width/height + * @reserved : Reserved field + */ +struct vdec_ap_ipi_dec_start { + uint32_t msg_id; + uint32_t vpu_inst_addr; + uint32_t data[3]; + uint32_t reserved; +}; + +/** + * struct vdec_vpu_ipi_init_ack - for VPU_IPIMSG_DEC_INIT_ACK + * @msg_id : VPU_IPIMSG_DEC_INIT_ACK + * @status : VPU exeuction result + * @ap_inst_addr : AP vcodec_vpu_inst instance address + * @vpu_inst_addr : VPU decoder instance address + */ +struct vdec_vpu_ipi_init_ack { + uint32_t msg_id; + int32_t status; + uint64_t ap_inst_addr; + uint32_t vpu_inst_addr; +}; + +#endif diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c new file mode 100644 index 000000000000..5a24c51aebb7 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mtk_vcodec_drv.h" +#include "mtk_vcodec_util.h" +#include "vdec_ipi_msg.h" +#include "vdec_vpu_if.h" + +static void handle_init_ack_msg(struct vdec_vpu_ipi_init_ack *msg) +{ + struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) + (unsigned long)msg->ap_inst_addr; + + mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); + + /* mapping VPU address to kernel virtual address */ + /* the content in vsi is initialized to 0 in VPU */ + vpu->vsi = vpu_mapping_dm_addr(vpu->dev, msg->vpu_inst_addr); + vpu->inst_addr = msg->vpu_inst_addr; + + mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr); +} + +/* + * This function runs in interrupt context and it means there's an IPI MSG + * from VPU. + */ +void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) +{ + struct vdec_vpu_ipi_ack *msg = data; + struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) + (unsigned long)msg->ap_inst_addr; + + mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id); + + if (msg->status == 0) { + switch (msg->msg_id) { + case VPU_IPIMSG_DEC_INIT_ACK: + handle_init_ack_msg(data); + break; + + case VPU_IPIMSG_DEC_START_ACK: + case VPU_IPIMSG_DEC_END_ACK: + case VPU_IPIMSG_DEC_DEINIT_ACK: + case VPU_IPIMSG_DEC_RESET_ACK: + break; + + default: + mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id); + break; + } + } + + mtk_vcodec_debug(vpu, "- id=%X", msg->msg_id); + vpu->failure = msg->status; + vpu->signaled = 1; +} + +static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) +{ + int err; + uint32_t msg_id = *(uint32_t *)msg; + + mtk_vcodec_debug(vpu, "id=%X", msg_id); + + vpu->failure = 0; + vpu->signaled = 0; + + err = vpu_ipi_send(vpu->dev, vpu->id, msg, len); + if (err) { + mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d", + vpu->id, msg_id, err); + return err; + } + + return vpu->failure; +} + +static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id) +{ + struct vdec_ap_ipi_cmd msg; + int err = 0; + + mtk_vcodec_debug(vpu, "+ id=%X", msg_id); + + memset(&msg, 0, sizeof(msg)); + msg.msg_id = msg_id; + msg.vpu_inst_addr = vpu->inst_addr; + + err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg)); + mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err); + return err; +} + +int vpu_dec_init(struct vdec_vpu_inst *vpu) +{ + struct vdec_ap_ipi_init msg; + int err; + + mtk_vcodec_debug_enter(vpu); + + init_waitqueue_head(&vpu->wq); + + err = vpu_ipi_register(vpu->dev, vpu->id, vpu->handler, "vdec", NULL); + if (err != 0) { + mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err); + return err; + } + + memset(&msg, 0, sizeof(msg)); + msg.msg_id = AP_IPIMSG_DEC_INIT; + msg.ap_inst_addr = (unsigned long)vpu; + + mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu); + + err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); + mtk_vcodec_debug(vpu, "- ret=%d", err); + return err; +} + +int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) +{ + struct vdec_ap_ipi_dec_start msg; + int i; + int err = 0; + + mtk_vcodec_debug_enter(vpu); + + if (len > ARRAY_SIZE(msg.data)) { + mtk_vcodec_err(vpu, "invalid len = %d\n", len); + return -EINVAL; + } + + memset(&msg, 0, sizeof(msg)); + msg.msg_id = AP_IPIMSG_DEC_START; + msg.vpu_inst_addr = vpu->inst_addr; + + for (i = 0; i < len; i++) + msg.data[i] = data[i]; + + err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); + mtk_vcodec_debug(vpu, "- ret=%d", err); + return err; +} + +int vpu_dec_end(struct vdec_vpu_inst *vpu) +{ + return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END); +} + +int vpu_dec_deinit(struct vdec_vpu_inst *vpu) +{ + return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT); +} + +int vpu_dec_reset(struct vdec_vpu_inst *vpu) +{ + return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_RESET); +} diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h new file mode 100644 index 000000000000..0dc9ed01fffe --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _VDEC_VPU_IF_H_ +#define _VDEC_VPU_IF_H_ + +#include "mtk_vpu.h" + +/** + * struct vdec_vpu_inst - VPU instance for video codec + * @ipi_id : ipi id for each decoder + * @vsi : driver structure allocated by VPU side and shared to AP side + * for control and info share + * @failure : VPU execution result status, 0: success, others: fail + * @inst_addr : VPU decoder instance address + * @signaled : 1 - Host has received ack message from VPU, 0 - not received + * @ctx : context for v4l2 layer integration + * @dev : platform device of VPU + * @wq : wait queue to wait VPU message ack + * @handler : ipi handler for each decoder + */ +struct vdec_vpu_inst { + enum ipi_id id; + void *vsi; + int32_t failure; + uint32_t inst_addr; + unsigned int signaled; + struct mtk_vcodec_ctx *ctx; + struct platform_device *dev; + wait_queue_head_t wq; + ipi_handler_t handler; +}; + +/** + * vpu_dec_init - init decoder instance and allocate required resource in VPU. + * + * @vpu: instance for vdec_vpu_inst + */ +int vpu_dec_init(struct vdec_vpu_inst *vpu); + +/** + * vpu_dec_start - start decoding, basically the function will be invoked once + * every frame. + * + * @vpu : instance for vdec_vpu_inst + * @data: meta data to pass bitstream info to VPU decoder + * @len : meta data length + */ +int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len); + +/** + * vpu_dec_end - end decoding, basically the function will be invoked once + * when HW decoding done interrupt received successfully. The + * decoder in VPU will continute to do referene frame management + * and check if there is a new decoded frame available to display. + * + * @vpu : instance for vdec_vpu_inst + */ +int vpu_dec_end(struct vdec_vpu_inst *vpu); + +/** + * vpu_dec_deinit - deinit decoder instance and resource freed in VPU. + * + * @vpu: instance for vdec_vpu_inst + */ +int vpu_dec_deinit(struct vdec_vpu_inst *vpu); + +/** + * vpu_dec_reset - reset decoder, use for flush decoder when end of stream or + * seek. Remainig non displayed frame will be pushed to display. + * + * @vpu: instance for vdec_vpu_inst + */ +int vpu_dec_reset(struct vdec_vpu_inst *vpu); + +/** + * vpu_dec_ipi_handler - Handler for VPU ipi message. + * + * @data: ipi message + * @len : length of ipi message + * @priv: callback private data which is passed by decoder when register. + */ +void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv); + +#endif -- cgit v1.2.3 From 487a4c51c1e99ea1949520af565c0d29bf3164f6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Oct 2016 10:55:52 -0200 Subject: [media] mtk-vcodec: fix some smatch warnings Fix this bug: drivers/media/platform/mtk-vcodec/vdec_drv_if.c:38 vdec_if_init() info: ignoring unreachable code. With is indeed a real problem that prevents the driver to work! While here, also remove an used var, as reported by smatch: drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c: In function 'mtk_vcodec_init_dec_pm': drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c:29:17: warning: variable 'dev' set but not used [-Wunused-but-set-variable] struct device *dev; ^~~ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 2 -- drivers/media/platform/mtk-vcodec/vdec_drv_if.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 18182f5676d8..79ca03ac449c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -26,14 +26,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) { struct device_node *node; struct platform_device *pdev; - struct device *dev; struct mtk_vcodec_pm *pm; int ret = 0; pdev = mtkdev->plat_dev; pm = &mtkdev->pm; pm->mtkdev = mtkdev; - dev = &pdev->dev; node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0); if (!node) { mtk_v4l2_err("of_parse_phandle mediatek,larb fail!"); diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c index 3cb04ef45144..9813b2ffd5fa 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -31,6 +31,7 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) switch (fourcc) { case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_VP8: + break; default: return -EINVAL; } -- cgit v1.2.3 From a7b131751cd364a85ec115cb0a1898db6663ee8e Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:19:55 -0300 Subject: [media] vcodec: mediatek: Add Mediatek H264 Video Decoder Drive Add h264 decoder driver for MT8173 Signed-off-by: PC Chen Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/Makefile | 3 +- .../media/platform/mtk-vcodec/vdec/vdec_h264_if.c | 507 +++++++++++++++++++++ drivers/media/platform/mtk-vcodec/vdec_drv_if.c | 3 + 3 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index b54e82372b4c..58243edb3865 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -3,7 +3,8 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ mtk-vcodec-enc.o \ mtk-vcodec-common.o -mtk-vcodec-dec-y := mtk_vcodec_dec_drv.o \ +mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ + mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ mtk_vcodec_dec.o \ diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c new file mode 100644 index 000000000000..57a842ff3097 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: PC Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "../vdec_drv_if.h" +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_vpu_if.h" +#include "../vdec_drv_base.h" + +#define NAL_NON_IDR_SLICE 0x01 +#define NAL_IDR_SLICE 0x05 +#define NAL_H264_PPS 0x08 +#define NAL_TYPE(value) ((value) & 0x1F) + +#define BUF_PREDICTION_SZ (32 * 1024) + +#define MB_UNIT_LEN 16 + +/* motion vector size (bytes) for every macro block */ +#define HW_MB_STORE_SZ 64 + +#define H264_MAX_FB_NUM 17 +#define HDR_PARSING_BUF_SZ 1024 + +/** + * struct h264_fb - h264 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 h264_fb { + uint64_t vdec_fb_va; + uint64_t y_fb_dma; + uint64_t c_fb_dma; + int32_t poc; + uint32_t reserved; +}; + +/** + * struct h264_ring_fb_list - ring frame buffer list + * @fb_list : frame buffer arrary + * @read_idx : read index + * @write_idx : write index + * @count : buffer count in list + */ +struct h264_ring_fb_list { + struct h264_fb fb_list[H264_MAX_FB_NUM]; + unsigned int read_idx; + unsigned int write_idx; + unsigned int count; + unsigned int reserved; +}; + +/** + * struct vdec_h264_dec_info - decode information + * @dpb_sz : decoding picture buffer size + * @resolution_changed : resoltion change happen + * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer + * @reserved : for 8 bytes alignment + * @bs_dma : Input bit-stream buffer dma address + * @y_fb_dma : Y frame buffer dma address + * @c_fb_dma : C frame buffer dma address + * @vdec_fb_va : VDEC frame buffer struct virtual address + */ +struct vdec_h264_dec_info { + uint32_t dpb_sz; + uint32_t resolution_changed; + uint32_t realloc_mv_buf; + uint32_t reserved; + uint64_t bs_dma; + uint64_t y_fb_dma; + uint64_t c_fb_dma; + uint64_t vdec_fb_va; +}; + +/** + * struct vdec_h264_vsi - shared memory for decode information exchange + * between VPU and Host. + * The memory is allocated by VPU then mapping to Host + * in vpu_dec_init() and freed in vpu_dec_deinit() + * by VPU. + * AP-W/R : AP is writer/reader on this item + * VPU-W/R: VPU is write/reader on this item + * @hdr_buf : Header parsing buffer (AP-W, VPU-R) + * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R) + * @mv_buf_dma : HW working motion vector buffer dma address (AP-W, VPU-R) + * @list_free : free frame buffer ring list (AP-W/R, VPU-W) + * @list_disp : display frame buffer ring list (AP-R, VPU-W) + * @dec : decode information (AP-R, VPU-W) + * @pic : picture information (AP-R, VPU-W) + * @crop : crop information (AP-R, VPU-W) + */ +struct vdec_h264_vsi { + unsigned char hdr_buf[HDR_PARSING_BUF_SZ]; + uint64_t pred_buf_dma; + uint64_t mv_buf_dma[H264_MAX_FB_NUM]; + struct h264_ring_fb_list list_free; + struct h264_ring_fb_list list_disp; + struct vdec_h264_dec_info dec; + struct vdec_pic_info pic; + struct v4l2_rect crop; +}; + +/** + * struct vdec_h264_inst - h264 decoder instance + * @num_nalu : how many nalus be decoded + * @ctx : point to mtk_vcodec_ctx + * @pred_buf : HW working predication buffer + * @mv_buf : HW working motion vector buffer + * @vpu : VPU instance + * @vsi : VPU shared information + */ +struct vdec_h264_inst { + unsigned int num_nalu; + struct mtk_vcodec_ctx *ctx; + struct mtk_vcodec_mem pred_buf; + struct mtk_vcodec_mem mv_buf[H264_MAX_FB_NUM]; + struct vdec_vpu_inst vpu; + struct vdec_h264_vsi *vsi; +}; + +static unsigned int get_mv_buf_size(unsigned int width, unsigned int height) +{ + return HW_MB_STORE_SZ * (width/MB_UNIT_LEN) * (height/MB_UNIT_LEN); +} + +static int allocate_predication_buf(struct vdec_h264_inst *inst) +{ + int err = 0; + + inst->pred_buf.size = BUF_PREDICTION_SZ; + err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf); + if (err) { + mtk_vcodec_err(inst, "failed to allocate ppl buf"); + return err; + } + + inst->vsi->pred_buf_dma = inst->pred_buf.dma_addr; + return 0; +} + +static void free_predication_buf(struct vdec_h264_inst *inst) +{ + struct mtk_vcodec_mem *mem = NULL; + + mtk_vcodec_debug_enter(inst); + + inst->vsi->pred_buf_dma = 0; + mem = &inst->pred_buf; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); +} + +static int alloc_mv_buf(struct vdec_h264_inst *inst, struct vdec_pic_info *pic) +{ + int i; + int err; + struct mtk_vcodec_mem *mem = NULL; + unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h); + + for (i = 0; i < H264_MAX_FB_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; + } + inst->vsi->mv_buf_dma[i] = mem->dma_addr; + } + + return 0; +} + +static void free_mv_buf(struct vdec_h264_inst *inst) +{ + int i; + struct mtk_vcodec_mem *mem = NULL; + + for (i = 0; i < H264_MAX_FB_NUM; i++) { + inst->vsi->mv_buf_dma[i] = 0; + mem = &inst->mv_buf[i]; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + } +} + +static int check_list_validity(struct vdec_h264_inst *inst, bool disp_list) +{ + struct h264_ring_fb_list *list; + + list = disp_list ? &inst->vsi->list_disp : &inst->vsi->list_free; + + if (list->count > H264_MAX_FB_NUM || + list->read_idx >= H264_MAX_FB_NUM || + list->write_idx >= H264_MAX_FB_NUM) { + mtk_vcodec_err(inst, "%s list err: cnt=%d r_idx=%d w_idx=%d", + disp_list ? "disp" : "free", list->count, + list->read_idx, list->write_idx); + return -EINVAL; + } + + return 0; +} + +static void put_fb_to_free(struct vdec_h264_inst *inst, struct vdec_fb *fb) +{ + struct h264_ring_fb_list *list; + + if (fb) { + if (check_list_validity(inst, false)) + return; + + list = &inst->vsi->list_free; + if (list->count == H264_MAX_FB_NUM) { + mtk_vcodec_err(inst, "[FB] put fb free_list full"); + return; + } + + mtk_vcodec_debug(inst, "[FB] put fb into free_list @(%p, %llx)", + fb->base_y.va, (u64)fb->base_y.dma_addr); + + list->fb_list[list->write_idx].vdec_fb_va = (u64)(uintptr_t)fb; + list->write_idx = (list->write_idx == H264_MAX_FB_NUM - 1) ? + 0 : list->write_idx + 1; + list->count++; + } +} + +static void get_pic_info(struct vdec_h264_inst *inst, + struct vdec_pic_info *pic) +{ + *pic = inst->vsi->pic; + mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, + pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); +} + +static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) +{ + cr->left = inst->vsi->crop.left; + cr->top = inst->vsi->crop.top; + cr->width = inst->vsi->crop.width; + cr->height = inst->vsi->crop.height; + + mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); +} + +static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz) +{ + *dpb_sz = inst->vsi->dec.dpb_sz; + mtk_vcodec_debug(inst, "sz=%d", *dpb_sz); +} + +static int vdec_h264_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) +{ + struct vdec_h264_inst *inst = NULL; + int err; + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + inst->ctx = ctx; + + inst->vpu.id = IPI_VDEC_H264; + inst->vpu.dev = ctx->dev->vpu_plat_dev; + inst->vpu.ctx = ctx; + inst->vpu.handler = vpu_dec_ipi_handler; + + err = vpu_dec_init(&inst->vpu); + if (err) { + mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); + goto error_free_inst; + } + + inst->vsi = (struct vdec_h264_vsi *)inst->vpu.vsi; + err = allocate_predication_buf(inst); + if (err) + goto error_deinit; + + mtk_vcodec_debug(inst, "H264 Instance >> %p", inst); + + *h_vdec = (unsigned long)inst; + return 0; + +error_deinit: + vpu_dec_deinit(&inst->vpu); + +error_free_inst: + kfree(inst); + return err; +} + +static void vdec_h264_deinit(unsigned long h_vdec) +{ + struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; + + mtk_vcodec_debug_enter(inst); + + vpu_dec_deinit(&inst->vpu); + free_predication_buf(inst); + free_mv_buf(inst); + + kfree(inst); +} + +static int find_start_code(unsigned char *data, unsigned int data_sz) +{ + if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1) + return 3; + + if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 && + data[3] == 1) + return 4; + + return -1; +} + +static int vdec_h264_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; + struct vdec_vpu_inst *vpu = &inst->vpu; + int nal_start_idx = 0; + int err = 0; + unsigned int nal_start; + unsigned int nal_type; + unsigned char *buf; + unsigned int buf_sz; + unsigned int data[2]; + uint64_t vdec_fb_va = (u64)(uintptr_t)fb; + uint64_t y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; + uint64_t c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; + + mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", + ++inst->num_nalu, y_fb_dma, c_fb_dma, fb); + + /* bs NULL means flush decoder */ + if (bs == NULL) + return vpu_dec_reset(vpu); + + buf = (unsigned char *)bs->va; + buf_sz = bs->size; + nal_start_idx = find_start_code(buf, buf_sz); + if (nal_start_idx < 0) + goto err_free_fb_out; + + nal_start = buf[nal_start_idx]; + nal_type = NAL_TYPE(buf[nal_start_idx]); + mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu, + nal_type); + + if (nal_type == NAL_H264_PPS) { + buf_sz -= nal_start_idx; + if (buf_sz > HDR_PARSING_BUF_SZ) { + err = -EILSEQ; + goto err_free_fb_out; + } + memcpy(inst->vsi->hdr_buf, buf + nal_start_idx, buf_sz); + } + + inst->vsi->dec.bs_dma = (uint64_t)bs->dma_addr; + inst->vsi->dec.y_fb_dma = y_fb_dma; + inst->vsi->dec.c_fb_dma = c_fb_dma; + inst->vsi->dec.vdec_fb_va = vdec_fb_va; + + data[0] = buf_sz; + data[1] = nal_start; + err = vpu_dec_start(vpu, data, 2); + if (err) + goto err_free_fb_out; + + *res_chg = inst->vsi->dec.resolution_changed; + if (*res_chg) { + struct vdec_pic_info pic; + + mtk_vcodec_debug(inst, "- resolution changed -"); + get_pic_info(inst, &pic); + + if (inst->vsi->dec.realloc_mv_buf) { + err = alloc_mv_buf(inst, &pic); + if (err) + goto err_free_fb_out; + } + } + + if (nal_type == NAL_NON_IDR_SLICE || nal_type == NAL_IDR_SLICE) { + /* wait decoder done interrupt */ + err = mtk_vcodec_wait_for_done_ctx(inst->ctx, + MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS); + if (err) + goto err_free_fb_out; + + vpu_dec_end(vpu); + } + + mtk_vcodec_debug(inst, "\n - NALU[%d] type=%d -\n", inst->num_nalu, + nal_type); + return 0; + +err_free_fb_out: + put_fb_to_free(inst, fb); + mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); + return err; +} + +static void vdec_h264_get_fb(struct vdec_h264_inst *inst, + struct h264_ring_fb_list *list, + bool disp_list, struct vdec_fb **out_fb) +{ + struct vdec_fb *fb; + + if (check_list_validity(inst, disp_list)) + return; + + if (list->count == 0) { + mtk_vcodec_debug(inst, "[FB] there is no %s fb", + disp_list ? "disp" : "free"); + *out_fb = NULL; + return; + } + + fb = (struct vdec_fb *) + (uintptr_t)list->fb_list[list->read_idx].vdec_fb_va; + fb->status |= (disp_list ? FB_ST_DISPLAY : FB_ST_FREE); + + *out_fb = fb; + mtk_vcodec_debug(inst, "[FB] get %s fb st=%d poc=%d %llx", + disp_list ? "disp" : "free", + fb->status, list->fb_list[list->read_idx].poc, + list->fb_list[list->read_idx].vdec_fb_va); + + list->read_idx = (list->read_idx == H264_MAX_FB_NUM - 1) ? + 0 : list->read_idx + 1; + list->count--; +} + +static int vdec_h264_get_param(unsigned long h_vdec, + enum vdec_get_param_type type, void *out) +{ + struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; + + switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_h264_get_fb(inst, &inst->vsi->list_disp, true, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + vdec_h264_get_fb(inst, &inst->vsi->list_free, false, out); + break; + + case GET_PARAM_PIC_INFO: + get_pic_info(inst, out); + break; + + case GET_PARAM_DPB_SIZE: + get_dpb_size(inst, out); + break; + + case GET_PARAM_CROP_INFO: + get_crop_info(inst, out); + break; + + default: + mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + return -EINVAL; + } + + return 0; +} + +static struct vdec_common_if vdec_h264_if = { + vdec_h264_init, + vdec_h264_decode, + vdec_h264_get_param, + vdec_h264_deinit, +}; + +struct vdec_common_if *get_h264_dec_comm_if(void); + +struct vdec_common_if *get_h264_dec_comm_if(void) +{ + return &vdec_h264_if; +} diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c index 9813b2ffd5fa..e03f126eb51f 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -23,6 +23,7 @@ #include "mtk_vcodec_dec_pm.h" #include "mtk_vpu.h" +const struct vdec_common_if *get_h264_dec_comm_if(void); int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) { @@ -30,6 +31,8 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) switch (fourcc) { case V4L2_PIX_FMT_H264: + ctx->dec_if = get_h264_dec_comm_if(); + break; case V4L2_PIX_FMT_VP8: break; default: -- cgit v1.2.3 From d1fad85f5af329650d101069ae8f78e3043b8f2b Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:19:56 -0300 Subject: [media] vcodec: mediatek: Add Mediatek VP8 Video Decoder Driver Add vp8 decoder driver for MT8173 [mchehab@s-opensource.org: make checkpatch.pl happy] Signed-off-by: PC Chen Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/Makefile | 1 + .../media/platform/mtk-vcodec/vdec/vdec_vp8_if.c | 634 +++++++++++++++++++++ drivers/media/platform/mtk-vcodec/vdec_drv_if.c | 2 + 3 files changed, 637 insertions(+) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 58243edb3865..7743c81346a8 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ mtk-vcodec-common.o mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ + vdec/vdec_vp8_if.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c new file mode 100644 index 000000000000..6e7a62ae0842 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Jungchang Tsao + * PC Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "../vdec_drv_if.h" +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_vpu_if.h" +#include "../vdec_drv_base.h" + +/* Decoding picture buffer size (3 reference frames plus current frame) */ +#define VP8_DPB_SIZE 4 + +/* HW working buffer size (bytes) */ +#define VP8_WORKING_BUF_SZ (45 * 4096) + +/* HW control register address */ +#define VP8_SEGID_DRAM_ADDR 0x3c +#define VP8_HW_VLD_ADDR 0x93C +#define VP8_HW_VLD_VALUE 0x940 +#define VP8_BSASET 0x100 +#define VP8_BSDSET 0x104 +#define VP8_RW_CKEN_SET 0x0 +#define VP8_RW_DCM_CON 0x18 +#define VP8_WO_VLD_SRST 0x108 +#define VP8_RW_MISC_SYS_SEL 0x84 +#define VP8_RW_MISC_SPEC_CON 0xC8 +#define VP8_WO_VLD_SRST 0x108 +#define VP8_RW_VP8_CTRL 0xA4 +#define VP8_RW_MISC_DCM_CON 0xEC +#define VP8_RW_MISC_SRST 0xF4 +#define VP8_RW_MISC_FUNC_CON 0xCC + +#define VP8_MAX_FRM_BUF_NUM 5 +#define VP8_MAX_FRM_BUF_NODE_NUM (VP8_MAX_FRM_BUF_NUM * 2) + +/* required buffer size (bytes) to store decode information */ +#define VP8_HW_SEGMENT_DATA_SZ 272 +#define VP8_HW_SEGMENT_UINT 4 + +#define VP8_DEC_TABLE_PROC_LOOP 96 +#define VP8_DEC_TABLE_UNIT 3 +#define VP8_DEC_TABLE_SZ 300 +#define VP8_DEC_TABLE_OFFSET 2 +#define VP8_DEC_TABLE_RW_UNIT 4 + +/** + * struct vdec_vp8_dec_info - decode misc information + * @working_buf_dma : working buffer dma address + * @prev_y_dma : previous decoded frame buffer Y plane address + * @cur_y_fb_dma : current plane Y frame buffer dma address + * @cur_c_fb_dma : current plane C frame buffer dma address + * @bs_dma : bitstream dma address + * @bs_sz : bitstream size + * @resolution_changed: resolution change flag 1 - changed, 0 - not change + * @show_frame : display this frame or not + * @wait_key_frame : wait key frame coming + */ +struct vdec_vp8_dec_info { + uint64_t working_buf_dma; + uint64_t prev_y_dma; + uint64_t cur_y_fb_dma; + uint64_t cur_c_fb_dma; + uint64_t bs_dma; + uint32_t bs_sz; + uint32_t resolution_changed; + uint32_t show_frame; + uint32_t wait_key_frame; +}; + +/** + * struct vdec_vp8_vsi - VPU shared information + * @dec : decoding information + * @pic : picture information + * @dec_table : decoder coefficient table + * @segment_buf : segmentation buffer + * @load_data : flag to indicate reload decode data + */ +struct vdec_vp8_vsi { + struct vdec_vp8_dec_info dec; + struct vdec_pic_info pic; + uint32_t dec_table[VP8_DEC_TABLE_SZ]; + uint32_t segment_buf[VP8_HW_SEGMENT_DATA_SZ][VP8_HW_SEGMENT_UINT]; + uint32_t load_data; +}; + +/** + * struct vdec_vp8_hw_reg_base - HW register base + * @sys : base address for sys + * @misc : base address for misc + * @ld : base address for ld + * @top : base address for top + * @cm : base address for cm + * @hwd : base address for hwd + * @hwb : base address for hwb + */ +struct vdec_vp8_hw_reg_base { + void __iomem *sys; + void __iomem *misc; + void __iomem *ld; + void __iomem *top; + void __iomem *cm; + void __iomem *hwd; + void __iomem *hwb; +}; + +/** + * struct vdec_vp8_vpu_inst - VPU instance for VP8 decode + * @wq_hd : Wait queue to wait VPU message ack + * @signaled : 1 - Host has received ack message from VPU, 0 - not recevie + * @failure : VPU execution result status 0 - success, others - fail + * @inst_addr : VPU decoder instance address + */ +struct vdec_vp8_vpu_inst { + wait_queue_head_t wq_hd; + int signaled; + int failure; + uint32_t inst_addr; +}; + +/* frame buffer (fb) list + * [available_fb_node_list] - decode fb are initialized to 0 and populated in + * [fb_use_list] - fb is set after decode and is moved to this list + * [fb_free_list] - fb is not needed for reference will be moved from + * [fb_use_list] to [fb_free_list] and + * once user remove fb from [fb_free_list], + * it is circulated back to [available_fb_node_list] + * [fb_disp_list] - fb is set after decode and is moved to this list + * once user remove fb from [fb_disp_list] it is + * circulated back to [available_fb_node_list] + */ + +/** + * struct vdec_vp8_inst - VP8 decoder instance + * @cur_fb : current frame buffer + * @dec_fb : decode frame buffer node + * @available_fb_node_list : list to store available frame buffer node + * @fb_use_list : list to store frame buffer in use + * @fb_free_list : list to store free frame buffer + * @fb_disp_list : list to store display ready frame buffer + * @working_buf : HW decoder working buffer + * @reg_base : HW register base address + * @frm_cnt : decode frame count + * @ctx : V4L2 context + * @dev : platform device + * @vpu : VPU instance for decoder + * @vsi : VPU share information + */ +struct vdec_vp8_inst { + struct vdec_fb *cur_fb; + struct vdec_fb_node dec_fb[VP8_MAX_FRM_BUF_NODE_NUM]; + struct list_head available_fb_node_list; + struct list_head fb_use_list; + struct list_head fb_free_list; + struct list_head fb_disp_list; + struct mtk_vcodec_mem working_buf; + struct vdec_vp8_hw_reg_base reg_base; + unsigned int frm_cnt; + struct mtk_vcodec_ctx *ctx; + struct vdec_vpu_inst vpu; + struct vdec_vp8_vsi *vsi; +}; + +static void get_hw_reg_base(struct vdec_vp8_inst *inst) +{ + inst->reg_base.top = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_TOP); + inst->reg_base.cm = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_CM); + inst->reg_base.hwd = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWD); + inst->reg_base.sys = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_SYS); + inst->reg_base.misc = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_MISC); + inst->reg_base.ld = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_LD); + inst->reg_base.hwb = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWB); +} + +static void write_hw_segmentation_data(struct vdec_vp8_inst *inst) +{ + int i, j; + u32 seg_id_addr; + u32 val; + void __iomem *cm = inst->reg_base.cm; + struct vdec_vp8_vsi *vsi = inst->vsi; + + seg_id_addr = readl(inst->reg_base.top + VP8_SEGID_DRAM_ADDR) >> 4; + + for (i = 0; i < ARRAY_SIZE(vsi->segment_buf); i++) { + for (j = ARRAY_SIZE(vsi->segment_buf[i]) - 1; j >= 0; j--) { + val = (1 << 16) + ((seg_id_addr + i) << 2) + j; + writel(val, cm + VP8_HW_VLD_ADDR); + + val = vsi->segment_buf[i][j]; + writel(val, cm + VP8_HW_VLD_VALUE); + } + } +} + +static void read_hw_segmentation_data(struct vdec_vp8_inst *inst) +{ + int i, j; + u32 seg_id_addr; + u32 val; + void __iomem *cm = inst->reg_base.cm; + struct vdec_vp8_vsi *vsi = inst->vsi; + + seg_id_addr = readl(inst->reg_base.top + VP8_SEGID_DRAM_ADDR) >> 4; + + for (i = 0; i < ARRAY_SIZE(vsi->segment_buf); i++) { + for (j = ARRAY_SIZE(vsi->segment_buf[i]) - 1; j >= 0; j--) { + val = ((seg_id_addr + i) << 2) + j; + writel(val, cm + VP8_HW_VLD_ADDR); + + val = readl(cm + VP8_HW_VLD_VALUE); + vsi->segment_buf[i][j] = val; + } + } +} + +/* reset HW and enable HW read/write data function */ +static void enable_hw_rw_function(struct vdec_vp8_inst *inst) +{ + u32 val = 0; + void __iomem *sys = inst->reg_base.sys; + void __iomem *misc = inst->reg_base.misc; + void __iomem *ld = inst->reg_base.ld; + void __iomem *hwb = inst->reg_base.hwb; + void __iomem *hwd = inst->reg_base.hwd; + + writel(0x1, sys + VP8_RW_CKEN_SET); + writel(0x101, ld + VP8_WO_VLD_SRST); + writel(0x101, hwb + VP8_WO_VLD_SRST); + + writel(1, sys); + val = readl(misc + VP8_RW_MISC_SRST); + writel((val & 0xFFFFFFFE), misc + VP8_RW_MISC_SRST); + + writel(0x1, misc + VP8_RW_MISC_SYS_SEL); + writel(0x17F, misc + VP8_RW_MISC_SPEC_CON); + writel(0x71201100, misc + VP8_RW_MISC_FUNC_CON); + writel(0x0, ld + VP8_WO_VLD_SRST); + writel(0x0, hwb + VP8_WO_VLD_SRST); + writel(0x1, sys + VP8_RW_DCM_CON); + writel(0x1, misc + VP8_RW_MISC_DCM_CON); + writel(0x1, hwd + VP8_RW_VP8_CTRL); +} + +static void store_dec_table(struct vdec_vp8_inst *inst) +{ + int i, j; + u32 addr = 0, val = 0; + void __iomem *hwd = inst->reg_base.hwd; + u32 *p = &inst->vsi->dec_table[VP8_DEC_TABLE_OFFSET]; + + for (i = 0; i < VP8_DEC_TABLE_PROC_LOOP; i++) { + writel(addr, hwd + VP8_BSASET); + for (j = 0; j < VP8_DEC_TABLE_UNIT ; j++) { + val = *p++; + writel(val, hwd + VP8_BSDSET); + } + addr += VP8_DEC_TABLE_RW_UNIT; + } +} + +static void load_dec_table(struct vdec_vp8_inst *inst) +{ + int i; + u32 addr = 0; + u32 *p = &inst->vsi->dec_table[VP8_DEC_TABLE_OFFSET]; + void __iomem *hwd = inst->reg_base.hwd; + + for (i = 0; i < VP8_DEC_TABLE_PROC_LOOP; i++) { + writel(addr, hwd + VP8_BSASET); + /* read total 11 bytes */ + *p++ = readl(hwd + VP8_BSDSET); + *p++ = readl(hwd + VP8_BSDSET); + *p++ = readl(hwd + VP8_BSDSET) & 0xFFFFFF; + addr += VP8_DEC_TABLE_RW_UNIT; + } +} + +static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic) +{ + *pic = inst->vsi->pic; + + mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, + pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); +} + +static void vp8_dec_finish(struct vdec_vp8_inst *inst) +{ + struct vdec_fb_node *node; + uint64_t prev_y_dma = inst->vsi->dec.prev_y_dma; + + mtk_vcodec_debug(inst, "prev fb base dma=%llx", prev_y_dma); + + /* put last decode ok frame to fb_free_list */ + if (prev_y_dma != 0) { + list_for_each_entry(node, &inst->fb_use_list, list) { + struct vdec_fb *fb = (struct vdec_fb *)node->fb; + + if (prev_y_dma == (uint64_t)fb->base_y.dma_addr) { + list_move_tail(&node->list, + &inst->fb_free_list); + break; + } + } + } + + /* available_fb_node_list -> fb_use_list */ + node = list_first_entry(&inst->available_fb_node_list, + struct vdec_fb_node, list); + node->fb = inst->cur_fb; + list_move_tail(&node->list, &inst->fb_use_list); + + /* available_fb_node_list -> fb_disp_list */ + if (inst->vsi->dec.show_frame) { + node = list_first_entry(&inst->available_fb_node_list, + struct vdec_fb_node, list); + node->fb = inst->cur_fb; + list_move_tail(&node->list, &inst->fb_disp_list); + } +} + +static void move_fb_list_use_to_free(struct vdec_vp8_inst *inst) +{ + struct vdec_fb_node *node, *tmp; + + list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list) + list_move_tail(&node->list, &inst->fb_free_list); +} + +static void init_list(struct vdec_vp8_inst *inst) +{ + int i; + + INIT_LIST_HEAD(&inst->available_fb_node_list); + INIT_LIST_HEAD(&inst->fb_use_list); + INIT_LIST_HEAD(&inst->fb_free_list); + INIT_LIST_HEAD(&inst->fb_disp_list); + + for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) { + INIT_LIST_HEAD(&inst->dec_fb[i].list); + inst->dec_fb[i].fb = NULL; + list_add_tail(&inst->dec_fb[i].list, + &inst->available_fb_node_list); + } +} + +static void add_fb_to_free_list(struct vdec_vp8_inst *inst, void *fb) +{ + struct vdec_fb_node *node; + + if (fb) { + node = list_first_entry(&inst->available_fb_node_list, + struct vdec_fb_node, list); + node->fb = fb; + list_move_tail(&node->list, &inst->fb_free_list); + } +} + +static int alloc_working_buf(struct vdec_vp8_inst *inst) +{ + int err; + struct mtk_vcodec_mem *mem = &inst->working_buf; + + mem->size = VP8_WORKING_BUF_SZ; + err = mtk_vcodec_mem_alloc(inst->ctx, mem); + if (err) { + mtk_vcodec_err(inst, "Cannot allocate working buffer"); + return err; + } + + inst->vsi->dec.working_buf_dma = (uint64_t)mem->dma_addr; + return 0; +} + +static void free_working_buf(struct vdec_vp8_inst *inst) +{ + struct mtk_vcodec_mem *mem = &inst->working_buf; + + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + + inst->vsi->dec.working_buf_dma = 0; +} + +static int vdec_vp8_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) +{ + struct vdec_vp8_inst *inst; + int err; + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + inst->ctx = ctx; + + inst->vpu.id = IPI_VDEC_VP8; + inst->vpu.dev = ctx->dev->vpu_plat_dev; + inst->vpu.ctx = ctx; + inst->vpu.handler = vpu_dec_ipi_handler; + + err = vpu_dec_init(&inst->vpu); + if (err) { + mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err); + goto error_free_inst; + } + + inst->vsi = (struct vdec_vp8_vsi *)inst->vpu.vsi; + init_list(inst); + err = alloc_working_buf(inst); + if (err) + goto error_deinit; + + get_hw_reg_base(inst); + mtk_vcodec_debug(inst, "VP8 Instance >> %p", inst); + + *h_vdec = (unsigned long)inst; + return 0; + +error_deinit: + vpu_dec_deinit(&inst->vpu); +error_free_inst: + kfree(inst); + return err; +} + +static int vdec_vp8_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec; + struct vdec_vp8_dec_info *dec = &inst->vsi->dec; + struct vdec_vpu_inst *vpu = &inst->vpu; + unsigned char *bs_va; + unsigned int data; + int err = 0; + uint64_t y_fb_dma; + uint64_t c_fb_dma; + + /* bs NULL means flush decoder */ + if (bs == NULL) { + move_fb_list_use_to_free(inst); + return vpu_dec_reset(vpu); + } + + y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; + c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; + + mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx fb=%p", + inst->frm_cnt, y_fb_dma, c_fb_dma, fb); + + inst->cur_fb = fb; + dec->bs_dma = (unsigned long)bs->dma_addr; + dec->bs_sz = bs->size; + dec->cur_y_fb_dma = y_fb_dma; + dec->cur_c_fb_dma = c_fb_dma; + + mtk_vcodec_debug(inst, "\n + FRAME[%d] +\n", inst->frm_cnt); + + write_hw_segmentation_data(inst); + enable_hw_rw_function(inst); + store_dec_table(inst); + + bs_va = (unsigned char *)bs->va; + + /* retrieve width/hight and scale info from header */ + data = (*(bs_va + 9) << 24) | (*(bs_va + 8) << 16) | + (*(bs_va + 7) << 8) | *(bs_va + 6); + err = vpu_dec_start(vpu, &data, 1); + if (err) { + add_fb_to_free_list(inst, fb); + if (dec->wait_key_frame) { + mtk_vcodec_debug(inst, "wait key frame !"); + return 0; + } + + goto error; + } + + if (dec->resolution_changed) { + mtk_vcodec_debug(inst, "- resolution_changed -"); + *res_chg = true; + add_fb_to_free_list(inst, fb); + return 0; + } + + /* wait decoder done interrupt */ + mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS); + + if (inst->vsi->load_data) + load_dec_table(inst); + + vp8_dec_finish(inst); + read_hw_segmentation_data(inst); + + err = vpu_dec_end(vpu); + if (err) + goto error; + + mtk_vcodec_debug(inst, "\n - FRAME[%d] - show=%d\n", inst->frm_cnt, + dec->show_frame); + inst->frm_cnt++; + *res_chg = false; + return 0; + +error: + mtk_vcodec_err(inst, "\n - FRAME[%d] - err=%d\n", inst->frm_cnt, err); + return err; +} + +static void get_disp_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) +{ + struct vdec_fb_node *node; + struct vdec_fb *fb; + + node = list_first_entry_or_null(&inst->fb_disp_list, + struct vdec_fb_node, list); + if (node) { + list_move_tail(&node->list, &inst->available_fb_node_list); + fb = (struct vdec_fb *)node->fb; + fb->status |= FB_ST_DISPLAY; + mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d", + node->fb, fb->status); + } else { + fb = NULL; + mtk_vcodec_debug(inst, "[FB] there is no disp fb"); + } + + *out_fb = fb; +} + +static void get_free_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) +{ + struct vdec_fb_node *node; + struct vdec_fb *fb; + + node = list_first_entry_or_null(&inst->fb_free_list, + struct vdec_fb_node, list); + if (node) { + list_move_tail(&node->list, &inst->available_fb_node_list); + fb = (struct vdec_fb *)node->fb; + fb->status |= FB_ST_FREE; + mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d", + node->fb, fb->status); + } else { + fb = NULL; + mtk_vcodec_debug(inst, "[FB] there is no free fb"); + } + + *out_fb = fb; +} + +static void get_crop_info(struct vdec_vp8_inst *inst, struct v4l2_rect *cr) +{ + cr->left = 0; + cr->top = 0; + cr->width = inst->vsi->pic.pic_w; + cr->height = inst->vsi->pic.pic_h; + mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d", + cr->left, cr->top, cr->width, cr->height); +} + +static int vdec_vp8_get_param(unsigned long h_vdec, + enum vdec_get_param_type type, void *out) +{ + struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec; + + switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + get_disp_fb(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + get_free_fb(inst, out); + break; + + case GET_PARAM_PIC_INFO: + get_pic_info(inst, out); + break; + + case GET_PARAM_CROP_INFO: + get_crop_info(inst, out); + break; + + case GET_PARAM_DPB_SIZE: + *((unsigned int *)out) = VP8_DPB_SIZE; + break; + + default: + mtk_vcodec_err(inst, "invalid get parameter type=%d", type); + return -EINVAL; + } + + return 0; +} + +static void vdec_vp8_deinit(unsigned long h_vdec) +{ + struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec; + + mtk_vcodec_debug_enter(inst); + + vpu_dec_deinit(&inst->vpu); + free_working_buf(inst); + kfree(inst); +} + +static struct vdec_common_if vdec_vp8_if = { + vdec_vp8_init, + vdec_vp8_decode, + vdec_vp8_get_param, + vdec_vp8_deinit, +}; + +struct vdec_common_if *get_vp8_dec_comm_if(void); + +struct vdec_common_if *get_vp8_dec_comm_if(void) +{ + return &vdec_vp8_if; +} diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c index e03f126eb51f..25c7cb96b716 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -24,6 +24,7 @@ #include "mtk_vpu.h" const struct vdec_common_if *get_h264_dec_comm_if(void); +const struct vdec_common_if *get_vp8_dec_comm_if(void); int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) { @@ -34,6 +35,7 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) ctx->dec_if = get_h264_dec_comm_if(); break; case V4L2_PIX_FMT_VP8: + ctx->dec_if = get_vp8_dec_comm_if(); break; default: return -EINVAL; -- cgit v1.2.3 From a8b4a1ea0cecda1089739cfda1b247d17981062d Mon Sep 17 00:00:00 2001 From: Wu-Cheng Li Date: Fri, 2 Sep 2016 09:19:57 -0300 Subject: [media] videodev2.h: add V4L2_PIX_FMT_VP9 format This adds VP9 video coding format, a successor to VP8. Signed-off-by: Wu-Cheng Li Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 94f123f3e04e..ad206de8eada 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -603,6 +603,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ +#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ -- cgit v1.2.3 From fa14a56475ff3690efcda3b6b90f3502db0aa10b Mon Sep 17 00:00:00 2001 From: Wu-Cheng Li Date: Fri, 2 Sep 2016 09:19:58 -0300 Subject: [media] v4l2-ioctl: add VP9 format description VP9 is a video coding format and a successor to VP8. Signed-off-by: Wu-Cheng Li Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 26fe7aef1196..a4b5d360fc96 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1230,6 +1230,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; case V4L2_PIX_FMT_VP8: descr = "VP8"; break; + case V4L2_PIX_FMT_VP9: descr = "VP9"; break; case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; -- cgit v1.2.3 From 988fcf0c0ea694f6e6ba00fc9eb1c6a2e72edfe8 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:19:59 -0300 Subject: [media] Add documentation for V4L2_PIX_FMT_VP9 Add documentation for V4L2_PIX_FMT_VP9. Signed-off-by: Tiffany Lin Signed-off-by: Wu-Cheng Li Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-013.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/media/uapi/v4l/pixfmt-013.rst b/Documentation/media/uapi/v4l/pixfmt-013.rst index 542c087152e3..728d7ede10fa 100644 --- a/Documentation/media/uapi/v4l/pixfmt-013.rst +++ b/Documentation/media/uapi/v4l/pixfmt-013.rst @@ -85,3 +85,8 @@ Compressed Formats - ``V4L2_PIX_FMT_VP8`` - 'VP80' - VP8 video elementary stream. + * .. _V4L2-PIX-FMT-VP9: + + - ``V4L2_PIX_FMT_VP9`` + - 'VP90' + - VP9 video elementary stream. -- cgit v1.2.3 From f77e89854b3e1ce2ca647963bd5bf0320a54a357 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 2 Sep 2016 09:20:00 -0300 Subject: [media] vcodec: mediatek: Add Mediatek VP9 Video Decoder Driver Add vp9 decoder driver for MT8173 [mchehab@s-opensource.org: make checkpatch.pl happy] Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/Makefile | 1 + drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 10 + .../media/platform/mtk-vcodec/vdec/vdec_vp9_if.c | 967 +++++++++++++++++++++ drivers/media/platform/mtk-vcodec/vdec_drv_base.h | 1 + drivers/media/platform/mtk-vcodec/vdec_drv_if.c | 4 + 5 files changed, 983 insertions(+) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 7743c81346a8..852d9697ccfa 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp8_if.o \ + vdec/vdec_vp9_if.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 7f7464a570cb..5823bccfac3e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -43,6 +43,11 @@ static struct mtk_video_fmt mtk_video_formats[] = { .type = MTK_FMT_DEC, .num_planes = 1, }, + { + .fourcc = V4L2_PIX_FMT_VP9, + .type = MTK_FMT_DEC, + .num_planes = 1, + }, }; static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { @@ -56,6 +61,11 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 }, }, + { + .fourcc = V4L2_PIX_FMT_VP9, + .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16, + MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 }, + }, }; #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c new file mode 100644 index 000000000000..e91a3b425b0c --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Daniel Hsiao + * Kai-Sean Yang + * Tiffany Lin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "../mtk_vcodec_intr.h" +#include "../vdec_drv_base.h" +#include "../vdec_vpu_if.h" + +#define VP9_SUPER_FRAME_BS_SZ 64 +#define MAX_VP9_DPB_SIZE 9 + +#define REFS_PER_FRAME 3 +#define MAX_NUM_REF_FRAMES 8 +#define VP9_MAX_FRM_BUF_NUM 9 +#define VP9_MAX_FRM_BUF_NODE_NUM (VP9_MAX_FRM_BUF_NUM * 2) + +/** + * struct vp9_dram_buf - contains buffer info for vpu + * @va : cpu address + * @pa : iova address + * @sz : buffer size + * @padding : for 64 bytes alignment + */ +struct vp9_dram_buf { + unsigned long va; + unsigned long pa; + unsigned int sz; + unsigned int padding; +}; + +/** + * struct vp9_fb_info - contains frame buffer info + * @fb : frmae buffer + * @reserved : reserved field used by vpu + */ +struct vp9_fb_info { + struct vdec_fb *fb; + unsigned int reserved[32]; +}; + +/** + * struct vp9_ref_cnt_buf - contains reference buffer information + * @buf : referenced frame buffer + * @ref_cnt : referenced frame buffer's reference count. + * When reference count=0, remove it from reference list + */ +struct vp9_ref_cnt_buf { + struct vp9_fb_info buf; + unsigned int ref_cnt; +}; + +/** + * struct vp9_fb_info - contains current frame's reference buffer information + * @buf : reference buffer + * @idx : reference buffer index to frm_bufs + * @reserved : reserved field used by vpu + */ +struct vp9_ref_buf { + struct vp9_fb_info *buf; + unsigned int idx; + unsigned int reserved[6]; +}; + +/** + * struct vp9_fb_info - contains frame buffer info + * @fb : super frame reference frame buffer + * @used : this reference frame info entry is used + * @padding : for 64 bytes size align + */ +struct vp9_sf_ref_fb { + struct vdec_fb fb; + int used; + int padding; +}; + +/* + * struct vdec_vp9_vsi - shared buffer between host and VPU firmware + * AP-W/R : AP is writer/reader on this item + * VPU-W/R: VPU is write/reader on this item + * @sf_bs_buf : super frame backup buffer (AP-W, VPU-R) + * @sf_ref_fb : record supoer frame reference buffer information + * (AP-R/W, VPU-R/W) + * @sf_next_ref_fb_idx : next available super frame (AP-W, VPU-R) + * @sf_frm_cnt : super frame count, filled by vpu (AP-R, VPU-W) + * @sf_frm_offset : super frame offset, filled by vpu (AP-R, VPU-W) + * @sf_frm_sz : super frame size, filled by vpu (AP-R, VPU-W) + * @sf_frm_idx : current super frame (AP-R, VPU-W) + * @sf_init : inform super frame info already parsed by vpu (AP-R, VPU-W) + * @fb : capture buffer (AP-W, VPU-R) + * @bs : bs buffer (AP-W, VPU-R) + * @cur_fb : current show capture buffer (AP-R/W, VPU-R/W) + * @pic_w : picture width (AP-R, VPU-W) + * @pic_h : picture height (AP-R, VPU-W) + * @buf_w : codec width (AP-R, VPU-W) + * @buf_h : coded height (AP-R, VPU-W) + * @buf_sz_y_bs : ufo compressed y plane size (AP-R, VPU-W) + * @buf_sz_c_bs : ufo compressed cbcr plane size (AP-R, VPU-W) + * @buf_len_sz_y : size used to store y plane ufo info (AP-R, VPU-W) + * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W) + + * @profile : profile sparsed from vpu (AP-R, VPU-W) + * @show_frame : display this frame or not (AP-R, VPU-W) + * @show_existing_frame : inform this frame is show existing frame + * (AP-R, VPU-W) + * @frm_to_show_idx : index to show frame (AP-R, VPU-W) + + * @refresh_frm_flags : indicate when frame need to refine reference count + * (AP-R, VPU-W) + * @resolution_changed : resolution change in this frame (AP-R, VPU-W) + + * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W) + * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W) + * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W) + * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W) + * @mv_buf : motion vector working buffer (AP-W, VPU-R) + * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W) + */ +struct vdec_vp9_vsi { + unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ]; + struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_FRM_BUF_NUM-1]; + int sf_next_ref_fb_idx; + unsigned int sf_frm_cnt; + unsigned int sf_frm_offset[VP9_MAX_FRM_BUF_NUM-1]; + unsigned int sf_frm_sz[VP9_MAX_FRM_BUF_NUM-1]; + unsigned int sf_frm_idx; + unsigned int sf_init; + struct vdec_fb fb; + struct mtk_vcodec_mem bs; + struct vdec_fb cur_fb; + unsigned int pic_w; + unsigned int pic_h; + unsigned int buf_w; + unsigned int buf_h; + unsigned int buf_sz_y_bs; + unsigned int buf_sz_c_bs; + unsigned int buf_len_sz_y; + unsigned int buf_len_sz_c; + unsigned int profile; + unsigned int show_frame; + unsigned int show_existing_frame; + unsigned int frm_to_show_idx; + unsigned int refresh_frm_flags; + unsigned int resolution_changed; + + struct vp9_ref_cnt_buf frm_bufs[VP9_MAX_FRM_BUF_NUM]; + int ref_frm_map[MAX_NUM_REF_FRAMES]; + unsigned int new_fb_idx; + unsigned int frm_num; + struct vp9_dram_buf mv_buf; + + struct vp9_ref_buf frm_refs[REFS_PER_FRAME]; +}; + +/* + * struct vdec_vp9_inst - vp9 decode instance + * @mv_buf : working buffer for mv + * @dec_fb : vdec_fb node to link fb to different fb_xxx_list + * @available_fb_node_list : current available vdec_fb node + * @fb_use_list : current used or referenced vdec_fb + * @fb_free_list : current available to free vdec_fb + * @fb_disp_list : current available to display vdec_fb + * @cur_fb : current frame buffer + * @ctx : current decode context + * @vpu : vpu instance information + * @vsi : shared buffer between host and VPU firmware + * @total_frm_cnt : total frame count, it do not include sub-frames in super + * frame + * @mem : instance memory information + */ +struct vdec_vp9_inst { + struct mtk_vcodec_mem mv_buf; + + struct vdec_fb_node dec_fb[VP9_MAX_FRM_BUF_NODE_NUM]; + struct list_head available_fb_node_list; + struct list_head fb_use_list; + struct list_head fb_free_list; + struct list_head fb_disp_list; + struct vdec_fb *cur_fb; + struct mtk_vcodec_ctx *ctx; + struct vdec_vpu_inst vpu; + struct vdec_vp9_vsi *vsi; + unsigned int total_frm_cnt; + struct mtk_vcodec_mem mem; +}; + +static bool vp9_is_sf_ref_fb(struct vdec_vp9_inst *inst, struct vdec_fb *fb) +{ + int i; + struct vdec_vp9_vsi *vsi = inst->vsi; + + for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) { + if (fb == &vsi->sf_ref_fb[i].fb) + return true; + } + return false; +} + +static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst + *inst, void *addr) +{ + struct vdec_fb *fb = NULL; + struct vdec_fb_node *node; + + list_for_each_entry(node, &inst->fb_use_list, list) { + fb = (struct vdec_fb *)node->fb; + if (fb->base_y.va == addr) { + list_move_tail(&node->list, + &inst->available_fb_node_list); + break; + } + } + return fb; +} + +static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, + struct vdec_fb *fb) +{ + struct vdec_fb_node *node; + + if (fb) { + node = list_first_entry_or_null(&inst->available_fb_node_list, + struct vdec_fb_node, list); + + if (node) { + node->fb = fb; + list_move_tail(&node->list, &inst->fb_free_list); + } + } else { + mtk_vcodec_debug(inst, "No free fb node"); + } +} + +static void vp9_free_sf_ref_fb(struct vdec_fb *fb) +{ + struct vp9_sf_ref_fb *sf_ref_fb = + container_of(fb, struct vp9_sf_ref_fb, fb); + + sf_ref_fb->used = 0; +} + +static void vp9_ref_cnt_fb(struct vdec_vp9_inst *inst, int *idx, + int new_idx) +{ + struct vdec_vp9_vsi *vsi = inst->vsi; + int ref_idx = *idx; + + if (ref_idx >= 0 && vsi->frm_bufs[ref_idx].ref_cnt > 0) { + vsi->frm_bufs[ref_idx].ref_cnt--; + + if (vsi->frm_bufs[ref_idx].ref_cnt == 0) { + if (!vp9_is_sf_ref_fb(inst, + vsi->frm_bufs[ref_idx].buf.fb)) { + struct vdec_fb *fb; + + fb = vp9_rm_from_fb_use_list(inst, + vsi->frm_bufs[ref_idx].buf.fb->base_y.va); + vp9_add_to_fb_free_list(inst, fb); + } else + vp9_free_sf_ref_fb( + vsi->frm_bufs[ref_idx].buf.fb); + } + } + + *idx = new_idx; + vsi->frm_bufs[new_idx].ref_cnt++; +} + +static void vp9_free_all_sf_ref_fb(struct vdec_vp9_inst *inst) +{ + int i; + struct vdec_vp9_vsi *vsi = inst->vsi; + + for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) { + if (vsi->sf_ref_fb[i].fb.base_y.va) { + mtk_vcodec_mem_free(inst->ctx, + &vsi->sf_ref_fb[i].fb.base_y); + mtk_vcodec_mem_free(inst->ctx, + &vsi->sf_ref_fb[i].fb.base_c); + vsi->sf_ref_fb[i].used = 0; + } + } +} + +/* For each sub-frame except the last one, the driver will dynamically + * allocate reference buffer by calling vp9_get_sf_ref_fb() + * The last sub-frame will use the original fb provided by the + * vp9_dec_decode() interface + */ +static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst) +{ + int idx; + struct mtk_vcodec_mem *mem_basy_y; + struct mtk_vcodec_mem *mem_basy_c; + struct vdec_vp9_vsi *vsi = inst->vsi; + + for (idx = 0; + idx < ARRAY_SIZE(vsi->sf_ref_fb); + idx++) { + if (vsi->sf_ref_fb[idx].fb.base_y.va && + vsi->sf_ref_fb[idx].used == 0) { + return idx; + } + } + + for (idx = 0; + idx < ARRAY_SIZE(vsi->sf_ref_fb); + idx++) { + if (vsi->sf_ref_fb[idx].fb.base_y.va == NULL) + break; + } + + if (idx == ARRAY_SIZE(vsi->sf_ref_fb)) { + mtk_vcodec_err(inst, "List Full"); + return -1; + } + + mem_basy_y = &vsi->sf_ref_fb[idx].fb.base_y; + mem_basy_y->size = vsi->buf_sz_y_bs + + vsi->buf_len_sz_y; + + if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_y)) { + mtk_vcodec_err(inst, "Cannot allocate sf_ref_buf y_buf"); + return -1; + } + + mem_basy_c = &vsi->sf_ref_fb[idx].fb.base_c; + mem_basy_c->size = vsi->buf_sz_c_bs + + vsi->buf_len_sz_c; + + if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_c)) { + mtk_vcodec_err(inst, "Cannot allocate sf_ref_fb c_buf"); + return -1; + } + vsi->sf_ref_fb[idx].used = 0; + + return idx; +} + +static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) +{ + struct vdec_vp9_vsi *vsi = inst->vsi; + int result; + struct mtk_vcodec_mem *mem; + + unsigned int max_pic_w; + unsigned int max_pic_h; + + + if (!(inst->ctx->dev->dec_capability & + VCODEC_CAPABILITY_4K_DISABLED)) { + max_pic_w = VCODEC_DEC_4K_CODED_WIDTH; + max_pic_h = VCODEC_DEC_4K_CODED_HEIGHT; + } else { + max_pic_w = MTK_VDEC_MAX_W; + max_pic_h = MTK_VDEC_MAX_H; + } + + if ((vsi->pic_w > max_pic_w) || + (vsi->pic_h > max_pic_h)) { + mtk_vcodec_err(inst, "Invalid w/h %d/%d", + vsi->pic_w, vsi->pic_h); + return false; + } + + mtk_vcodec_debug(inst, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d", + vsi->resolution_changed, + vsi->pic_w, + vsi->pic_h, + vsi->buf_w, + vsi->buf_h); + + mem = &inst->mv_buf; + + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + + mem->size = ((vsi->buf_w / 64) * + (vsi->buf_h / 64) + 2) * 36 * 16; + + result = mtk_vcodec_mem_alloc(inst->ctx, mem); + if (result) { + mem->size = 0; + mtk_vcodec_err(inst, "Cannot allocate mv_buf"); + return false; + } + /* Set the va again */ + vsi->mv_buf.va = (unsigned long)mem->va; + vsi->mv_buf.pa = (unsigned long)mem->dma_addr; + vsi->mv_buf.sz = (unsigned int)mem->size; + + vp9_free_all_sf_ref_fb(inst); + vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); + + return true; +} + +static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst, + struct vdec_fb *fb) +{ + struct vdec_fb_node *node; + + if (!fb) { + mtk_vcodec_err(inst, "fb == NULL"); + return false; + } + + node = list_first_entry_or_null(&inst->available_fb_node_list, + struct vdec_fb_node, list); + if (node) { + node->fb = fb; + list_move_tail(&node->list, &inst->fb_disp_list); + } else { + mtk_vcodec_err(inst, "No available fb node"); + return false; + } + + return true; +} + +/* If any buffer updating is signaled it should be done here. */ +static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) +{ + struct vdec_vp9_vsi *vsi = inst->vsi; + struct vp9_fb_info *frm_to_show; + int ref_index = 0, mask; + + for (mask = vsi->refresh_frm_flags; mask; mask >>= 1) { + if (mask & 1) + vp9_ref_cnt_fb(inst, &vsi->ref_frm_map[ref_index], + vsi->new_fb_idx); + ++ref_index; + } + + frm_to_show = &vsi->frm_bufs[vsi->new_fb_idx].buf; + vsi->frm_bufs[vsi->new_fb_idx].ref_cnt--; + + if (frm_to_show->fb != inst->cur_fb) { + /* This frame is show exist frame and no decode output + * copy frame data from frm_to_show to current CAPTURE + * buffer + */ + if ((frm_to_show->fb != NULL) && + (inst->cur_fb->base_y.size >= + frm_to_show->fb->base_y.size)) { + memcpy((void *)inst->cur_fb->base_y.va, + (void *)frm_to_show->fb->base_y.va, + vsi->buf_w * + vsi->buf_h); + memcpy((void *)inst->cur_fb->base_c.va, + (void *)frm_to_show->fb->base_c.va, + vsi->buf_w * + vsi->buf_h / 2); + } else { + /* After resolution change case, current CAPTURE buffer + * may have less buffer size than frm_to_show buffer + * size + */ + if (frm_to_show->fb != NULL) + mtk_vcodec_err(inst, + "inst->cur_fb->base_y.size=%zu, frm_to_show->fb.base_y.size=%zu", + inst->cur_fb->base_y.size, + frm_to_show->fb->base_y.size); + } + if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { + if (vsi->show_frame) + vp9_add_to_fb_disp_list(inst, inst->cur_fb); + } + } else { + if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) { + if (vsi->show_frame) + vp9_add_to_fb_disp_list(inst, frm_to_show->fb); + } + } + + /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will + * clean fb_free_list + */ + if (vsi->frm_bufs[vsi->new_fb_idx].ref_cnt == 0) { + if (!vp9_is_sf_ref_fb( + inst, vsi->frm_bufs[vsi->new_fb_idx].buf.fb)) { + struct vdec_fb *fb; + + fb = vp9_rm_from_fb_use_list(inst, + vsi->frm_bufs[vsi->new_fb_idx].buf.fb->base_y.va); + + vp9_add_to_fb_free_list(inst, fb); + } else { + vp9_free_sf_ref_fb( + vsi->frm_bufs[vsi->new_fb_idx].buf.fb); + } + } + + /* if this super frame and it is not last sub-frame, get next fb for + * sub-frame decode + */ + if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1) + vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); +} + +static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst) +{ + struct mtk_vcodec_ctx *ctx = inst->ctx; + + mtk_vcodec_wait_for_done_ctx(inst->ctx, + MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS); + + if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) + return true; + else + return false; +} + +static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_ctx *ctx) +{ + int result; + struct mtk_vcodec_mem mem; + struct vdec_vp9_inst *inst; + + memset(&mem, 0, sizeof(mem)); + mem.size = sizeof(struct vdec_vp9_inst); + result = mtk_vcodec_mem_alloc(ctx, &mem); + if (result) + return NULL; + + inst = mem.va; + inst->mem = mem; + + return inst; +} + +static void vp9_free_inst(struct vdec_vp9_inst *inst) +{ + struct mtk_vcodec_mem mem; + + mem = inst->mem; + if (mem.va) + mtk_vcodec_mem_free(inst->ctx, &mem); +} + +static bool vp9_decode_end_proc(struct vdec_vp9_inst *inst) +{ + struct vdec_vp9_vsi *vsi = inst->vsi; + bool ret = false; + + if (!vsi->show_existing_frame) { + ret = vp9_wait_dec_end(inst); + if (!ret) { + mtk_vcodec_err(inst, "Decode failed, Decode Timeout @[%d]", + vsi->frm_num); + return false; + } + + if (vpu_dec_end(&inst->vpu)) { + mtk_vcodec_err(inst, "vp9_dec_vpu_end failed"); + return false; + } + mtk_vcodec_debug(inst, "Decode Ok @%d (%d/%d)", vsi->frm_num, + vsi->pic_w, vsi->pic_h); + } else { + mtk_vcodec_debug(inst, "Decode Ok @%d (show_existing_frame)", + vsi->frm_num); + } + + vp9_swap_frm_bufs(inst); + vsi->frm_num++; + return true; +} + +static bool vp9_is_last_sub_frm(struct vdec_vp9_inst *inst) +{ + struct vdec_vp9_vsi *vsi = inst->vsi; + + if (vsi->sf_frm_cnt <= 0 || vsi->sf_frm_idx == vsi->sf_frm_cnt) + return true; + + return false; +} + +static struct vdec_fb *vp9_rm_from_fb_disp_list(struct vdec_vp9_inst *inst) +{ + struct vdec_fb_node *node; + struct vdec_fb *fb = NULL; + + node = list_first_entry_or_null(&inst->fb_disp_list, + struct vdec_fb_node, list); + if (node) { + fb = (struct vdec_fb *)node->fb; + fb->status |= FB_ST_DISPLAY; + list_move_tail(&node->list, &inst->available_fb_node_list); + mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d", + node->fb, fb->status); + } else + mtk_vcodec_debug(inst, "[FB] there is no disp fb"); + + return fb; +} + +static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst, + struct vdec_fb *fb) +{ + struct vdec_fb_node *node; + + if (!fb) { + mtk_vcodec_debug(inst, "fb == NULL"); + return false; + } + + node = list_first_entry_or_null(&inst->available_fb_node_list, + struct vdec_fb_node, list); + if (node) { + node->fb = fb; + list_move_tail(&node->list, &inst->fb_use_list); + } else { + mtk_vcodec_err(inst, "No free fb node"); + return false; + } + return true; +} + +static void vp9_reset(struct vdec_vp9_inst *inst) +{ + struct vdec_fb_node *node, *tmp; + + list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list) + list_move_tail(&node->list, &inst->fb_free_list); + + vp9_free_all_sf_ref_fb(inst); + inst->vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); + + if (vpu_dec_reset(&inst->vpu)) + mtk_vcodec_err(inst, "vp9_dec_vpu_reset failed"); + + /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */ + inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va; + inst->vsi->mv_buf.pa = (unsigned long)inst->mv_buf.dma_addr; + inst->vsi->mv_buf.sz = (unsigned long)inst->mv_buf.size; +} + +static void init_all_fb_lists(struct vdec_vp9_inst *inst) +{ + int i; + + INIT_LIST_HEAD(&inst->available_fb_node_list); + INIT_LIST_HEAD(&inst->fb_use_list); + INIT_LIST_HEAD(&inst->fb_free_list); + INIT_LIST_HEAD(&inst->fb_disp_list); + + for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) { + INIT_LIST_HEAD(&inst->dec_fb[i].list); + inst->dec_fb[i].fb = NULL; + list_add_tail(&inst->dec_fb[i].list, + &inst->available_fb_node_list); + } +} + +static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) +{ + pic->y_bs_sz = inst->vsi->buf_sz_y_bs; + pic->c_bs_sz = inst->vsi->buf_sz_c_bs; + pic->y_len_sz = inst->vsi->buf_len_sz_y; + pic->c_len_sz = inst->vsi->buf_len_sz_c; + + pic->pic_w = inst->vsi->pic_w; + pic->pic_h = inst->vsi->pic_h; + pic->buf_w = inst->vsi->buf_w; + pic->buf_h = inst->vsi->buf_h; + + mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", + pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); + mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, + pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); +} + +static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) +{ + + *out_fb = vp9_rm_from_fb_disp_list(inst); + if (*out_fb) + (*out_fb)->status |= FB_ST_DISPLAY; +} + +static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) +{ + struct vdec_fb_node *node; + struct vdec_fb *fb = NULL; + + node = list_first_entry_or_null(&inst->fb_free_list, + struct vdec_fb_node, list); + if (node) { + list_move_tail(&node->list, &inst->available_fb_node_list); + fb = (struct vdec_fb *)node->fb; + fb->status |= FB_ST_FREE; + mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d", + node->fb, fb->status); + } else { + mtk_vcodec_debug(inst, "[FB] there is no free fb"); + } + + *out_fb = fb; +} + +static void vdec_vp9_deinit(unsigned long h_vdec) +{ + struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; + struct mtk_vcodec_mem *mem; + int ret = 0; + + ret = vpu_dec_deinit(&inst->vpu); + if (ret) + mtk_vcodec_err(inst, "vpu_dec_deinit failed"); + + mem = &inst->mv_buf; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + + vp9_free_all_sf_ref_fb(inst); + vp9_free_inst(inst); +} + +static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec) +{ + struct vdec_vp9_inst *inst; + + inst = vp9_alloc_inst(ctx); + if (!inst) + return -ENOMEM; + + inst->total_frm_cnt = 0; + inst->ctx = ctx; + + inst->vpu.id = IPI_VDEC_VP9; + inst->vpu.dev = ctx->dev->vpu_plat_dev; + inst->vpu.ctx = ctx; + inst->vpu.handler = vpu_dec_ipi_handler; + + if (vpu_dec_init(&inst->vpu)) { + mtk_vcodec_err(inst, "vp9_dec_vpu_init failed"); + goto err_deinit_inst; + } + + inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi; + init_all_fb_lists(inst); + + (*h_vdec) = (unsigned long)inst; + return 0; + +err_deinit_inst: + vp9_free_inst(inst); + + return -EINVAL; +} + +static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + int ret = 0; + struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; + struct vdec_vp9_vsi *vsi = inst->vsi; + u32 data[3]; + int i; + + *res_chg = false; + + if ((bs == NULL) && (fb == NULL)) { + mtk_vcodec_debug(inst, "[EOS]"); + vp9_reset(inst); + return ret; + } + + if (bs == NULL) { + mtk_vcodec_err(inst, "bs == NULL"); + return -EINVAL; + } + + mtk_vcodec_debug(inst, "Input BS Size = %zu", bs->size); + + while (1) { + struct vdec_fb *cur_fb = NULL; + + data[0] = *((unsigned int *)bs->va); + data[1] = *((unsigned int *)(bs->va + 4)); + data[2] = *((unsigned int *)(bs->va + 8)); + + vsi->bs = *bs; + + if (fb) + vsi->fb = *fb; + + if (!vsi->sf_init) { + unsigned int sf_bs_sz; + unsigned int sf_bs_off; + unsigned char *sf_bs_src; + unsigned char *sf_bs_dst; + + sf_bs_sz = bs->size > VP9_SUPER_FRAME_BS_SZ ? + VP9_SUPER_FRAME_BS_SZ : bs->size; + sf_bs_off = VP9_SUPER_FRAME_BS_SZ - sf_bs_sz; + sf_bs_src = bs->va + bs->size - sf_bs_sz; + sf_bs_dst = vsi->sf_bs_buf + sf_bs_off; + memcpy(sf_bs_dst, sf_bs_src, sf_bs_sz); + } else { + if ((vsi->sf_frm_cnt > 0) && + (vsi->sf_frm_idx < vsi->sf_frm_cnt)) { + unsigned int idx = vsi->sf_frm_idx; + + memcpy((void *)bs->va, + (void *)(bs->va + + vsi->sf_frm_offset[idx]), + vsi->sf_frm_sz[idx]); + } + } + ret = vpu_dec_start(&inst->vpu, data, 3); + if (ret) { + mtk_vcodec_err(inst, "vpu_dec_start failed"); + goto DECODE_ERROR; + } + + if (vsi->resolution_changed) { + if (!vp9_alloc_work_buf(inst)) { + ret = -EINVAL; + goto DECODE_ERROR; + } + } + + if (vsi->sf_frm_cnt > 0) { + cur_fb = &vsi->sf_ref_fb[vsi->sf_next_ref_fb_idx].fb; + + if (vsi->sf_frm_idx < vsi->sf_frm_cnt) + inst->cur_fb = cur_fb; + else + inst->cur_fb = fb; + } else { + inst->cur_fb = fb; + } + + vsi->frm_bufs[vsi->new_fb_idx].buf.fb = inst->cur_fb; + if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) + vp9_add_to_fb_use_list(inst, inst->cur_fb); + + mtk_vcodec_debug(inst, "[#pic %d]", vsi->frm_num); + + if (vsi->show_existing_frame) + mtk_vcodec_debug(inst, + "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", + vsi->new_fb_idx, vsi->frm_to_show_idx); + + if (vsi->show_existing_frame && (vsi->frm_to_show_idx < + VP9_MAX_FRM_BUF_NUM)) { + mtk_vcodec_err(inst, + "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", + vsi->new_fb_idx, vsi->frm_to_show_idx); + + vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, + vsi->frm_to_show_idx); + ret = -EINVAL; + goto DECODE_ERROR; + } + + /* VPU assign the buffer pointer in its address space, + * reassign here + */ + for (i = 0; i < ARRAY_SIZE(vsi->frm_refs); i++) { + unsigned int idx = vsi->frm_refs[i].idx; + + vsi->frm_refs[i].buf = &vsi->frm_bufs[idx].buf; + } + + if (vsi->resolution_changed) { + *res_chg = true; + mtk_vcodec_debug(inst, "VDEC_ST_RESOLUTION_CHANGED"); + + ret = 0; + goto DECODE_ERROR; + } + + if (vp9_decode_end_proc(inst) != true) { + mtk_vcodec_err(inst, "vp9_decode_end_proc"); + ret = -EINVAL; + goto DECODE_ERROR; + } + + if (vp9_is_last_sub_frm(inst)) + break; + + } + inst->total_frm_cnt++; + +DECODE_ERROR: + if (ret < 0) + vp9_add_to_fb_free_list(inst, fb); + + return ret; +} + +static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr) +{ + cr->left = 0; + cr->top = 0; + cr->width = inst->vsi->pic_w; + cr->height = inst->vsi->pic_h; + mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); +} + +static int vdec_vp9_get_param(unsigned long h_vdec, + enum vdec_get_param_type type, void *out) +{ + struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; + int ret = 0; + + switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + get_disp_fb(inst, out); + break; + case GET_PARAM_FREE_FRAME_BUFFER: + get_free_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: + get_pic_info(inst, out); + break; + case GET_PARAM_DPB_SIZE: + *((unsigned int *)out) = MAX_VP9_DPB_SIZE; + break; + case GET_PARAM_CROP_INFO: + get_crop_info(inst, out); + break; + default: + mtk_vcodec_err(inst, "not supported param type %d", type); + ret = -EINVAL; + break; + } + + return ret; +} + +static struct vdec_common_if vdec_vp9_if = { + vdec_vp9_init, + vdec_vp9_decode, + vdec_vp9_get_param, + vdec_vp9_deinit, +}; + +struct vdec_common_if *get_vp9_dec_comm_if(void); + +struct vdec_common_if *get_vp9_dec_comm_if(void) +{ + return &vdec_vp9_if; +} diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_base.h b/drivers/media/platform/mtk-vcodec/vdec_drv_base.h index ca022e3300d7..7e4c1a92bbd8 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_base.h +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_base.h @@ -17,6 +17,7 @@ #include "mtk_vcodec_drv.h" +#include "vdec_drv_if.h" struct vdec_common_if { /** diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c index 25c7cb96b716..5ffc468dd910 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -25,6 +25,7 @@ const struct vdec_common_if *get_h264_dec_comm_if(void); const struct vdec_common_if *get_vp8_dec_comm_if(void); +const struct vdec_common_if *get_vp9_dec_comm_if(void); int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) { @@ -37,6 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) case V4L2_PIX_FMT_VP8: ctx->dec_if = get_vp8_dec_comm_if(); break; + case V4L2_PIX_FMT_VP9: + ctx->dec_if = get_vp9_dec_comm_if(); + break; default: return -EINVAL; } -- cgit v1.2.3 From fa44d3b9e785327eef8182eae5ae7d463b9cbcba Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 6 Sep 2016 11:51:15 -0300 Subject: [media] vcodec: mediatek: fix odd_ptr_err.cocci warnings PTR_ERR should access the value just tested by IS_ERR Generated by: scripts/coccinelle/tests/odd_ptr_err.cocci CC: Tiffany Lin Signed-off-by: Julia Lawall Signed-off-by: Fengguang Wu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 70aa99329ce5..d48287c727f4 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -255,7 +255,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } dev->reg_base[i] = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR((__force void *)dev->reg_base[i])) { - ret = PTR_ERR((__force void *)dev->reg_base); + ret = PTR_ERR((__force void *)dev->reg_base[i]); goto err_res; } mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); -- cgit v1.2.3 From 67712beb2df027ff36ff6d19b1aeb1af213fac04 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Wed, 7 Sep 2016 04:08:17 -0300 Subject: [media] vcodec: mediatek: add Maintainers entry for Mediatek MT8173 vcodec drivers Add Tiffany Lin and Andrew-CT Chen as maintainers for Mediatek MT8173 vcodec drivers Signed-off-by: Tiffany Lin Signed-off-by: Andrew-CT Chen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1cd38a7e0064..b4d6e9d30ec2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7818,6 +7818,15 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/mediatek/ +MEDIATEK MEDIA DRIVER +M: Tiffany Lin +M: Andrew-CT Chen +S: Supported +F: drivers/media/platform/mtk-vcodec/ +F: drivers/media/platform/mtk-vpu/ +F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt +F: Documentation/devicetree/bindings/media/mediatek-vpu.txt + MEDIATEK MT7601U WIRELESS LAN DRIVER M: Jakub Kicinski L: linux-wireless@vger.kernel.org -- cgit v1.2.3 From 211eba9e791e6f6f4c5945b7fabc1dba150075e4 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 7 Sep 2016 14:10:27 -0300 Subject: [media] VPU: mediatek: fix null pointer dereference on pdev pdev is being null checked, however, prior to that it is being dereferenced by platform_get_drvdata. Move the assignments of vpu and run to after the pdev null check to avoid a potential null pointer dereference. Signed-off-by: Colin Ian King Reviewed-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index 63510de0147c..c3643d929167 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -534,9 +534,9 @@ static int load_requested_vpu(struct mtk_vpu *vpu, int vpu_load_firmware(struct platform_device *pdev) { - struct mtk_vpu *vpu = platform_get_drvdata(pdev); + struct mtk_vpu *vpu; struct device *dev = &pdev->dev; - struct vpu_run *run = &vpu->run; + struct vpu_run *run; const struct firmware *vpu_fw = NULL; int ret; @@ -545,6 +545,9 @@ int vpu_load_firmware(struct platform_device *pdev) return -EINVAL; } + vpu = platform_get_drvdata(pdev); + run = &vpu->run; + mutex_lock(&vpu->vpu_mutex); if (vpu->fw_loaded) { mutex_unlock(&vpu->vpu_mutex); -- cgit v1.2.3 From d4de663458bd00a579742e966c2db0d86352358b Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 9 Sep 2016 12:48:04 -0300 Subject: [media] v4l: add Mediatek compressed video block format Add V4L2_PIX_FMT_MT21C format used on MT8173 driver. It is compressed format and need MT8173 MDP driver to transfer to other standard format. Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index a4b5d360fc96..39e19b4222be 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1249,6 +1249,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; + case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; default: WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); if (fmt->description[0]) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index ad206de8eada..2da477c04479 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -635,6 +635,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y8I v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */ #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ +#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ -- cgit v1.2.3 From a38b7ce98bffcf2dd0e1461e24f410f76bac4cb4 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 9 Sep 2016 12:48:05 -0300 Subject: [media] docs-rst: Add compressed video formats used on MT8173 codec driver Add V4L2_PIX_FMT_MT21C documentation Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-reserved.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst index bd7bf3dae6af..c3bed4687973 100644 --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst @@ -234,7 +234,15 @@ please make a proposal on the linux-media mailing list. repeated for each line, i.e. the number of entries in the pointer array. Anything what's in between the UYVY lines is JPEG data and should be concatenated to form the JPEG stream. - + * .. _V4L2-PIX-FMT-MT21C: + + - ``V4L2_PIX_FMT_MT21C`` + - 'MT21C' + - Compressed two-planar YVU420 format used by Mediatek MT8173. + The compression is lossless. + It is an opaque intermediate format, and MDP HW could convert + V4L2_PIX_FMT_MT21C to V4L2_PIX_FMT_NV12M, + V4L2_PIX_FMT_YUV420M and V4L2_PIX_FMT_YVU420. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| -- cgit v1.2.3 From 86082512625cab8755970105098a4a8818e3f954 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 9 Sep 2016 12:48:06 -0300 Subject: [media] vcodec: mediatek: Add V4L2_PIX_FMT_MT21C support for v4l2 decoder Add V4L2_PIX_FMT_MT21C support Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 5823bccfac3e..05209193ff7e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -25,7 +25,7 @@ #include "mtk_vcodec_dec_pm.h" #define OUT_FMT_IDX 0 -#define CAP_FMT_IDX 0 +#define CAP_FMT_IDX 3 #define MTK_VDEC_MIN_W 64U #define MTK_VDEC_MIN_H 64U @@ -48,6 +48,11 @@ static struct mtk_video_fmt mtk_video_formats[] = { .type = MTK_FMT_DEC, .num_planes = 1, }, + { + .fourcc = V4L2_PIX_FMT_MT21C, + .type = MTK_FMT_FRAME, + .num_planes = 2, + }, }; static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { -- cgit v1.2.3 From 60eaae2b139d315954de2c323b34843101630ee0 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Fri, 9 Sep 2016 12:48:07 -0300 Subject: [media] arm64: dts: mediatek: Add Video Decoder for MT8173 Add video decoder node for MT8173 Signed-off-by: Tiffany Lin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 1c71e256601d..dec87fff5728 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -1051,6 +1051,50 @@ #clock-cells = <1>; }; + vcodec_dec: vcodec@16000000 { + compatible = "mediatek,mt8173-vcodec-dec"; + reg = <0 0x16000000 0 0x100>, /* VDEC_SYS */ + <0 0x16020000 0 0x1000>, /* VDEC_MISC */ + <0 0x16021000 0 0x800>, /* VDEC_LD */ + <0 0x16021800 0 0x800>, /* VDEC_TOP */ + <0 0x16022000 0 0x1000>, /* VDEC_CM */ + <0 0x16023000 0 0x1000>, /* VDEC_AD */ + <0 0x16024000 0 0x1000>, /* VDEC_AV */ + <0 0x16025000 0 0x1000>, /* VDEC_PP */ + <0 0x16026800 0 0x800>, /* VDEC_HWD */ + <0 0x16027000 0 0x800>, /* VDEC_HWQ */ + <0 0x16027800 0 0x800>, /* VDEC_HWB */ + <0 0x16028400 0 0x400>; /* VDEC_HWG */ + interrupts = ; + mediatek,larb = <&larb1>; + iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>, + <&iommu M4U_PORT_HW_VDEC_PP_EXT>, + <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>, + <&iommu M4U_PORT_HW_VDEC_UFO_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>; + mediatek,vpu = <&vpu>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>, + <&topckgen CLK_TOP_UNIVPLL_D2>, + <&topckgen CLK_TOP_CCI400_SEL>, + <&topckgen CLK_TOP_VDEC_SEL>, + <&topckgen CLK_TOP_VCODECPLL>, + <&apmixedsys CLK_APMIXED_VENCPLL>, + <&topckgen CLK_TOP_VENC_LT_SEL>, + <&topckgen CLK_TOP_VCODECPLL_370P5>; + clock-names = "vcodecpll", + "univpll_d2", + "clk_cci400_sel", + "vdec_sel", + "vdecpll", + "vencpll", + "venc_lt_sel", + "vdec_bus_clk_src"; + }; + larb1: larb@16010000 { compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x16010000 0 0x1000>; -- cgit v1.2.3 From 737ea6cfd2263127e6cb00e607135b1087468d60 Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:01 -0300 Subject: [media] VPU: mediatek: Add mdp support VPU driver add mdp support [mchehab@s-opensource.com: fix a merge conflict and make checkpatch happy] Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.h b/drivers/media/platform/mtk-vpu/mtk_vpu.h index 69da501afffa..aec0268be3d0 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.h +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.h @@ -53,6 +53,8 @@ typedef void (*ipi_handler_t) (void *data, * handle H264 video encoder job, and vice versa. * @IPI_VENC_VP8: The interrupt fro vpu is to notify kernel to * handle VP8 video encoder job,, and vice versa. + * @IPI_MDP: The interrupt from vpu is to notify kernel to + * handle MDP (Media Data Path) job, and vice versa. * @IPI_MAX: The maximum IPI number */ @@ -63,6 +65,7 @@ enum ipi_id { IPI_VDEC_VP9, IPI_VENC_H264, IPI_VENC_VP8, + IPI_MDP, IPI_MAX, }; @@ -71,11 +74,13 @@ enum ipi_id { * * @VPU_RST_ENC: encoder reset id * @VPU_RST_DEC: decoder reset id + * @VPU_RST_MDP: MDP (Media Data Path) reset id * @VPU_RST_MAX: maximum reset id */ enum rst_id { VPU_RST_ENC, VPU_RST_DEC, + VPU_RST_MDP, VPU_RST_MAX, }; -- cgit v1.2.3 From b391202c06cf6a4cc1f7a23c164617143aede109 Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:02 -0300 Subject: [media] dt-bindings: Add a binding for Mediatek MDP Add a DT binding documentation of MDP for the MT8173 SoC from Mediatek Signed-off-by: Minghsiu Tsai Acked-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/mediatek-mdp.txt | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/mediatek-mdp.txt diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt new file mode 100644 index 000000000000..4182063a54db --- /dev/null +++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt @@ -0,0 +1,109 @@ +* Mediatek Media Data Path + +Media Data Path is used for scaling and color space conversion. + +Required properties (controller (parent) node): +- compatible: "mediatek,mt8173-mdp" +- mediatek,vpu: the node of video processor unit, see + Documentation/devicetree/bindings/media/mediatek-vpu.txt for details. + +Required properties (all function blocks, child node): +- compatible: Should be one of + "mediatek,mt8173-mdp-rdma" - read DMA + "mediatek,mt8173-mdp-rsz" - resizer + "mediatek,mt8173-mdp-wdma" - write DMA + "mediatek,mt8173-mdp-wrot" - write DMA with rotation +- reg: Physical base address and length of the function block register space +- clocks: device clocks, see + Documentation/devicetree/bindings/clock/clock-bindings.txt for details. +- power-domains: a phandle to the power domain, see + Documentation/devicetree/bindings/power/power_domain.txt for details. + +Required properties (DMA function blocks, child node): +- compatible: Should be one of + "mediatek,mt8173-mdp-rdma" + "mediatek,mt8173-mdp-wdma" + "mediatek,mt8173-mdp-wrot" +- iommus: should point to the respective IOMMU block with master port as + argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt + for details. +- mediatek,larb: must contain the local arbiters in the current Socs, see + Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt + for details. + +Example: +mdp { + compatible = "mediatek,mt8173-mdp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + mediatek,vpu = <&vpu>; + + mdp_rdma0: rdma@14001000 { + compatible = "mediatek,mt8173-mdp-rdma"; + reg = <0 0x14001000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA0>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA0>; + mediatek,larb = <&larb0>; + }; + + mdp_rdma1: rdma@14002000 { + compatible = "mediatek,mt8173-mdp-rdma"; + reg = <0 0x14002000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA1>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA1>; + mediatek,larb = <&larb4>; + }; + + mdp_rsz0: rsz@14003000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14003000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ0>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz1: rsz@14004000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14004000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ1>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz2: rsz@14005000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14005000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ2>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_wdma0: wdma@14006000 { + compatible = "mediatek,mt8173-mdp-wdma"; + reg = <0 0x14006000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WDMA>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WDMA>; + mediatek,larb = <&larb0>; + }; + + mdp_wrot0: wrot@14007000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14007000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT0>; + mediatek,larb = <&larb0>; + }; + + mdp_wrot1: wrot@14008000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14008000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT1>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT1>; + mediatek,larb = <&larb4>; + }; +}; -- cgit v1.2.3 From c8eb2d7e8202fd9cb912f5d33cc34ede66dcb24a Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:03 -0300 Subject: [media] media: Add Mediatek MDP Driver Add MDP driver for MT8173 Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 17 + drivers/media/platform/Makefile | 2 + drivers/media/platform/mtk-mdp/Makefile | 9 + drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 159 ++++ drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 72 ++ drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 294 ++++++ drivers/media/platform/mtk-mdp/mtk_mdp_core.h | 260 +++++ drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h | 126 +++ drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 1270 +++++++++++++++++++++++++ drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h | 22 + drivers/media/platform/mtk-mdp/mtk_mdp_regs.c | 152 +++ drivers/media/platform/mtk-mdp/mtk_mdp_regs.h | 31 + drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c | 145 +++ drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h | 41 + 14 files changed, 2600 insertions(+) create mode 100644 drivers/media/platform/mtk-mdp/Makefile create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_core.c create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_core.h create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_regs.c create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_regs.h create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c create mode 100644 drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index ce4a96fccc43..8d00a3fdcf96 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -175,6 +175,23 @@ config VIDEO_MEDIATEK_VPU To compile this driver as a module, choose M here: the module will be called mtk-vpu. +config VIDEO_MEDIATEK_MDP + tristate "Mediatek MDP driver" + depends on MTK_IOMMU || COMPILE_TEST + depends on VIDEO_DEV && VIDEO_V4L2 + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on HAS_DMA + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + select VIDEO_MEDIATEK_VPU + default n + ---help--- + It is a v4l2 driver and present in Mediatek MT8173 SoCs. + The driver supports for scaling and color space conversion. + + To compile this driver as a module, choose M here: the + module will be called mtk-mdp. + config VIDEO_MEDIATEK_VCODEC tristate "Mediatek Video Codec driver" depends on MTK_IOMMU || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 40b18d12726e..f842933d17de 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -66,3 +66,5 @@ ccflags-y += -I$(srctree)/drivers/media/i2c obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/ + +obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ diff --git a/drivers/media/platform/mtk-mdp/Makefile b/drivers/media/platform/mtk-mdp/Makefile new file mode 100644 index 000000000000..f8025699af99 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/Makefile @@ -0,0 +1,9 @@ +mtk-mdp-y += mtk_mdp_core.o +mtk-mdp-y += mtk_mdp_comp.o +mtk-mdp-y += mtk_mdp_m2m.o +mtk-mdp-y += mtk_mdp_regs.o +mtk-mdp-y += mtk_mdp_vpu.o + +obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp.o + +ccflags-y += -I$(srctree)/drivers/media/platform/mtk-vpu diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c new file mode 100644 index 000000000000..aa8f9fd1f1a2 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include "mtk_mdp_comp.h" + + +static const char * const mtk_mdp_comp_stem[MTK_MDP_COMP_TYPE_MAX] = { + "mdp_rdma", + "mdp_rsz", + "mdp_wdma", + "mdp_wrot", +}; + +struct mtk_mdp_comp_match { + enum mtk_mdp_comp_type type; + int alias_id; +}; + +static const struct mtk_mdp_comp_match mtk_mdp_matches[MTK_MDP_COMP_ID_MAX] = { + { MTK_MDP_RDMA, 0 }, + { MTK_MDP_RDMA, 1 }, + { MTK_MDP_RSZ, 0 }, + { MTK_MDP_RSZ, 1 }, + { MTK_MDP_RSZ, 2 }, + { MTK_MDP_WDMA, 0 }, + { MTK_MDP_WROT, 0 }, + { MTK_MDP_WROT, 1 }, +}; + +int mtk_mdp_comp_get_id(struct device *dev, struct device_node *node, + enum mtk_mdp_comp_type comp_type) +{ + int id = of_alias_get_id(node, mtk_mdp_comp_stem[comp_type]); + int i; + + for (i = 0; i < ARRAY_SIZE(mtk_mdp_matches); i++) { + if (comp_type == mtk_mdp_matches[i].type && + id == mtk_mdp_matches[i].alias_id) + return i; + } + + dev_err(dev, "Failed to get id. type: %d, id: %d\n", comp_type, id); + + return -EINVAL; +} + +void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp) +{ + int i, err; + + if (comp->larb_dev) { + err = mtk_smi_larb_get(comp->larb_dev); + if (err) + dev_err(dev, + "failed to get larb, err %d. type:%d id:%d\n", + err, comp->type, comp->id); + } + + for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { + if (!comp->clk[i]) + continue; + err = clk_prepare_enable(comp->clk[i]); + if (err) + dev_err(dev, + "failed to enable clock, err %d. type:%d id:%d i:%d\n", + err, comp->type, comp->id, i); + } +} + +void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { + if (!comp->clk[i]) + continue; + clk_disable_unprepare(comp->clk[i]); + } + + if (comp->larb_dev) + mtk_smi_larb_put(comp->larb_dev); +} + +int mtk_mdp_comp_init(struct device *dev, struct device_node *node, + struct mtk_mdp_comp *comp, enum mtk_mdp_comp_id comp_id) +{ + struct device_node *larb_node; + struct platform_device *larb_pdev; + int i; + + if (comp_id < 0 || comp_id >= MTK_MDP_COMP_ID_MAX) { + dev_err(dev, "Invalid comp_id %d\n", comp_id); + return -EINVAL; + } + + comp->dev_node = of_node_get(node); + comp->id = comp_id; + comp->type = mtk_mdp_matches[comp_id].type; + comp->regs = of_iomap(node, 0); + + for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { + comp->clk[i] = of_clk_get(node, i); + + /* Only RDMA needs two clocks */ + if (comp->type != MTK_MDP_RDMA) + break; + } + + /* Only DMA capable components need the LARB property */ + comp->larb_dev = NULL; + if (comp->type != MTK_MDP_RDMA && + comp->type != MTK_MDP_WDMA && + comp->type != MTK_MDP_WROT) + return 0; + + larb_node = of_parse_phandle(node, "mediatek,larb", 0); + if (!larb_node) { + dev_err(dev, + "Missing mediadek,larb phandle in %s node\n", + node->full_name); + return -EINVAL; + } + + larb_pdev = of_find_device_by_node(larb_node); + if (!larb_pdev) { + dev_warn(dev, "Waiting for larb device %s\n", + larb_node->full_name); + of_node_put(larb_node); + return -EPROBE_DEFER; + } + of_node_put(larb_node); + + comp->larb_dev = &larb_pdev->dev; + + return 0; +} + +void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp) +{ + of_node_put(comp->dev_node); +} diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h new file mode 100644 index 000000000000..63b3983ef1a4 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_COMP_H__ +#define __MTK_MDP_COMP_H__ + +/** + * enum mtk_mdp_comp_type - the MDP component + * @MTK_MDP_RDMA: Read DMA + * @MTK_MDP_RSZ: Riszer + * @MTK_MDP_WDMA: Write DMA + * @MTK_MDP_WROT: Write DMA with rotation + */ +enum mtk_mdp_comp_type { + MTK_MDP_RDMA, + MTK_MDP_RSZ, + MTK_MDP_WDMA, + MTK_MDP_WROT, + MTK_MDP_COMP_TYPE_MAX, +}; + +enum mtk_mdp_comp_id { + MTK_MDP_COMP_RDMA0, + MTK_MDP_COMP_RDMA1, + MTK_MDP_COMP_RSZ0, + MTK_MDP_COMP_RSZ1, + MTK_MDP_COMP_RSZ2, + MTK_MDP_COMP_WDMA, + MTK_MDP_COMP_WROT0, + MTK_MDP_COMP_WROT1, + MTK_MDP_COMP_ID_MAX, +}; + +/** + * struct mtk_mdp_comp - the MDP's function component data + * @dev_node: component device node + * @clk: clocks required for component + * @regs: Mapped address of component registers. + * @larb_dev: SMI device required for component + * @type: component type + * @id: component ID + */ +struct mtk_mdp_comp { + struct device_node *dev_node; + struct clk *clk[2]; + void __iomem *regs; + struct device *larb_dev; + enum mtk_mdp_comp_type type; + enum mtk_mdp_comp_id id; +}; + +int mtk_mdp_comp_init(struct device *dev, struct device_node *node, + struct mtk_mdp_comp *comp, enum mtk_mdp_comp_id comp_id); +void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp); +int mtk_mdp_comp_get_id(struct device *dev, struct device_node *node, + enum mtk_mdp_comp_type comp_type); +void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp); +void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp); + + +#endif /* __MTK_MDP_COMP_H__ */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c new file mode 100644 index 000000000000..7e35235d82e2 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_mdp_core.h" +#include "mtk_mdp_m2m.h" +#include "mtk_vpu.h" + +/* MDP debug log level (0-3). 3 shows all the logs. */ +int mtk_mdp_dbg_level; +EXPORT_SYMBOL(mtk_mdp_dbg_level); + +module_param(mtk_mdp_dbg_level, int, 0644); + +static const struct of_device_id mtk_mdp_comp_dt_ids[] = { + { + .compatible = "mediatek,mt8173-mdp-rdma", + .data = (void *)MTK_MDP_RDMA + }, { + .compatible = "mediatek,mt8173-mdp-rsz", + .data = (void *)MTK_MDP_RSZ + }, { + .compatible = "mediatek,mt8173-mdp-wdma", + .data = (void *)MTK_MDP_WDMA + }, { + .compatible = "mediatek,mt8173-mdp-wrot", + .data = (void *)MTK_MDP_WROT + } +}; + +static const struct of_device_id mtk_mdp_of_ids[] = { + { .compatible = "mediatek,mt8173-mdp", }, + { }, +}; +MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids); + +static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp) +{ + struct device *dev = &mdp->pdev->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) + mtk_mdp_comp_clock_on(dev, mdp->comp[i]); +} + +static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp) +{ + struct device *dev = &mdp->pdev->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) + mtk_mdp_comp_clock_off(dev, mdp->comp[i]); +} + +static void mtk_mdp_wdt_worker(struct work_struct *work) +{ + struct mtk_mdp_dev *mdp = + container_of(work, struct mtk_mdp_dev, wdt_work); + struct mtk_mdp_ctx *ctx; + + mtk_mdp_err("Watchdog timeout"); + + list_for_each_entry(ctx, &mdp->ctx_list, list) { + mtk_mdp_dbg(0, "[%d] Change as state error", ctx->id); + mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_CTX_ERROR); + } +} + +static void mtk_mdp_reset_handler(void *priv) +{ + struct mtk_mdp_dev *mdp = priv; + + queue_work(mdp->wdt_wq, &mdp->wdt_work); +} + +static int mtk_mdp_probe(struct platform_device *pdev) +{ + struct mtk_mdp_dev *mdp; + struct device *dev = &pdev->dev; + struct device_node *node; + int i, ret = 0; + + mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); + if (!mdp) + return -ENOMEM; + + mdp->id = pdev->id; + mdp->pdev = pdev; + INIT_LIST_HEAD(&mdp->ctx_list); + + mutex_init(&mdp->lock); + mutex_init(&mdp->vpulock); + + /* Iterate over sibling MDP function blocks */ + for_each_child_of_node(dev->of_node, node) { + const struct of_device_id *of_id; + enum mtk_mdp_comp_type comp_type; + int comp_id; + struct mtk_mdp_comp *comp; + + of_id = of_match_node(mtk_mdp_comp_dt_ids, node); + if (!of_id) + continue; + + if (!of_device_is_available(node)) { + dev_err(dev, "Skipping disabled component %s\n", + node->full_name); + continue; + } + + comp_type = (enum mtk_mdp_comp_type)of_id->data; + comp_id = mtk_mdp_comp_get_id(dev, node, comp_type); + if (comp_id < 0) { + dev_warn(dev, "Skipping unknown component %s\n", + node->full_name); + continue; + } + + comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL); + if (!comp) { + ret = -ENOMEM; + goto err_comp; + } + mdp->comp[comp_id] = comp; + + ret = mtk_mdp_comp_init(dev, node, comp, comp_id); + if (ret) + goto err_comp; + } + + mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME); + if (!mdp->job_wq) { + dev_err(&pdev->dev, "unable to alloc job workqueue\n"); + ret = -ENOMEM; + goto err_alloc_job_wq; + } + + mdp->wdt_wq = create_singlethread_workqueue("mdp_wdt_wq"); + if (!mdp->wdt_wq) { + dev_err(&pdev->dev, "unable to alloc wdt workqueue\n"); + ret = -ENOMEM; + goto err_alloc_wdt_wq; + } + INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker); + + ret = v4l2_device_register(dev, &mdp->v4l2_dev); + if (ret) { + dev_err(&pdev->dev, "Failed to register v4l2 device\n"); + ret = -EINVAL; + goto err_dev_register; + } + + ret = mtk_mdp_register_m2m_device(mdp); + if (ret) { + v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n"); + goto err_m2m_register; + } + + mdp->vpu_dev = vpu_get_plat_device(pdev); + vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, + VPU_RST_MDP); + + platform_set_drvdata(pdev, mdp); + + vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); + + pm_runtime_enable(dev); + dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id); + + return 0; + +err_m2m_register: + v4l2_device_unregister(&mdp->v4l2_dev); + +err_dev_register: + destroy_workqueue(mdp->wdt_wq); + +err_alloc_wdt_wq: + destroy_workqueue(mdp->job_wq); + +err_alloc_job_wq: + +err_comp: + for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) + mtk_mdp_comp_deinit(dev, mdp->comp[i]); + + dev_dbg(dev, "err %d\n", ret); + return ret; +} + +static int mtk_mdp_remove(struct platform_device *pdev) +{ + struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev); + int i; + + pm_runtime_disable(&pdev->dev); + vb2_dma_contig_clear_max_seg_size(&pdev->dev); + mtk_mdp_unregister_m2m_device(mdp); + v4l2_device_unregister(&mdp->v4l2_dev); + + flush_workqueue(mdp->job_wq); + destroy_workqueue(mdp->job_wq); + + for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) + mtk_mdp_comp_deinit(&pdev->dev, mdp->comp[i]); + + dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); + return 0; +} + +#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) +static int mtk_mdp_pm_suspend(struct device *dev) +{ + struct mtk_mdp_dev *mdp = dev_get_drvdata(dev); + + mtk_mdp_clock_off(mdp); + + return 0; +} + +static int mtk_mdp_pm_resume(struct device *dev) +{ + struct mtk_mdp_dev *mdp = dev_get_drvdata(dev); + + mtk_mdp_clock_on(mdp); + + return 0; +} +#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM_SLEEP +static int mtk_mdp_suspend(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + + return mtk_mdp_pm_suspend(dev); +} + +static int mtk_mdp_resume(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + + return mtk_mdp_pm_resume(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops mtk_mdp_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mtk_mdp_suspend, mtk_mdp_resume) + SET_RUNTIME_PM_OPS(mtk_mdp_pm_suspend, mtk_mdp_pm_resume, NULL) +}; + +static struct platform_driver mtk_mdp_driver = { + .probe = mtk_mdp_probe, + .remove = mtk_mdp_remove, + .driver = { + .name = MTK_MDP_MODULE_NAME, + .owner = THIS_MODULE, + .pm = &mtk_mdp_pm_ops, + .of_match_table = mtk_mdp_of_ids, + } +}; + +module_platform_driver(mtk_mdp_driver); + +MODULE_AUTHOR("Houlong Wei "); +MODULE_DESCRIPTION("Mediatek image processor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h new file mode 100644 index 000000000000..2e979f97d1df --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_CORE_H__ +#define __MTK_MDP_CORE_H__ + +#include +#include +#include +#include +#include +#include + +#include "mtk_mdp_vpu.h" +#include "mtk_mdp_comp.h" + + +#define MTK_MDP_MODULE_NAME "mtk-mdp" + +#define MTK_MDP_SHUTDOWN_TIMEOUT ((100*HZ)/1000) /* 100ms */ +#define MTK_MDP_MAX_CTRL_NUM 10 + +#define MTK_MDP_FMT_FLAG_OUTPUT BIT(0) +#define MTK_MDP_FMT_FLAG_CAPTURE BIT(1) + +#define MTK_MDP_VPU_INIT BIT(0) +#define MTK_MDP_SRC_FMT BIT(1) +#define MTK_MDP_DST_FMT BIT(2) +#define MTK_MDP_CTX_ERROR BIT(5) + +/** + * struct mtk_mdp_pix_align - alignement of image + * @org_w: source alignment of width + * @org_h: source alignment of height + * @target_w: dst alignment of width + * @target_h: dst alignment of height + */ +struct mtk_mdp_pix_align { + u16 org_w; + u16 org_h; + u16 target_w; + u16 target_h; +}; + +/** + * struct mtk_mdp_fmt - the driver's internal color format data + * @pixelformat: the fourcc code for this format, 0 if not applicable + * @num_planes: number of physically non-contiguous data planes + * @num_comp: number of logical data planes + * @depth: per plane driver's private 'number of bits per pixel' + * @row_depth: per plane driver's private 'number of bits per pixel per row' + * @flags: flags indicating which operation mode format applies to + MTK_MDP_FMT_FLAG_OUTPUT is used in OUTPUT stream + MTK_MDP_FMT_FLAG_CAPTURE is used in CAPTURE stream + * @align: pointer to a pixel alignment struct, NULL if using default value + */ +struct mtk_mdp_fmt { + u32 pixelformat; + u16 num_planes; + u16 num_comp; + u8 depth[VIDEO_MAX_PLANES]; + u8 row_depth[VIDEO_MAX_PLANES]; + u32 flags; + struct mtk_mdp_pix_align *align; +}; + +/** + * struct mtk_mdp_addr - the image processor physical address set + * @addr: address of planes + */ +struct mtk_mdp_addr { + dma_addr_t addr[MTK_MDP_MAX_NUM_PLANE]; +}; + +/* struct mtk_mdp_ctrls - the image processor control set + * @rotate: rotation degree + * @hflip: horizontal flip + * @vflip: vertical flip + * @global_alpha: the alpha value of current frame + */ +struct mtk_mdp_ctrls { + struct v4l2_ctrl *rotate; + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *global_alpha; +}; + +/** + * struct mtk_mdp_frame - source/target frame properties + * @width: SRC : SRCIMG_WIDTH, DST : OUTPUTDMA_WHOLE_IMG_WIDTH + * @height: SRC : SRCIMG_HEIGHT, DST : OUTPUTDMA_WHOLE_IMG_HEIGHT + * @crop: cropped(source)/scaled(destination) size + * @payload: image size in bytes (w x h x bpp) + * @pitch: bytes per line of image in memory + * @addr: image frame buffer physical addresses + * @fmt: color format pointer + * @alpha: frame's alpha value + */ +struct mtk_mdp_frame { + u32 width; + u32 height; + struct v4l2_rect crop; + unsigned long payload[VIDEO_MAX_PLANES]; + unsigned int pitch[VIDEO_MAX_PLANES]; + struct mtk_mdp_addr addr; + const struct mtk_mdp_fmt *fmt; + u8 alpha; +}; + +/** + * struct mtk_mdp_variant - image processor variant information + * @pix_max: maximum limit of image size + * @pix_min: minimun limit of image size + * @pix_align: alignement of image + * @h_scale_up_max: maximum scale-up in horizontal + * @v_scale_up_max: maximum scale-up in vertical + * @h_scale_down_max: maximum scale-down in horizontal + * @v_scale_down_max: maximum scale-down in vertical + */ +struct mtk_mdp_variant { + struct mtk_mdp_pix_limit *pix_max; + struct mtk_mdp_pix_limit *pix_min; + struct mtk_mdp_pix_align *pix_align; + u16 h_scale_up_max; + u16 v_scale_up_max; + u16 h_scale_down_max; + u16 v_scale_down_max; +}; + +/** + * struct mtk_mdp_dev - abstraction for image processor entity + * @lock: the mutex protecting this data structure + * @vpulock: the mutex protecting the communication with VPU + * @pdev: pointer to the image processor platform device + * @variant: the IP variant information + * @id: image processor device index (0..MTK_MDP_MAX_DEVS) + * @comp: MDP function components + * @m2m_dev: v4l2 memory-to-memory device data + * @ctx_list: list of struct mtk_mdp_ctx + * @vdev: video device for image processor driver + * @v4l2_dev: V4L2 device to register video devices for. + * @job_wq: processor work queue + * @vpu_dev: VPU platform device + * @ctx_num: counter of active MTK MDP context + * @id_counter: An integer id given to the next opened context + * @wdt_wq: work queue for VPU watchdog + * @wdt_work: worker for VPU watchdog + */ +struct mtk_mdp_dev { + struct mutex lock; + struct mutex vpulock; + struct platform_device *pdev; + struct mtk_mdp_variant *variant; + u16 id; + struct mtk_mdp_comp *comp[MTK_MDP_COMP_ID_MAX]; + struct v4l2_m2m_dev *m2m_dev; + struct list_head ctx_list; + struct video_device vdev; + struct v4l2_device v4l2_dev; + struct workqueue_struct *job_wq; + struct platform_device *vpu_dev; + int ctx_num; + unsigned long id_counter; + struct workqueue_struct *wdt_wq; + struct work_struct wdt_work; +}; + +/** + * mtk_mdp_ctx - the device context data + * @list: link to ctx_list of mtk_mdp_dev + * @s_frame: source frame properties + * @d_frame: destination frame properties + * @id: index of the context that this structure describes + * @flags: additional flags for image conversion + * @state: flags to keep track of user configuration + Protected by slock + * @rotation: rotates the image by specified angle + * @hflip: mirror the picture horizontally + * @vflip: mirror the picture vertically + * @mdp_dev: the image processor device this context applies to + * @m2m_ctx: memory-to-memory device context + * @fh: v4l2 file handle + * @ctrl_handler: v4l2 controls handler + * @ctrls image processor control set + * @ctrls_rdy: true if the control handler is initialized + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat + * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function + * @quant: enum v4l2_quantization, colorspace quantization + * @vpu: VPU instance + * @slock: the mutex protecting mtp_mdp_ctx.state + * @work: worker for image processing + */ +struct mtk_mdp_ctx { + struct list_head list; + struct mtk_mdp_frame s_frame; + struct mtk_mdp_frame d_frame; + u32 flags; + u32 state; + int id; + int rotation; + u32 hflip:1; + u32 vflip:1; + struct mtk_mdp_dev *mdp_dev; + struct v4l2_m2m_ctx *m2m_ctx; + struct v4l2_fh fh; + struct v4l2_ctrl_handler ctrl_handler; + struct mtk_mdp_ctrls ctrls; + bool ctrls_rdy; + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_xfer_func xfer_func; + enum v4l2_quantization quant; + + struct mtk_mdp_vpu vpu; + struct mutex slock; + struct work_struct work; +}; + +extern int mtk_mdp_dbg_level; + +#if defined(DEBUG) + +#define mtk_mdp_dbg(level, fmt, args...) \ + do { \ + if (mtk_mdp_dbg_level >= level) \ + pr_info("[MTK_MDP] level=%d %s(),%d: " fmt "\n", \ + level, __func__, __LINE__, ##args); \ + } while (0) + +#define mtk_mdp_err(fmt, args...) \ + pr_err("[MTK_MDP][ERROR] %s:%d: " fmt "\n", __func__, __LINE__, \ + ##args) + + +#define mtk_mdp_dbg_enter() mtk_mdp_dbg(3, "+") +#define mtk_mdp_dbg_leave() mtk_mdp_dbg(3, "-") + +#else + +#define mtk_mdp_dbg(level, fmt, args...) +#define mtk_mdp_err(fmt, args...) +#define mtk_mdp_dbg_enter() +#define mtk_mdp_dbg_leave() + +#endif + +#endif /* __MTK_MDP_CORE_H__ */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h b/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h new file mode 100644 index 000000000000..78e2cc0dead1 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_IPI_H__ +#define __MTK_MDP_IPI_H__ + +#define MTK_MDP_MAX_NUM_PLANE 3 + +enum mdp_ipi_msgid { + AP_MDP_INIT = 0xd000, + AP_MDP_DEINIT = 0xd001, + AP_MDP_PROCESS = 0xd002, + + VPU_MDP_INIT_ACK = 0xe000, + VPU_MDP_DEINIT_ACK = 0xe001, + VPU_MDP_PROCESS_ACK = 0xe002 +}; + +#pragma pack(push, 4) + +/** + * struct mdp_ipi_init - for AP_MDP_INIT + * @msg_id : AP_MDP_INIT + * @ipi_id : IPI_MDP + * @ap_inst : AP mtk_mdp_vpu address + */ +struct mdp_ipi_init { + uint32_t msg_id; + uint32_t ipi_id; + uint64_t ap_inst; +}; + +/** + * struct mdp_ipi_comm - for AP_MDP_PROCESS, AP_MDP_DEINIT + * @msg_id : AP_MDP_PROCESS, AP_MDP_DEINIT + * @ipi_id : IPI_MDP + * @ap_inst : AP mtk_mdp_vpu address + * @vpu_inst_addr : VPU MDP instance address + */ +struct mdp_ipi_comm { + uint32_t msg_id; + uint32_t ipi_id; + uint64_t ap_inst; + uint32_t vpu_inst_addr; +}; + +/** + * struct mdp_ipi_comm_ack - for VPU_MDP_DEINIT_ACK, VPU_MDP_PROCESS_ACK + * @msg_id : VPU_MDP_DEINIT_ACK, VPU_MDP_PROCESS_ACK + * @ipi_id : IPI_MDP + * @ap_inst : AP mtk_mdp_vpu address + * @vpu_inst_addr : VPU MDP instance address + * @status : VPU exeuction result + */ +struct mdp_ipi_comm_ack { + uint32_t msg_id; + uint32_t ipi_id; + uint64_t ap_inst; + uint32_t vpu_inst_addr; + int32_t status; +}; + +/** + * struct mdp_config - configured for source/destination image + * @x : left + * @y : top + * @w : width + * @h : height + * @w_stride : bytes in horizontal + * @h_stride : bytes in vertical + * @crop_x : cropped left + * @crop_y : cropped top + * @crop_w : cropped width + * @crop_h : cropped height + * @format : color format + */ +struct mdp_config { + int32_t x; + int32_t y; + int32_t w; + int32_t h; + int32_t w_stride; + int32_t h_stride; + int32_t crop_x; + int32_t crop_y; + int32_t crop_w; + int32_t crop_h; + int32_t format; +}; + +struct mdp_buffer { + uint64_t addr_mva[MTK_MDP_MAX_NUM_PLANE]; + int32_t plane_size[MTK_MDP_MAX_NUM_PLANE]; + int32_t plane_num; +}; + +struct mdp_config_misc { + int32_t orientation; /* 0, 90, 180, 270 */ + int32_t hflip; /* 1 will enable the flip */ + int32_t vflip; /* 1 will enable the flip */ + int32_t alpha; /* global alpha */ +}; + +struct mdp_process_vsi { + struct mdp_config src_config; + struct mdp_buffer src_buffer; + struct mdp_config dst_config; + struct mdp_buffer dst_buffer; + struct mdp_config_misc misc; +}; + +#pragma pack(pop) + +#endif /* __MTK_MDP_IPI_H__ */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c new file mode 100644 index 000000000000..065502757133 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -0,0 +1,1270 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_mdp_core.h" +#include "mtk_mdp_m2m.h" +#include "mtk_mdp_regs.h" +#include "mtk_vpu.h" + + +/** + * struct mtk_mdp_pix_limit - image pixel size limits + * @org_w: source pixel width + * @org_h: source pixel height + * @target_rot_dis_w: pixel dst scaled width with the rotator is off + * @target_rot_dis_h: pixel dst scaled height with the rotator is off + * @target_rot_en_w: pixel dst scaled width with the rotator is on + * @target_rot_en_h: pixel dst scaled height with the rotator is on + */ +struct mtk_mdp_pix_limit { + u16 org_w; + u16 org_h; + u16 target_rot_dis_w; + u16 target_rot_dis_h; + u16 target_rot_en_w; + u16 target_rot_en_h; +}; + +static struct mtk_mdp_pix_align mtk_mdp_size_align = { + .org_w = 16, + .org_h = 16, + .target_w = 2, + .target_h = 2, +}; + +static const struct mtk_mdp_fmt mtk_mdp_formats[] = { + { + .pixelformat = V4L2_PIX_FMT_NV12M, + .depth = { 8, 4 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .num_comp = 2, + .flags = MTK_MDP_FMT_FLAG_OUTPUT | + MTK_MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YUV420M, + .depth = { 8, 2, 2 }, + .row_depth = { 8, 4, 4 }, + .num_planes = 3, + .num_comp = 3, + .flags = MTK_MDP_FMT_FLAG_OUTPUT | + MTK_MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YVU420, + .depth = { 12 }, + .row_depth = { 8 }, + .num_planes = 1, + .num_comp = 3, + .flags = MTK_MDP_FMT_FLAG_OUTPUT | + MTK_MDP_FMT_FLAG_CAPTURE, + } +}; + +static struct mtk_mdp_pix_limit mtk_mdp_size_max = { + .target_rot_dis_w = 4096, + .target_rot_dis_h = 4096, + .target_rot_en_w = 4096, + .target_rot_en_h = 4096, +}; + +static struct mtk_mdp_pix_limit mtk_mdp_size_min = { + .org_w = 16, + .org_h = 16, + .target_rot_dis_w = 16, + .target_rot_dis_h = 16, + .target_rot_en_w = 16, + .target_rot_en_h = 16, +}; + +/* align size for normal raster scan pixel format */ +static struct mtk_mdp_pix_align mtk_mdp_rs_align = { + .org_w = 2, + .org_h = 2, + .target_w = 2, + .target_h = 2, +}; + +static struct mtk_mdp_variant mtk_mdp_default_variant = { + .pix_max = &mtk_mdp_size_max, + .pix_min = &mtk_mdp_size_min, + .pix_align = &mtk_mdp_rs_align, + .h_scale_up_max = 32, + .v_scale_up_max = 32, + .h_scale_down_max = 32, + .v_scale_down_max = 128, +}; + +static const struct mtk_mdp_fmt *mtk_mdp_find_fmt(u32 pixelformat, u32 type) +{ + u32 i, flag; + + flag = V4L2_TYPE_IS_OUTPUT(type) ? MTK_MDP_FMT_FLAG_OUTPUT : + MTK_MDP_FMT_FLAG_CAPTURE; + + for (i = 0; i < ARRAY_SIZE(mtk_mdp_formats); ++i) { + if (!(mtk_mdp_formats[i].flags & flag)) + continue; + if (mtk_mdp_formats[i].pixelformat == pixelformat) + return &mtk_mdp_formats[i]; + } + return NULL; +} + +static const struct mtk_mdp_fmt *mtk_mdp_find_fmt_by_index(u32 index, u32 type) +{ + u32 i, flag, num = 0; + + flag = V4L2_TYPE_IS_OUTPUT(type) ? MTK_MDP_FMT_FLAG_OUTPUT : + MTK_MDP_FMT_FLAG_CAPTURE; + + for (i = 0; i < ARRAY_SIZE(mtk_mdp_formats); ++i) { + if (!(mtk_mdp_formats[i].flags & flag)) + continue; + if (index == num) + return &mtk_mdp_formats[i]; + num++; + } + return NULL; +} + +static void mtk_mdp_bound_align_image(u32 *w, unsigned int wmin, + unsigned int wmax, unsigned int align_w, + u32 *h, unsigned int hmin, + unsigned int hmax, unsigned int align_h) +{ + int org_w, org_h, step_w, step_h; + int walign, halign; + + org_w = *w; + org_h = *h; + walign = ffs(align_w) - 1; + halign = ffs(align_h) - 1; + v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0); + + step_w = 1 << walign; + step_h = 1 << halign; + if (*w < org_w && (*w + step_w) <= wmax) + *w += step_w; + if (*h < org_h && (*h + step_h) <= hmax) + *h += step_h; +} + +static const struct mtk_mdp_fmt *mtk_mdp_try_fmt_mplane(struct mtk_mdp_ctx *ctx, + struct v4l2_format *f) +{ + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + struct mtk_mdp_variant *variant = mdp->variant; + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + const struct mtk_mdp_fmt *fmt; + u32 max_w, max_h, align_w, align_h; + u32 min_w, min_h, org_w, org_h; + int i; + + fmt = mtk_mdp_find_fmt(pix_mp->pixelformat, f->type); + if (!fmt) + fmt = mtk_mdp_find_fmt_by_index(0, f->type); + if (!fmt) { + dev_dbg(&ctx->mdp_dev->pdev->dev, + "pixelformat format 0x%X invalid\n", + pix_mp->pixelformat); + return NULL; + } + + pix_mp->field = V4L2_FIELD_NONE; + pix_mp->pixelformat = fmt->pixelformat; + if (!V4L2_TYPE_IS_OUTPUT(f->type)) { + pix_mp->colorspace = ctx->colorspace; + pix_mp->xfer_func = ctx->xfer_func; + pix_mp->ycbcr_enc = ctx->ycbcr_enc; + pix_mp->quantization = ctx->quant; + } + memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); + + max_w = variant->pix_max->target_rot_dis_w; + max_h = variant->pix_max->target_rot_dis_h; + + if (fmt->align == NULL) { + /* use default alignment */ + align_w = variant->pix_align->org_w; + align_h = variant->pix_align->org_h; + } else { + align_w = fmt->align->org_w; + align_h = fmt->align->org_h; + } + + if (V4L2_TYPE_IS_OUTPUT(f->type)) { + min_w = variant->pix_min->org_w; + min_h = variant->pix_min->org_h; + } else { + min_w = variant->pix_min->target_rot_dis_w; + min_h = variant->pix_min->target_rot_dis_h; + } + + mtk_mdp_dbg(2, "[%d] type:%d, wxh:%ux%u, align:%ux%u, max:%ux%u", + ctx->id, f->type, pix_mp->width, pix_mp->height, + align_w, align_h, max_w, max_h); + /* + * To check if image size is modified to adjust parameter against + * hardware abilities + */ + org_w = pix_mp->width; + org_h = pix_mp->height; + + mtk_mdp_bound_align_image(&pix_mp->width, min_w, max_w, align_w, + &pix_mp->height, min_h, max_h, align_h); + + if (org_w != pix_mp->width || org_h != pix_mp->height) + mtk_mdp_dbg(1, "[%d] size change:%ux%u to %ux%u", ctx->id, + org_w, org_h, pix_mp->width, pix_mp->height); + pix_mp->num_planes = fmt->num_planes; + + for (i = 0; i < pix_mp->num_planes; ++i) { + int bpl = (pix_mp->width * fmt->row_depth[i]) / 8; + int sizeimage = (pix_mp->width * pix_mp->height * + fmt->depth[i]) / 8; + + pix_mp->plane_fmt[i].bytesperline = bpl; + if (pix_mp->plane_fmt[i].sizeimage < sizeimage) + pix_mp->plane_fmt[i].sizeimage = sizeimage; + memset(pix_mp->plane_fmt[i].reserved, 0, + sizeof(pix_mp->plane_fmt[i].reserved)); + mtk_mdp_dbg(2, "[%d] p%d, bpl:%d, sizeimage:%u (%u)", ctx->id, + i, bpl, pix_mp->plane_fmt[i].sizeimage, sizeimage); + } + + return fmt; +} + +static struct mtk_mdp_frame *mtk_mdp_ctx_get_frame(struct mtk_mdp_ctx *ctx, + enum v4l2_buf_type type) +{ + if (V4L2_TYPE_IS_OUTPUT(type)) + return &ctx->s_frame; + return &ctx->d_frame; +} + +static void mtk_mdp_check_crop_change(u32 new_w, u32 new_h, u32 *w, u32 *h) +{ + if (new_w != *w || new_h != *h) { + mtk_mdp_dbg(1, "size change:%dx%d to %dx%d", + *w, *h, new_w, new_h); + + *w = new_w; + *h = new_h; + } +} + +static int mtk_mdp_try_crop(struct mtk_mdp_ctx *ctx, u32 type, + struct v4l2_rect *r) +{ + struct mtk_mdp_frame *frame; + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + struct mtk_mdp_variant *variant = mdp->variant; + u32 align_w, align_h, new_w, new_h; + u32 min_w, min_h, max_w, max_h; + + if (r->top < 0 || r->left < 0) { + dev_err(&ctx->mdp_dev->pdev->dev, + "doesn't support negative values for top & left\n"); + return -EINVAL; + } + + mtk_mdp_dbg(2, "[%d] type:%d, set wxh:%dx%d", ctx->id, type, + r->width, r->height); + + frame = mtk_mdp_ctx_get_frame(ctx, type); + max_w = frame->width; + max_h = frame->height; + new_w = r->width; + new_h = r->height; + + if (V4L2_TYPE_IS_OUTPUT(type)) { + align_w = 1; + align_h = 1; + min_w = 64; + min_h = 32; + } else { + align_w = variant->pix_align->target_w; + align_h = variant->pix_align->target_h; + if (ctx->ctrls.rotate->val == 90 || + ctx->ctrls.rotate->val == 270) { + max_w = frame->height; + max_h = frame->width; + min_w = variant->pix_min->target_rot_en_w; + min_h = variant->pix_min->target_rot_en_h; + new_w = r->height; + new_h = r->width; + } else { + min_w = variant->pix_min->target_rot_dis_w; + min_h = variant->pix_min->target_rot_dis_h; + } + } + + mtk_mdp_dbg(2, "[%d] align:%dx%d, min:%dx%d, new:%dx%d", ctx->id, + align_w, align_h, min_w, min_h, new_w, new_h); + + mtk_mdp_bound_align_image(&new_w, min_w, max_w, align_w, + &new_h, min_h, max_h, align_h); + + if (!V4L2_TYPE_IS_OUTPUT(type) && + (ctx->ctrls.rotate->val == 90 || + ctx->ctrls.rotate->val == 270)) + mtk_mdp_check_crop_change(new_h, new_w, + &r->width, &r->height); + else + mtk_mdp_check_crop_change(new_w, new_h, + &r->width, &r->height); + + /* adjust left/top if cropping rectangle is out of bounds */ + /* Need to add code to algin left value with 2's multiple */ + if (r->left + new_w > max_w) + r->left = max_w - new_w; + if (r->top + new_h > max_h) + r->top = max_h - new_h; + + if (r->left & 1) + r->left -= 1; + + mtk_mdp_dbg(2, "[%d] crop l,t,w,h:%d,%d,%d,%d, max:%dx%d", ctx->id, + r->left, r->top, r->width, + r->height, max_w, max_h); + return 0; +} + +static inline struct mtk_mdp_ctx *fh_to_ctx(struct v4l2_fh *fh) +{ + return container_of(fh, struct mtk_mdp_ctx, fh); +} + +static inline struct mtk_mdp_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_mdp_ctx, ctrl_handler); +} + +void mtk_mdp_ctx_state_lock_set(struct mtk_mdp_ctx *ctx, u32 state) +{ + mutex_lock(&ctx->slock); + ctx->state |= state; + mutex_unlock(&ctx->slock); +} + +static void mtk_mdp_ctx_state_lock_clear(struct mtk_mdp_ctx *ctx, u32 state) +{ + mutex_lock(&ctx->slock); + ctx->state &= ~state; + mutex_unlock(&ctx->slock); +} + +static bool mtk_mdp_ctx_state_is_set(struct mtk_mdp_ctx *ctx, u32 mask) +{ + bool ret; + + mutex_lock(&ctx->slock); + ret = (ctx->state & mask) == mask; + mutex_unlock(&ctx->slock); + return ret; +} + +static void mtk_mdp_ctx_lock(struct vb2_queue *vq) +{ + struct mtk_mdp_ctx *ctx = vb2_get_drv_priv(vq); + + mutex_lock(&ctx->mdp_dev->lock); +} + +static void mtk_mdp_ctx_unlock(struct vb2_queue *vq) +{ + struct mtk_mdp_ctx *ctx = vb2_get_drv_priv(vq); + + mutex_unlock(&ctx->mdp_dev->lock); +} + +static void mtk_mdp_set_frame_size(struct mtk_mdp_frame *frame, int width, + int height) +{ + frame->width = width; + frame->height = height; + frame->crop.width = width; + frame->crop.height = height; + frame->crop.left = 0; + frame->crop.top = 0; +} + +static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct mtk_mdp_ctx *ctx = q->drv_priv; + int ret; + + ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev); + if (ret < 0) + mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d", + ctx->id, ret); + + return 0; +} + +static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx, + enum v4l2_buf_type type) +{ + if (V4L2_TYPE_IS_OUTPUT(type)) + return v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + else + return v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); +} + +static void mtk_mdp_m2m_stop_streaming(struct vb2_queue *q) +{ + struct mtk_mdp_ctx *ctx = q->drv_priv; + struct vb2_buffer *vb; + + vb = mtk_mdp_m2m_buf_remove(ctx, q->type); + while (vb != NULL) { + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_ERROR); + vb = mtk_mdp_m2m_buf_remove(ctx, q->type); + } + + pm_runtime_put(&ctx->mdp_dev->pdev->dev); +} + +static void mtk_mdp_m2m_job_abort(void *priv) +{ +} + +/* The color format (num_planes) must be already configured. */ +static void mtk_mdp_prepare_addr(struct mtk_mdp_ctx *ctx, + struct vb2_buffer *vb, + struct mtk_mdp_frame *frame, + struct mtk_mdp_addr *addr) +{ + u32 pix_size, planes, i; + + pix_size = frame->width * frame->height; + planes = min_t(u32, frame->fmt->num_planes, ARRAY_SIZE(addr->addr)); + for (i = 0; i < planes; i++) + addr->addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); + + if (planes == 1) { + if (frame->fmt->pixelformat == V4L2_PIX_FMT_YVU420) { + addr->addr[1] = (dma_addr_t)(addr->addr[0] + pix_size); + addr->addr[2] = (dma_addr_t)(addr->addr[1] + + (pix_size >> 2)); + } else { + dev_err(&ctx->mdp_dev->pdev->dev, + "Invalid pixelformat:0x%x\n", + frame->fmt->pixelformat); + } + } + mtk_mdp_dbg(3, "[%d] planes:%d, size:%d, addr:%p,%p,%p", + ctx->id, planes, pix_size, (void *)addr->addr[0], + (void *)addr->addr[1], (void *)addr->addr[2]); +} + +static void mtk_mdp_m2m_get_bufs(struct mtk_mdp_ctx *ctx) +{ + struct mtk_mdp_frame *s_frame, *d_frame; + struct vb2_buffer *src_vb, *dst_vb; + struct vb2_v4l2_buffer *src_vbuf, *dst_vbuf; + + s_frame = &ctx->s_frame; + d_frame = &ctx->d_frame; + + src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); + mtk_mdp_prepare_addr(ctx, src_vb, s_frame, &s_frame->addr); + + dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + mtk_mdp_prepare_addr(ctx, dst_vb, d_frame, &d_frame->addr); + + src_vbuf = to_vb2_v4l2_buffer(src_vb); + dst_vbuf = to_vb2_v4l2_buffer(dst_vb); + dst_vbuf->vb2_buf.timestamp = src_vbuf->vb2_buf.timestamp; +} + +static void mtk_mdp_process_done(void *priv, int vb_state) +{ + struct mtk_mdp_dev *mdp = priv; + struct mtk_mdp_ctx *ctx; + struct vb2_buffer *src_vb, *dst_vb; + struct vb2_v4l2_buffer *src_vbuf = NULL, *dst_vbuf = NULL; + + ctx = v4l2_m2m_get_curr_priv(mdp->m2m_dev); + if (!ctx) + return; + + src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + src_vbuf = to_vb2_v4l2_buffer(src_vb); + dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + dst_vbuf = to_vb2_v4l2_buffer(dst_vb); + + dst_vbuf->vb2_buf.timestamp = src_vbuf->vb2_buf.timestamp; + dst_vbuf->timecode = src_vbuf->timecode; + dst_vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + dst_vbuf->flags |= src_vbuf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + + v4l2_m2m_buf_done(src_vbuf, vb_state); + v4l2_m2m_buf_done(dst_vbuf, vb_state); + v4l2_m2m_job_finish(ctx->mdp_dev->m2m_dev, ctx->m2m_ctx); +} + +static void mtk_mdp_m2m_worker(struct work_struct *work) +{ + struct mtk_mdp_ctx *ctx = + container_of(work, struct mtk_mdp_ctx, work); + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + int ret; + + if (mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_CTX_ERROR)) { + dev_err(&mdp->pdev->dev, "ctx is in error state"); + goto worker_end; + } + + mtk_mdp_m2m_get_bufs(ctx); + + mtk_mdp_hw_set_input_addr(ctx, &ctx->s_frame.addr); + mtk_mdp_hw_set_output_addr(ctx, &ctx->d_frame.addr); + + mtk_mdp_hw_set_in_size(ctx); + mtk_mdp_hw_set_in_image_format(ctx); + + mtk_mdp_hw_set_out_size(ctx); + mtk_mdp_hw_set_out_image_format(ctx); + + mtk_mdp_hw_set_rotation(ctx); + mtk_mdp_hw_set_global_alpha(ctx); + + ret = mtk_mdp_vpu_process(&ctx->vpu); + if (ret) { + dev_err(&mdp->pdev->dev, "processing failed: %d", ret); + goto worker_end; + } + + buf_state = VB2_BUF_STATE_DONE; + +worker_end: + mtk_mdp_process_done(mdp, buf_state); +} + +static void mtk_mdp_m2m_device_run(void *priv) +{ + struct mtk_mdp_ctx *ctx = priv; + + queue_work(ctx->mdp_dev->job_wq, &ctx->work); +} + +static int mtk_mdp_m2m_queue_setup(struct vb2_queue *vq, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct mtk_mdp_ctx *ctx = vb2_get_drv_priv(vq); + struct mtk_mdp_frame *frame; + int i; + + frame = mtk_mdp_ctx_get_frame(ctx, vq->type); + *num_planes = frame->fmt->num_planes; + for (i = 0; i < frame->fmt->num_planes; i++) + sizes[i] = frame->payload[i]; + mtk_mdp_dbg(2, "[%d] type:%d, planes:%d, buffers:%d, size:%u,%u", + ctx->id, vq->type, *num_planes, *num_buffers, + sizes[0], sizes[1]); + return 0; +} + +static int mtk_mdp_m2m_buf_prepare(struct vb2_buffer *vb) +{ + struct mtk_mdp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_mdp_frame *frame; + int i; + + frame = mtk_mdp_ctx_get_frame(ctx, vb->vb2_queue->type); + + if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + for (i = 0; i < frame->fmt->num_planes; i++) + vb2_set_plane_payload(vb, i, frame->payload[i]); + } + + return 0; +} + +static void mtk_mdp_m2m_buf_queue(struct vb2_buffer *vb) +{ + struct mtk_mdp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); +} + +static struct vb2_ops mtk_mdp_m2m_qops = { + .queue_setup = mtk_mdp_m2m_queue_setup, + .buf_prepare = mtk_mdp_m2m_buf_prepare, + .buf_queue = mtk_mdp_m2m_buf_queue, + .wait_prepare = mtk_mdp_ctx_unlock, + .wait_finish = mtk_mdp_ctx_lock, + .stop_streaming = mtk_mdp_m2m_stop_streaming, + .start_streaming = mtk_mdp_m2m_start_streaming, +}; + +static int mtk_mdp_m2m_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + + strlcpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver)); + strlcpy(cap->card, mdp->pdev->name, sizeof(cap->card)); + strlcpy(cap->bus_info, "platform:mt8173", sizeof(cap->bus_info)); + + return 0; +} + +static int mtk_mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f, u32 type) +{ + const struct mtk_mdp_fmt *fmt; + + fmt = mtk_mdp_find_fmt_by_index(f->index, type); + if (!fmt) + return -EINVAL; + + f->pixelformat = fmt->pixelformat; + + return 0; +} + +static int mtk_mdp_m2m_enum_fmt_mplane_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_mdp_enum_fmt_mplane(f, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); +} + +static int mtk_mdp_m2m_enum_fmt_mplane_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_mdp_enum_fmt_mplane(f, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); +} + +static int mtk_mdp_m2m_g_fmt_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + struct mtk_mdp_frame *frame; + struct v4l2_pix_format_mplane *pix_mp; + int i; + + mtk_mdp_dbg(2, "[%d] type:%d", ctx->id, f->type); + + frame = mtk_mdp_ctx_get_frame(ctx, f->type); + pix_mp = &f->fmt.pix_mp; + + pix_mp->width = frame->width; + pix_mp->height = frame->height; + pix_mp->field = V4L2_FIELD_NONE; + pix_mp->pixelformat = frame->fmt->pixelformat; + pix_mp->num_planes = frame->fmt->num_planes; + pix_mp->colorspace = ctx->colorspace; + pix_mp->xfer_func = ctx->xfer_func; + pix_mp->ycbcr_enc = ctx->ycbcr_enc; + pix_mp->quantization = ctx->quant; + mtk_mdp_dbg(2, "[%d] wxh:%dx%d", ctx->id, + pix_mp->width, pix_mp->height); + + for (i = 0; i < pix_mp->num_planes; ++i) { + pix_mp->plane_fmt[i].bytesperline = (frame->width * + frame->fmt->row_depth[i]) / 8; + pix_mp->plane_fmt[i].sizeimage = (frame->width * + frame->height * frame->fmt->depth[i]) / 8; + + mtk_mdp_dbg(2, "[%d] p%d, bpl:%d, sizeimage:%d", ctx->id, i, + pix_mp->plane_fmt[i].bytesperline, + pix_mp->plane_fmt[i].sizeimage); + } + + return 0; +} + +static int mtk_mdp_m2m_try_fmt_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + + if (!mtk_mdp_try_fmt_mplane(ctx, f)) + return -EINVAL; + return 0; +} + +static int mtk_mdp_m2m_s_fmt_mplane(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + struct vb2_queue *vq; + struct mtk_mdp_frame *frame; + struct v4l2_pix_format_mplane *pix_mp; + const struct mtk_mdp_fmt *fmt; + int i; + + mtk_mdp_dbg(2, "[%d] type:%d", ctx->id, f->type); + + frame = mtk_mdp_ctx_get_frame(ctx, f->type); + fmt = mtk_mdp_try_fmt_mplane(ctx, f); + if (!fmt) { + mtk_mdp_err("[%d] try_fmt failed, type:%d", ctx->id, f->type); + return -EINVAL; + } + frame->fmt = fmt; + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + if (vb2_is_streaming(vq)) { + dev_info(&ctx->mdp_dev->pdev->dev, "queue %d busy", f->type); + return -EBUSY; + } + + pix_mp = &f->fmt.pix_mp; + for (i = 0; i < frame->fmt->num_planes; i++) { + frame->payload[i] = pix_mp->plane_fmt[i].sizeimage; + frame->pitch[i] = pix_mp->plane_fmt[i].bytesperline; + } + + mtk_mdp_set_frame_size(frame, pix_mp->width, pix_mp->height); + if (V4L2_TYPE_IS_OUTPUT(f->type)) { + ctx->colorspace = pix_mp->colorspace; + ctx->xfer_func = pix_mp->xfer_func; + ctx->ycbcr_enc = pix_mp->ycbcr_enc; + ctx->quant = pix_mp->quantization; + } + + if (V4L2_TYPE_IS_OUTPUT(f->type)) + mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_SRC_FMT); + else + mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_DST_FMT); + + mtk_mdp_dbg(2, "[%d] type:%d, frame:%dx%d", ctx->id, f->type, + frame->width, frame->height); + + return 0; +} + +static int mtk_mdp_m2m_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *reqbufs) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + + if (reqbufs->count == 0) { + if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + mtk_mdp_ctx_state_lock_clear(ctx, MTK_MDP_SRC_FMT); + else + mtk_mdp_ctx_state_lock_clear(ctx, MTK_MDP_DST_FMT); + } + + return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); +} + +static int mtk_mdp_m2m_streamon(struct file *file, void *fh, + enum v4l2_buf_type type) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + int ret; + + /* The source and target color format need to be set */ + if (V4L2_TYPE_IS_OUTPUT(type)) { + if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_SRC_FMT)) + return -EINVAL; + } else if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_DST_FMT)) { + return -EINVAL; + } + + if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_VPU_INIT)) { + ret = mtk_mdp_vpu_init(&ctx->vpu); + if (ret < 0) { + dev_err(&ctx->mdp_dev->pdev->dev, + "vpu init failed %d\n", + ret); + return -EINVAL; + } + mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_VPU_INIT); + } + + return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); +} + +static inline bool mtk_mdp_is_target_compose(u32 target) +{ + if (target == V4L2_SEL_TGT_COMPOSE_DEFAULT + || target == V4L2_SEL_TGT_COMPOSE_BOUNDS + || target == V4L2_SEL_TGT_COMPOSE) + return true; + return false; +} + +static inline bool mtk_mdp_is_target_crop(u32 target) +{ + if (target == V4L2_SEL_TGT_CROP_DEFAULT + || target == V4L2_SEL_TGT_CROP_BOUNDS + || target == V4L2_SEL_TGT_CROP) + return true; + return false; +} + +static int mtk_mdp_m2m_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct mtk_mdp_frame *frame; + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + bool valid = false; + + if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (mtk_mdp_is_target_compose(s->target)) + valid = true; + } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + if (mtk_mdp_is_target_crop(s->target)) + valid = true; + } + if (!valid) { + mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type, + s->target); + return -EINVAL; + } + + frame = mtk_mdp_ctx_get_frame(ctx, s->type); + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.left = 0; + s->r.top = 0; + s->r.width = frame->width; + s->r.height = frame->height; + return 0; + + case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_CROP: + s->r.left = frame->crop.left; + s->r.top = frame->crop.top; + s->r.width = frame->crop.width; + s->r.height = frame->crop.height; + return 0; + } + + return -EINVAL; +} + +static int mtk_mdp_check_scaler_ratio(struct mtk_mdp_variant *var, int src_w, + int src_h, int dst_w, int dst_h, int rot) +{ + int tmp_w, tmp_h; + + if (rot == 90 || rot == 270) { + tmp_w = dst_h; + tmp_h = dst_w; + } else { + tmp_w = dst_w; + tmp_h = dst_h; + } + + if ((src_w / tmp_w) > var->h_scale_down_max || + (src_h / tmp_h) > var->v_scale_down_max || + (tmp_w / src_w) > var->h_scale_up_max || + (tmp_h / src_h) > var->v_scale_up_max) + return -EINVAL; + + return 0; +} + +static int mtk_mdp_m2m_s_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct mtk_mdp_frame *frame; + struct mtk_mdp_ctx *ctx = fh_to_ctx(fh); + struct v4l2_rect new_r; + struct mtk_mdp_variant *variant = ctx->mdp_dev->variant; + int ret; + bool valid = false; + + if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (s->target == V4L2_SEL_TGT_COMPOSE) + valid = true; + } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + if (s->target == V4L2_SEL_TGT_CROP) + valid = true; + } + if (!valid) { + mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type, + s->target); + return -EINVAL; + } + + new_r = s->r; + ret = mtk_mdp_try_crop(ctx, s->type, &new_r); + if (ret) + return ret; + + if (mtk_mdp_is_target_crop(s->target)) + frame = &ctx->s_frame; + else + frame = &ctx->d_frame; + + /* Check to see if scaling ratio is within supported range */ + if (mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_DST_FMT | MTK_MDP_SRC_FMT)) { + if (V4L2_TYPE_IS_OUTPUT(s->type)) { + ret = mtk_mdp_check_scaler_ratio(variant, new_r.width, + new_r.height, ctx->d_frame.crop.width, + ctx->d_frame.crop.height, + ctx->ctrls.rotate->val); + } else { + ret = mtk_mdp_check_scaler_ratio(variant, + ctx->s_frame.crop.width, + ctx->s_frame.crop.height, new_r.width, + new_r.height, ctx->ctrls.rotate->val); + } + + if (ret) { + dev_info(&ctx->mdp_dev->pdev->dev, + "Out of scaler range"); + return -EINVAL; + } + } + + s->r = new_r; + frame->crop = new_r; + + return 0; +} + +static const struct v4l2_ioctl_ops mtk_mdp_m2m_ioctl_ops = { + .vidioc_querycap = mtk_mdp_m2m_querycap, + .vidioc_enum_fmt_vid_cap_mplane = mtk_mdp_m2m_enum_fmt_mplane_vid_cap, + .vidioc_enum_fmt_vid_out_mplane = mtk_mdp_m2m_enum_fmt_mplane_vid_out, + .vidioc_g_fmt_vid_cap_mplane = mtk_mdp_m2m_g_fmt_mplane, + .vidioc_g_fmt_vid_out_mplane = mtk_mdp_m2m_g_fmt_mplane, + .vidioc_try_fmt_vid_cap_mplane = mtk_mdp_m2m_try_fmt_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_mdp_m2m_try_fmt_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_mdp_m2m_s_fmt_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_mdp_m2m_s_fmt_mplane, + .vidioc_reqbufs = mtk_mdp_m2m_reqbufs, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_streamon = mtk_mdp_m2m_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + .vidioc_g_selection = mtk_mdp_m2m_g_selection, + .vidioc_s_selection = mtk_mdp_m2m_s_selection +}; + +static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct mtk_mdp_ctx *ctx = priv; + int ret; + + memset(src_vq, 0, sizeof(*src_vq)); + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->ops = &mtk_mdp_m2m_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->dev = &ctx->mdp_dev->pdev->dev; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + memset(dst_vq, 0, sizeof(*dst_vq)); + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->ops = &mtk_mdp_m2m_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->dev = &ctx->mdp_dev->pdev->dev; + + return vb2_queue_init(dst_vq); +} + +static int mtk_mdp_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_mdp_ctx *ctx = ctrl_to_ctx(ctrl); + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + struct mtk_mdp_variant *variant = mdp->variant; + u32 state = MTK_MDP_DST_FMT | MTK_MDP_SRC_FMT; + int ret = 0; + + if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) + return 0; + + switch (ctrl->id) { + case V4L2_CID_HFLIP: + ctx->hflip = ctrl->val; + break; + case V4L2_CID_VFLIP: + ctx->vflip = ctrl->val; + break; + case V4L2_CID_ROTATE: + if (mtk_mdp_ctx_state_is_set(ctx, state)) { + ret = mtk_mdp_check_scaler_ratio(variant, + ctx->s_frame.crop.width, + ctx->s_frame.crop.height, + ctx->d_frame.crop.width, + ctx->d_frame.crop.height, + ctx->ctrls.rotate->val); + + if (ret) + return -EINVAL; + } + + ctx->rotation = ctrl->val; + break; + case V4L2_CID_ALPHA_COMPONENT: + ctx->d_frame.alpha = ctrl->val; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mtk_mdp_ctrl_ops = { + .s_ctrl = mtk_mdp_s_ctrl, +}; + +static int mtk_mdp_ctrls_create(struct mtk_mdp_ctx *ctx) +{ + v4l2_ctrl_handler_init(&ctx->ctrl_handler, MTK_MDP_MAX_CTRL_NUM); + + ctx->ctrls.rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &mtk_mdp_ctrl_ops, V4L2_CID_ROTATE, 0, 270, 90, 0); + ctx->ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &mtk_mdp_ctrl_ops, + V4L2_CID_HFLIP, + 0, 1, 1, 0); + ctx->ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &mtk_mdp_ctrl_ops, + V4L2_CID_VFLIP, + 0, 1, 1, 0); + ctx->ctrls.global_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &mtk_mdp_ctrl_ops, + V4L2_CID_ALPHA_COMPONENT, + 0, 255, 1, 0); + ctx->ctrls_rdy = ctx->ctrl_handler.error == 0; + + if (ctx->ctrl_handler.error) { + int err = ctx->ctrl_handler.error; + + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + dev_err(&ctx->mdp_dev->pdev->dev, + "Failed to create control handlers\n"); + return err; + } + + return 0; +} + +static void mtk_mdp_set_default_params(struct mtk_mdp_ctx *ctx) +{ + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + struct mtk_mdp_frame *frame; + + frame = mtk_mdp_ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + frame->fmt = mtk_mdp_find_fmt_by_index(0, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + frame->width = mdp->variant->pix_min->org_w; + frame->height = mdp->variant->pix_min->org_h; + frame->payload[0] = frame->width * frame->height; + frame->payload[1] = frame->payload[0] / 2; + + frame = mtk_mdp_ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + frame->fmt = mtk_mdp_find_fmt_by_index(0, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + frame->width = mdp->variant->pix_min->target_rot_dis_w; + frame->height = mdp->variant->pix_min->target_rot_dis_h; + frame->payload[0] = frame->width * frame->height; + frame->payload[1] = frame->payload[0] / 2; + +} + +static int mtk_mdp_m2m_open(struct file *file) +{ + struct mtk_mdp_dev *mdp = video_drvdata(file); + struct video_device *vfd = video_devdata(file); + struct mtk_mdp_ctx *ctx = NULL; + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + if (mutex_lock_interruptible(&mdp->lock)) { + ret = -ERESTARTSYS; + goto err_lock; + } + + mutex_init(&ctx->slock); + ctx->id = mdp->id_counter++; + v4l2_fh_init(&ctx->fh, vfd); + file->private_data = &ctx->fh; + ret = mtk_mdp_ctrls_create(ctx); + if (ret) + goto error_ctrls; + + /* Use separate control handler per file handle */ + ctx->fh.ctrl_handler = &ctx->ctrl_handler; + v4l2_fh_add(&ctx->fh); + INIT_LIST_HEAD(&ctx->list); + + ctx->mdp_dev = mdp; + mtk_mdp_set_default_params(ctx); + + INIT_WORK(&ctx->work, mtk_mdp_m2m_worker); + ctx->m2m_ctx = v4l2_m2m_ctx_init(mdp->m2m_dev, ctx, + mtk_mdp_m2m_queue_init); + if (IS_ERR(ctx->m2m_ctx)) { + dev_err(&mdp->pdev->dev, "Failed to initialize m2m context"); + ret = PTR_ERR(ctx->m2m_ctx); + goto error_m2m_ctx; + } + ctx->fh.m2m_ctx = ctx->m2m_ctx; + if (mdp->ctx_num++ == 0) { + ret = vpu_load_firmware(mdp->vpu_dev); + if (ret < 0) { + dev_err(&mdp->pdev->dev, + "vpu_load_firmware failed %d\n", ret); + goto err_load_vpu; + } + + ret = mtk_mdp_vpu_register(mdp->pdev); + if (ret < 0) { + dev_err(&mdp->pdev->dev, + "mdp_vpu register failed %d\n", ret); + goto err_load_vpu; + } + } + + list_add(&ctx->list, &mdp->ctx_list); + mutex_unlock(&mdp->lock); + + mtk_mdp_dbg(0, "%s [%d]", dev_name(&mdp->pdev->dev), ctx->id); + + return 0; + +err_load_vpu: + mdp->ctx_num--; + v4l2_m2m_ctx_release(ctx->m2m_ctx); +error_m2m_ctx: + v4l2_ctrl_handler_free(&ctx->ctrl_handler); +error_ctrls: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + mutex_unlock(&mdp->lock); +err_lock: + kfree(ctx); + + return ret; +} + +static int mtk_mdp_m2m_release(struct file *file) +{ + struct mtk_mdp_ctx *ctx = fh_to_ctx(file->private_data); + struct mtk_mdp_dev *mdp = ctx->mdp_dev; + + flush_workqueue(mdp->job_wq); + mutex_lock(&mdp->lock); + v4l2_m2m_ctx_release(ctx->m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + mtk_mdp_vpu_deinit(&ctx->vpu); + mdp->ctx_num--; + list_del_init(&ctx->list); + + mtk_mdp_dbg(0, "%s [%d]", dev_name(&mdp->pdev->dev), ctx->id); + + mutex_unlock(&mdp->lock); + kfree(ctx); + + return 0; +} + +static const struct v4l2_file_operations mtk_mdp_m2m_fops = { + .owner = THIS_MODULE, + .open = mtk_mdp_m2m_open, + .release = mtk_mdp_m2m_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static struct v4l2_m2m_ops mtk_mdp_m2m_ops = { + .device_run = mtk_mdp_m2m_device_run, + .job_abort = mtk_mdp_m2m_job_abort, +}; + +int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp) +{ + struct device *dev = &mdp->pdev->dev; + int ret; + + mdp->variant = &mtk_mdp_default_variant; + mdp->vdev.device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; + mdp->vdev.fops = &mtk_mdp_m2m_fops; + mdp->vdev.ioctl_ops = &mtk_mdp_m2m_ioctl_ops; + mdp->vdev.release = video_device_release_empty; + mdp->vdev.lock = &mdp->lock; + mdp->vdev.vfl_dir = VFL_DIR_M2M; + mdp->vdev.v4l2_dev = &mdp->v4l2_dev; + snprintf(mdp->vdev.name, sizeof(mdp->vdev.name), "%s:m2m", + MTK_MDP_MODULE_NAME); + video_set_drvdata(&mdp->vdev, mdp); + + mdp->m2m_dev = v4l2_m2m_init(&mtk_mdp_m2m_ops); + if (IS_ERR(mdp->m2m_dev)) { + dev_err(dev, "failed to initialize v4l2-m2m device\n"); + ret = PTR_ERR(mdp->m2m_dev); + goto err_m2m_init; + } + + ret = video_register_device(&mdp->vdev, VFL_TYPE_GRABBER, 2); + if (ret) { + dev_err(dev, "failed to register video device\n"); + goto err_vdev_register; + } + + v4l2_info(&mdp->v4l2_dev, "driver registered as /dev/video%d", + mdp->vdev.num); + return 0; + +err_vdev_register: + v4l2_m2m_release(mdp->m2m_dev); +err_m2m_init: + video_device_release(&mdp->vdev); + + return ret; +} + +void mtk_mdp_unregister_m2m_device(struct mtk_mdp_dev *mdp) +{ + video_device_release(&mdp->vdev); + v4l2_m2m_release(mdp->m2m_dev); +} diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h new file mode 100644 index 000000000000..45afd3655817 --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_M2M_H__ +#define __MTK_MDP_M2M_H__ + +void mtk_mdp_ctx_state_lock_set(struct mtk_mdp_ctx *ctx, u32 state); +int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp); +void mtk_mdp_unregister_m2m_device(struct mtk_mdp_dev *mdp); + +#endif /* __MTK_MDP_M2M_H__ */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c new file mode 100644 index 000000000000..a5601e1a238c --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "mtk_mdp_core.h" +#include "mtk_mdp_regs.h" + + +#define MDP_COLORFMT_PACK(VIDEO, PLANE, COPLANE, HF, VF, BITS, GROUP, SWAP, ID)\ + (((VIDEO) << 27) | ((PLANE) << 24) | ((COPLANE) << 22) |\ + ((HF) << 20) | ((VF) << 18) | ((BITS) << 8) | ((GROUP) << 6) |\ + ((SWAP) << 5) | ((ID) << 0)) + +enum MDP_COLOR_ENUM { + MDP_COLOR_UNKNOWN = 0, + MDP_COLOR_NV12 = MDP_COLORFMT_PACK(0, 2, 1, 1, 1, 8, 1, 0, 12), + MDP_COLOR_I420 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 0, 8), + MDP_COLOR_YV12 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 1, 8), +}; + +static int32_t mtk_mdp_map_color_format(int v4l2_format) +{ + switch (v4l2_format) { + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12: + return MDP_COLOR_NV12; + case V4L2_PIX_FMT_YUV420M: + case V4L2_PIX_FMT_YUV420: + return MDP_COLOR_I420; + case V4L2_PIX_FMT_YVU420: + return MDP_COLOR_YV12; + } + + mtk_mdp_err("Unknown format 0x%x", v4l2_format); + + return MDP_COLOR_UNKNOWN; +} + +void mtk_mdp_hw_set_input_addr(struct mtk_mdp_ctx *ctx, + struct mtk_mdp_addr *addr) +{ + struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer; + int i; + + for (i = 0; i < ARRAY_SIZE(addr->addr); i++) + src_buf->addr_mva[i] = (uint64_t)addr->addr[i]; +} + +void mtk_mdp_hw_set_output_addr(struct mtk_mdp_ctx *ctx, + struct mtk_mdp_addr *addr) +{ + struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer; + int i; + + for (i = 0; i < ARRAY_SIZE(addr->addr); i++) + dst_buf->addr_mva[i] = (uint64_t)addr->addr[i]; +} + +void mtk_mdp_hw_set_in_size(struct mtk_mdp_ctx *ctx) +{ + struct mtk_mdp_frame *frame = &ctx->s_frame; + struct mdp_config *config = &ctx->vpu.vsi->src_config; + + /* Set input pixel offset */ + config->crop_x = frame->crop.left; + config->crop_y = frame->crop.top; + + /* Set input cropped size */ + config->crop_w = frame->crop.width; + config->crop_h = frame->crop.height; + + /* Set input original size */ + config->x = 0; + config->y = 0; + config->w = frame->width; + config->h = frame->height; +} + +void mtk_mdp_hw_set_in_image_format(struct mtk_mdp_ctx *ctx) +{ + unsigned int i; + struct mtk_mdp_frame *frame = &ctx->s_frame; + struct mdp_config *config = &ctx->vpu.vsi->src_config; + struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer; + + src_buf->plane_num = frame->fmt->num_comp; + config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat); + config->w_stride = 0; /* MDP will calculate it by color format. */ + config->h_stride = 0; /* MDP will calculate it by color format. */ + + for (i = 0; i < src_buf->plane_num; i++) + src_buf->plane_size[i] = frame->payload[i]; +} + +void mtk_mdp_hw_set_out_size(struct mtk_mdp_ctx *ctx) +{ + struct mtk_mdp_frame *frame = &ctx->d_frame; + struct mdp_config *config = &ctx->vpu.vsi->dst_config; + + config->crop_x = frame->crop.left; + config->crop_y = frame->crop.top; + config->crop_w = frame->crop.width; + config->crop_h = frame->crop.height; + config->x = 0; + config->y = 0; + config->w = frame->width; + config->h = frame->height; +} + +void mtk_mdp_hw_set_out_image_format(struct mtk_mdp_ctx *ctx) +{ + unsigned int i; + struct mtk_mdp_frame *frame = &ctx->d_frame; + struct mdp_config *config = &ctx->vpu.vsi->dst_config; + struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer; + + dst_buf->plane_num = frame->fmt->num_comp; + config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat); + config->w_stride = 0; /* MDP will calculate it by color format. */ + config->h_stride = 0; /* MDP will calculate it by color format. */ + for (i = 0; i < dst_buf->plane_num; i++) + dst_buf->plane_size[i] = frame->payload[i]; +} + +void mtk_mdp_hw_set_rotation(struct mtk_mdp_ctx *ctx) +{ + struct mdp_config_misc *misc = &ctx->vpu.vsi->misc; + + misc->orientation = ctx->ctrls.rotate->val; + misc->hflip = ctx->ctrls.hflip->val; + misc->vflip = ctx->ctrls.vflip->val; +} + +void mtk_mdp_hw_set_global_alpha(struct mtk_mdp_ctx *ctx) +{ + struct mdp_config_misc *misc = &ctx->vpu.vsi->misc; + + misc->alpha = ctx->ctrls.global_alpha->val; +} diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_regs.h b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.h new file mode 100644 index 000000000000..42bd057e76cc --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_REGS_H__ +#define __MTK_MDP_REGS_H__ + + +void mtk_mdp_hw_set_input_addr(struct mtk_mdp_ctx *ctx, + struct mtk_mdp_addr *addr); +void mtk_mdp_hw_set_output_addr(struct mtk_mdp_ctx *ctx, + struct mtk_mdp_addr *addr); +void mtk_mdp_hw_set_in_size(struct mtk_mdp_ctx *ctx); +void mtk_mdp_hw_set_in_image_format(struct mtk_mdp_ctx *ctx); +void mtk_mdp_hw_set_out_size(struct mtk_mdp_ctx *ctx); +void mtk_mdp_hw_set_out_image_format(struct mtk_mdp_ctx *ctx); +void mtk_mdp_hw_set_rotation(struct mtk_mdp_ctx *ctx); +void mtk_mdp_hw_set_global_alpha(struct mtk_mdp_ctx *ctx); + + +#endif /* __MTK_MDP_REGS_H__ */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c new file mode 100644 index 000000000000..fb07bf3dbd8b --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mtk_mdp_core.h" +#include "mtk_mdp_vpu.h" +#include "mtk_vpu.h" + + +static inline struct mtk_mdp_ctx *vpu_to_ctx(struct mtk_mdp_vpu *vpu) +{ + return container_of(vpu, struct mtk_mdp_ctx, vpu); +} + +static void mtk_mdp_vpu_handle_init_ack(struct mdp_ipi_comm_ack *msg) +{ + struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)msg->ap_inst; + + /* mapping VPU address to kernel virtual address */ + vpu->vsi = (struct mdp_process_vsi *) + vpu_mapping_dm_addr(vpu->pdev, msg->vpu_inst_addr); + vpu->inst_addr = msg->vpu_inst_addr; +} + +static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len, void *priv) +{ + unsigned int msg_id = *(unsigned int *)data; + struct mdp_ipi_comm_ack *msg = (struct mdp_ipi_comm_ack *)data; + struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)msg->ap_inst; + struct mtk_mdp_ctx *ctx; + + vpu->failure = msg->status; + if (!vpu->failure) { + switch (msg_id) { + case VPU_MDP_INIT_ACK: + mtk_mdp_vpu_handle_init_ack(data); + break; + case VPU_MDP_DEINIT_ACK: + case VPU_MDP_PROCESS_ACK: + break; + default: + ctx = vpu_to_ctx(vpu); + dev_err(&ctx->mdp_dev->pdev->dev, + "handle unknown ipi msg:0x%x\n", + msg_id); + break; + } + } else { + ctx = vpu_to_ctx(vpu); + mtk_mdp_dbg(0, "[%d]:msg 0x%x, failure:%d", ctx->id, + msg_id, vpu->failure); + } +} + +int mtk_mdp_vpu_register(struct platform_device *pdev) +{ + struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev); + int err; + + err = vpu_ipi_register(mdp->vpu_dev, IPI_MDP, + mtk_mdp_vpu_ipi_handler, "mdp_vpu", NULL); + if (err) + dev_err(&mdp->pdev->dev, + "vpu_ipi_registration fail status=%d\n", err); + + return err; +} + +static int mtk_mdp_vpu_send_msg(void *msg, int len, struct mtk_mdp_vpu *vpu, + int id) +{ + struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu); + int err; + + if (!vpu->pdev) { + mtk_mdp_dbg(1, "[%d]:vpu pdev is NULL", ctx->id); + return -EINVAL; + } + + mutex_lock(&ctx->mdp_dev->vpulock); + err = vpu_ipi_send(vpu->pdev, (enum ipi_id)id, msg, len); + if (err) { + mutex_unlock(&ctx->mdp_dev->vpulock); + dev_err(&ctx->mdp_dev->pdev->dev, + "vpu_ipi_send fail status %d\n", err); + } + mutex_unlock(&ctx->mdp_dev->vpulock); + + return err; +} + +static int mtk_mdp_vpu_send_ap_ipi(struct mtk_mdp_vpu *vpu, uint32_t msg_id) +{ + int err; + struct mdp_ipi_comm msg; + + msg.msg_id = msg_id; + msg.ipi_id = IPI_MDP; + msg.vpu_inst_addr = vpu->inst_addr; + msg.ap_inst = (uint64_t)vpu; + err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); + if (!err && vpu->failure) + err = -EINVAL; + + return err; +} + +int mtk_mdp_vpu_init(struct mtk_mdp_vpu *vpu) +{ + int err; + struct mdp_ipi_init msg; + struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu); + + vpu->pdev = ctx->mdp_dev->vpu_dev; + + msg.msg_id = AP_MDP_INIT; + msg.ipi_id = IPI_MDP; + msg.ap_inst = (uint64_t)vpu; + err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); + if (!err && vpu->failure) + err = -EINVAL; + + return err; +} + +int mtk_mdp_vpu_deinit(struct mtk_mdp_vpu *vpu) +{ + return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_DEINIT); +} + +int mtk_mdp_vpu_process(struct mtk_mdp_vpu *vpu) +{ + return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_PROCESS); +} diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h new file mode 100644 index 000000000000..df4bddaa438e --- /dev/null +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Houlong Wei + * Ming Hsiu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MTK_MDP_VPU_H__ +#define __MTK_MDP_VPU_H__ + +#include "mtk_mdp_ipi.h" + + +/** + * struct mtk_mdp_vpu - VPU instance for MDP + * @pdev : pointer to the VPU platform device + * @inst_addr : VPU MDP instance address + * @failure : VPU execution result status + * @vsi : VPU shared information + */ +struct mtk_mdp_vpu { + struct platform_device *pdev; + uint32_t inst_addr; + int32_t failure; + struct mdp_process_vsi *vsi; +}; + +int mtk_mdp_vpu_register(struct platform_device *pdev); +int mtk_mdp_vpu_init(struct mtk_mdp_vpu *vpu); +int mtk_mdp_vpu_deinit(struct mtk_mdp_vpu *vpu); +int mtk_mdp_vpu_process(struct mtk_mdp_vpu *vpu); + +#endif /* __MTK_MDP_VPU_H__ */ -- cgit v1.2.3 From 989b292a448f8f0ae0f8d74562ac9c210ec0f795 Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:04 -0300 Subject: [media] arm64: dts: mediatek: Add MDP for MT8173 Add MDP node for MT8173 Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index dec87fff5728..6689abf99367 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -41,6 +41,14 @@ dpi0 = &dpi0; dsi0 = &dsi0; dsi1 = &dsi1; + mdp_rdma0 = &mdp_rdma0; + mdp_rdma1 = &mdp_rdma1; + mdp_rsz0 = &mdp_rsz0; + mdp_rsz1 = &mdp_rsz1; + mdp_rsz2 = &mdp_rsz2; + mdp_wdma0 = &mdp_wdma0; + mdp_wrot0 = &mdp_wrot0; + mdp_wrot1 = &mdp_wrot1; }; cpus { @@ -755,6 +763,82 @@ #clock-cells = <1>; }; + mdp { + compatible = "mediatek,mt8173-mdp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + mediatek,vpu = <&vpu>; + + mdp_rdma0: rdma@14001000 { + compatible = "mediatek,mt8173-mdp-rdma"; + reg = <0 0x14001000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA0>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA0>; + mediatek,larb = <&larb0>; + }; + + mdp_rdma1: rdma@14002000 { + compatible = "mediatek,mt8173-mdp-rdma"; + reg = <0 0x14002000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA1>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA1>; + mediatek,larb = <&larb4>; + }; + + mdp_rsz0: rsz@14003000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14003000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ0>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz1: rsz@14004000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14004000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ1>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz2: rsz@14005000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14005000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ2>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + }; + + mdp_wdma0: wdma@14006000 { + compatible = "mediatek,mt8173-mdp-wdma"; + reg = <0 0x14006000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WDMA>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WDMA>; + mediatek,larb = <&larb0>; + }; + + mdp_wrot0: wrot@14007000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14007000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT0>; + mediatek,larb = <&larb0>; + }; + + mdp_wrot1: wrot@14008000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14008000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT1>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT1>; + mediatek,larb = <&larb4>; + }; + }; + ovl0: ovl@1400c000 { compatible = "mediatek,mt8173-disp-ovl"; reg = <0 0x1400c000 0 0x1000>; -- cgit v1.2.3 From 004b93b9e9a7d9e8590de8c864b909ca363deba5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Oct 2016 11:56:43 -0200 Subject: [media] mtk-mdp: fix compilation warnings if !DEBUG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mtk_mdp_dbg() is empty if !DEBUG. This causes the following warnings: drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c: In function ‘mtk_mdp_try_fmt_mplane’: drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c:231:52: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] org_w, org_h, pix_mp->width, pix_mp->height); ^ drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c: In function ‘mtk_mdp_m2m_start_streaming’: drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c:414:21: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ctx->id, ret); ^ With could actually make the code to do something wrong. So, add an empty block to make it be parsed ok. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h index 2e979f97d1df..848569d4ab90 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h @@ -250,7 +250,7 @@ extern int mtk_mdp_dbg_level; #else -#define mtk_mdp_dbg(level, fmt, args...) +#define mtk_mdp_dbg(level, fmt, args...) {} #define mtk_mdp_err(fmt, args...) #define mtk_mdp_dbg_enter() #define mtk_mdp_dbg_leave() -- cgit v1.2.3 From 859b5e407d83e79f42dad08c50bdfc2bb17766cb Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:05 -0300 Subject: [media] media: mtk-mdp: support pixelformat V4L2_PIX_FMT_MT21C Add V4L2_PIX_FMT_MT21C in format list. [mchehab@s-opensource.org: re-add mtk_mdp_size_align] Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 8 ++++++++ drivers/media/platform/mtk-mdp/mtk_mdp_regs.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index 065502757133..a90972efec5c 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -54,6 +54,14 @@ static struct mtk_mdp_pix_align mtk_mdp_size_align = { static const struct mtk_mdp_fmt mtk_mdp_formats[] = { { + .pixelformat = V4L2_PIX_FMT_MT21C, + .depth = { 8, 4 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .num_comp = 2, + .align = &mtk_mdp_size_align, + .flags = MTK_MDP_FMT_FLAG_OUTPUT, + }, { .pixelformat = V4L2_PIX_FMT_NV12M, .depth = { 8, 4 }, .row_depth = { 8, 8 }, diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c index a5601e1a238c..86d57f380c97 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_regs.c @@ -29,6 +29,8 @@ enum MDP_COLOR_ENUM { MDP_COLOR_NV12 = MDP_COLORFMT_PACK(0, 2, 1, 1, 1, 8, 1, 0, 12), MDP_COLOR_I420 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 0, 8), MDP_COLOR_YV12 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 1, 8), + /* Mediatek proprietary format */ + MDP_COLOR_420_MT21 = MDP_COLORFMT_PACK(5, 2, 1, 1, 1, 256, 1, 0, 12), }; static int32_t mtk_mdp_map_color_format(int v4l2_format) @@ -37,6 +39,8 @@ static int32_t mtk_mdp_map_color_format(int v4l2_format) case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12: return MDP_COLOR_NV12; + case V4L2_PIX_FMT_MT21C: + return MDP_COLOR_420_MT21; case V4L2_PIX_FMT_YUV420M: case V4L2_PIX_FMT_YUV420: return MDP_COLOR_I420; -- cgit v1.2.3 From fc96ec0dce65337438ab33c04af8a220657a86c3 Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Thu, 8 Sep 2016 10:09:06 -0300 Subject: [media] media: mtk-mdp: add Maintainers entry for Mediatek MDP driver Add Minghsiu Tsai, Houlong Wei and Andrew-CT Chen as maintainers for Mediatek MDP driver Signed-off-by: Minghsiu Tsai Signed-off-by: Houlong Wei Signed-off-by: Andrew-CT Chen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b4d6e9d30ec2..93e9f4227c53 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7827,6 +7827,15 @@ F: drivers/media/platform/mtk-vpu/ F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt F: Documentation/devicetree/bindings/media/mediatek-vpu.txt +MEDIATEK MDP DRIVER +M: Minghsiu Tsai +M: Houlong Wei +M: Andrew-CT Chen +S: Supported +F: drivers/media/platform/mtk-mdp/ +F: drivers/media/platform/mtk-vpu/ +F: Documentation/devicetree/bindings/media/mediatek-mdp.txt + MEDIATEK MT7601U WIRELESS LAN DRIVER M: Jakub Kicinski L: linux-wireless@vger.kernel.org -- cgit v1.2.3 From 37bf7e34ecc817ce6b8278588aeb22aab5635e1c Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Mon, 19 Sep 2016 03:34:42 -0300 Subject: [media] media: mtk-mdp: fix build warning in arch x86 This patch fix build warning in arch x86 Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 1 + drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index a90972efec5c..9a747e7321cc 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c index fb07bf3dbd8b..39188e5e46d0 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c @@ -25,7 +25,8 @@ static inline struct mtk_mdp_ctx *vpu_to_ctx(struct mtk_mdp_vpu *vpu) static void mtk_mdp_vpu_handle_init_ack(struct mdp_ipi_comm_ack *msg) { - struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)msg->ap_inst; + struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *) + (unsigned long)msg->ap_inst; /* mapping VPU address to kernel virtual address */ vpu->vsi = (struct mdp_process_vsi *) @@ -37,7 +38,8 @@ static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len, void *priv) { unsigned int msg_id = *(unsigned int *)data; struct mdp_ipi_comm_ack *msg = (struct mdp_ipi_comm_ack *)data; - struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)msg->ap_inst; + struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *) + (unsigned long)msg->ap_inst; struct mtk_mdp_ctx *ctx; vpu->failure = msg->status; @@ -108,7 +110,7 @@ static int mtk_mdp_vpu_send_ap_ipi(struct mtk_mdp_vpu *vpu, uint32_t msg_id) msg.msg_id = msg_id; msg.ipi_id = IPI_MDP; msg.vpu_inst_addr = vpu->inst_addr; - msg.ap_inst = (uint64_t)vpu; + msg.ap_inst = (unsigned long)vpu; err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); if (!err && vpu->failure) err = -EINVAL; @@ -126,7 +128,7 @@ int mtk_mdp_vpu_init(struct mtk_mdp_vpu *vpu) msg.msg_id = AP_MDP_INIT; msg.ipi_id = IPI_MDP; - msg.ap_inst = (uint64_t)vpu; + msg.ap_inst = (unsigned long)vpu; err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); if (!err && vpu->failure) err = -EINVAL; -- cgit v1.2.3 From 1b06fcf56aa65299203c876de5dd69d4f46e55a8 Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Mon, 19 Sep 2016 03:34:43 -0300 Subject: [media] media: mtk-mdp: fix build error This patch fix build error without CONFIG_PM_RUNTIME and CONFIG_PM_SLEEP Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 7e35235d82e2..40a229d8a1f5 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -233,7 +233,7 @@ static int mtk_mdp_remove(struct platform_device *pdev) return 0; } -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) +#ifdef CONFIG_PM static int mtk_mdp_pm_suspend(struct device *dev) { struct mtk_mdp_dev *mdp = dev_get_drvdata(dev); @@ -251,7 +251,7 @@ static int mtk_mdp_pm_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP static int mtk_mdp_suspend(struct device *dev) -- cgit v1.2.3 From a0345caf7fafd68f42ff5c6fbe07bb0c90d4af29 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Sep 2016 04:22:20 -0300 Subject: [media] pixfmt-reserved.rst: Improve MT21C documentation Improve the MT21C documentation, making it clearer that this format requires the MDP for further processing. Also fix the fourcc (it was a fivecc :-) ) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-reserved.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst index c3bed4687973..521adb795535 100644 --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst @@ -237,12 +237,12 @@ please make a proposal on the linux-media mailing list. * .. _V4L2-PIX-FMT-MT21C: - ``V4L2_PIX_FMT_MT21C`` - - 'MT21C' + - 'MT21' - Compressed two-planar YVU420 format used by Mediatek MT8173. - The compression is lossless. - It is an opaque intermediate format, and MDP HW could convert - V4L2_PIX_FMT_MT21C to V4L2_PIX_FMT_NV12M, - V4L2_PIX_FMT_YUV420M and V4L2_PIX_FMT_YVU420. + The compression is lossless. + It is an opaque intermediate format and the MDP hardware must be + used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``, + ``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| -- cgit v1.2.3 From 669c6141ea78dff885b5bf025456c7dffb669a61 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Sep 2016 05:00:34 -0300 Subject: [media] mtk-mdp: fix double mutex_unlock Fix smatch error: media-git/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c:100 mtk_mdp_vpu_send_msg() error: double unlock 'mutex:&ctx->mdp_dev->vpulock' Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c index 39188e5e46d0..4893825aa5dd 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c @@ -92,11 +92,9 @@ static int mtk_mdp_vpu_send_msg(void *msg, int len, struct mtk_mdp_vpu *vpu, mutex_lock(&ctx->mdp_dev->vpulock); err = vpu_ipi_send(vpu->pdev, (enum ipi_id)id, msg, len); - if (err) { - mutex_unlock(&ctx->mdp_dev->vpulock); + if (err) dev_err(&ctx->mdp_dev->pdev->dev, "vpu_ipi_send fail status %d\n", err); - } mutex_unlock(&ctx->mdp_dev->vpulock); return err; -- cgit v1.2.3 From b7547ef8670057b1143e9a47a300180db97a0e5b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 09:39:45 -0300 Subject: [media] smiapp: Move sub-device initialisation into a separate function Simplify smiapp_init() by moving the initialisation of individual sub-devices to a separate function. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 110 +++++++++++++++------------------ 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 44f8c7e10a35..957e37e1c25f 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2535,11 +2535,58 @@ static void smiapp_cleanup(struct smiapp_sensor *sensor) smiapp_free_controls(sensor); } +static void smiapp_create_subdev(struct smiapp_sensor *sensor, + struct smiapp_subdev *ssd, const char *name) +{ + struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + + if (!ssd) + return; + + if (ssd != sensor->src) + v4l2_subdev_init(&ssd->sd, &smiapp_ops); + + ssd->sensor = sensor; + + if (ssd == sensor->pixel_array) { + ssd->npads = 1; + } else { + ssd->npads = 2; + ssd->source_pad = 1; + } + + snprintf(ssd->sd.name, + sizeof(ssd->sd.name), "%s %s %d-%4.4x", sensor->minfo.name, + name, i2c_adapter_id(client->adapter), client->addr); + + ssd->sink_fmt.width = + sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; + ssd->sink_fmt.height = + sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; + ssd->compose.width = ssd->sink_fmt.width; + ssd->compose.height = ssd->sink_fmt.height; + ssd->crop[ssd->source_pad] = ssd->compose; + ssd->pads[ssd->source_pad].flags = MEDIA_PAD_FL_SOURCE; + if (ssd != sensor->pixel_array) { + ssd->crop[ssd->sink_pad] = ssd->compose; + ssd->pads[ssd->sink_pad].flags = MEDIA_PAD_FL_SINK; + } + + ssd->sd.entity.ops = &smiapp_entity_ops; + + if (ssd == sensor->src) + return; + + ssd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + ssd->sd.internal_ops = &smiapp_internal_ops; + ssd->sd.owner = THIS_MODULE; + v4l2_set_subdevdata(&ssd->sd, client); +} + static int smiapp_init(struct smiapp_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct smiapp_pll *pll = &sensor->pll; - struct smiapp_subdev *last = NULL; unsigned int i; int rval; @@ -2700,64 +2747,9 @@ static int smiapp_init(struct smiapp_sensor *sensor) if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; - for (i = 0; i < SMIAPP_SUBDEVS; i++) { - struct { - struct smiapp_subdev *ssd; - char *name; - } const __this[] = { - { sensor->scaler, "scaler", }, - { sensor->binner, "binner", }, - { sensor->pixel_array, "pixel array", }, - }, *_this = &__this[i]; - struct smiapp_subdev *this = _this->ssd; - - if (!this) - continue; - - if (this != sensor->src) - v4l2_subdev_init(&this->sd, &smiapp_ops); - - this->sensor = sensor; - - if (this == sensor->pixel_array) { - this->npads = 1; - } else { - this->npads = 2; - this->source_pad = 1; - } - - snprintf(this->sd.name, - sizeof(this->sd.name), "%s %s %d-%4.4x", - sensor->minfo.name, _this->name, - i2c_adapter_id(client->adapter), client->addr); - - this->sink_fmt.width = - sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; - this->sink_fmt.height = - sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; - this->compose.width = this->sink_fmt.width; - this->compose.height = this->sink_fmt.height; - this->crop[this->source_pad] = this->compose; - this->pads[this->source_pad].flags = MEDIA_PAD_FL_SOURCE; - if (this != sensor->pixel_array) { - this->crop[this->sink_pad] = this->compose; - this->pads[this->sink_pad].flags = MEDIA_PAD_FL_SINK; - } - - this->sd.entity.ops = &smiapp_entity_ops; - - if (last == NULL) { - last = this; - continue; - } - - this->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - this->sd.internal_ops = &smiapp_internal_ops; - this->sd.owner = THIS_MODULE; - v4l2_set_subdevdata(&this->sd, client); - - last = this; - } + smiapp_create_subdev(sensor, sensor->scaler, "scaler"); + smiapp_create_subdev(sensor, sensor->binner, "binner"); + smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array"); dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); -- cgit v1.2.3 From cc1488a1fcdcf8fee3ca12c82f5a48745b7fa45d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 10:02:09 -0300 Subject: [media] smiapp: Explicitly define number of pads in initialisation Define the number of pads explicitly in initialising the sub-devices. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 957e37e1c25f..2090b7f2b9aa 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2536,7 +2536,8 @@ static void smiapp_cleanup(struct smiapp_sensor *sensor) } static void smiapp_create_subdev(struct smiapp_sensor *sensor, - struct smiapp_subdev *ssd, const char *name) + struct smiapp_subdev *ssd, const char *name, + unsigned short num_pads) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); @@ -2548,12 +2549,8 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, ssd->sensor = sensor; - if (ssd == sensor->pixel_array) { - ssd->npads = 1; - } else { - ssd->npads = 2; - ssd->source_pad = 1; - } + ssd->npads = num_pads; + ssd->source_pad = num_pads - 1; snprintf(ssd->sd.name, sizeof(ssd->sd.name), "%s %s %d-%4.4x", sensor->minfo.name, @@ -2747,9 +2744,9 @@ static int smiapp_init(struct smiapp_sensor *sensor) if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; - smiapp_create_subdev(sensor, sensor->scaler, "scaler"); - smiapp_create_subdev(sensor, sensor->binner, "binner"); - smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array"); + smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2); + smiapp_create_subdev(sensor, sensor->binner, "binner", 2); + smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1); dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); -- cgit v1.2.3 From 6d8d61fe661aa6466ed709e5459cd3255dea87b9 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 10:04:52 -0300 Subject: [media] smiapp: Initialise media entity after sensor init This allows determining the number of pads in the entity based on the sensor. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 2090b7f2b9aa..4f9750324150 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -3058,12 +3058,7 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->sd.internal_ops = &smiapp_internal_src_ops; sensor->src->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sensor->src->sensor = sensor; - sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; - rval = media_entity_pads_init(&sensor->src->sd.entity, 2, - sensor->src->pads); - if (rval < 0) - return rval; if (client->dev.of_node) { rval = smiapp_init(sensor); @@ -3071,6 +3066,11 @@ static int smiapp_probe(struct i2c_client *client, goto out_media_entity_cleanup; } + rval = media_entity_pads_init(&sensor->src->sd.entity, 2, + sensor->src->pads); + if (rval < 0) + goto out_media_entity_cleanup; + rval = v4l2_async_register_subdev(&sensor->src->sd); if (rval < 0) goto out_media_entity_cleanup; -- cgit v1.2.3 From 2fca9ca0d6fb172ab4c01f506fc864f2881b6f80 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 10:21:10 -0300 Subject: [media] smiapp: Split off sub-device registration into two Remove the loop in sub-device registration and create each sub-device explicitly instead. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 82 +++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 4f9750324150..86c0d7c6bf83 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2475,54 +2475,62 @@ static const struct v4l2_subdev_ops smiapp_ops; static const struct v4l2_subdev_internal_ops smiapp_internal_ops; static const struct media_entity_operations smiapp_entity_ops; -static int smiapp_register_subdevs(struct smiapp_sensor *sensor) +static int smiapp_register_subdev(struct smiapp_sensor *sensor, + struct smiapp_subdev *ssd, + struct smiapp_subdev *sink_ssd, + u16 source_pad, u16 sink_pad, u32 link_flags) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); - struct smiapp_subdev *ssds[] = { - sensor->scaler, - sensor->binner, - sensor->pixel_array, - }; - unsigned int i; int rval; - for (i = 0; i < SMIAPP_SUBDEVS - 1; i++) { - struct smiapp_subdev *this = ssds[i + 1]; - struct smiapp_subdev *last = ssds[i]; + if (!sink_ssd) + return 0; - if (!last) - continue; + rval = media_entity_pads_init(&ssd->sd.entity, + ssd->npads, ssd->pads); + if (rval) { + dev_err(&client->dev, + "media_entity_pads_init failed\n"); + return rval; + } - rval = media_entity_pads_init(&this->sd.entity, - this->npads, this->pads); - if (rval) { - dev_err(&client->dev, - "media_entity_pads_init failed\n"); - return rval; - } + rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, + &ssd->sd); + if (rval) { + dev_err(&client->dev, + "v4l2_device_register_subdev failed\n"); + return rval; + } - rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, - &this->sd); - if (rval) { - dev_err(&client->dev, - "v4l2_device_register_subdev failed\n"); - return rval; - } + rval = media_create_pad_link(&ssd->sd.entity, source_pad, + &sink_ssd->sd.entity, sink_pad, + link_flags); + if (rval) { + dev_err(&client->dev, + "media_create_pad_link failed\n"); + return rval; + } - rval = media_create_pad_link(&this->sd.entity, - this->source_pad, - &last->sd.entity, - last->sink_pad, - MEDIA_LNK_FL_ENABLED | - MEDIA_LNK_FL_IMMUTABLE); - if (rval) { - dev_err(&client->dev, - "media_create_pad_link failed\n"); + return 0; +} + +static int smiapp_register_subdevs(struct smiapp_sensor *sensor) +{ + int rval; + + if (sensor->scaler) { + rval = smiapp_register_subdev( + sensor, sensor->binner, sensor->scaler, + SMIAPP_PAD_SRC, SMIAPP_PAD_SINK, + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + if (rval < 0) return rval; - } } - return 0; + return smiapp_register_subdev( + sensor, sensor->pixel_array, sensor->binner, + SMIAPP_PA_PAD_SRC, SMIAPP_PAD_SINK, + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); } static void smiapp_cleanup(struct smiapp_sensor *sensor) -- cgit v1.2.3 From 6c5ff7c8e8800c95be96c59f02ea31b8860ad745 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 12:15:15 -0300 Subject: [media] smiapp: Provide a common function to obtain native pixel array size The same pixel array size is required for the active format of each sub-device sink pad and try format of each sink pad of each opened file handle as well as for the native size rectangle. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 39 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 86c0d7c6bf83..e5d458420922 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2161,6 +2161,15 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, return 0; } +static void smiapp_get_native_size(struct smiapp_subdev *ssd, + struct v4l2_rect *r) +{ + r->top = 0; + r->left = 0; + r->width = ssd->sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; + r->height = ssd->sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; +} + static int __smiapp_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) @@ -2192,17 +2201,12 @@ static int __smiapp_get_selection(struct v4l2_subdev *subdev, switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_NATIVE_SIZE: - if (ssd == sensor->pixel_array) { - sel->r.left = sel->r.top = 0; - sel->r.width = - sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; - sel->r.height = - sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; - } else if (sel->pad == ssd->sink_pad) { + if (ssd == sensor->pixel_array) + smiapp_get_native_size(ssd, &sel->r); + else if (sel->pad == ssd->sink_pad) sel->r = sink_fmt; - } else { + else sel->r = *comp; - } break; case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_COMPOSE_BOUNDS: @@ -2564,10 +2568,8 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, sizeof(ssd->sd.name), "%s %s %d-%4.4x", sensor->minfo.name, name, i2c_adapter_id(client->adapter), client->addr); - ssd->sink_fmt.width = - sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; - ssd->sink_fmt.height = - sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; + smiapp_get_native_size(ssd, &ssd->sink_fmt); + ssd->compose.width = ssd->sink_fmt.width; ssd->compose.height = ssd->sink_fmt.height; ssd->crop[ssd->source_pad] = ssd->compose; @@ -2840,16 +2842,13 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, i); struct v4l2_rect *try_comp; - try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; - try_fmt->height = sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1; + smiapp_get_native_size(ssd, try_crop); + + try_fmt->width = try_crop->width; + try_fmt->height = try_crop->height; try_fmt->code = mbus_code; try_fmt->field = V4L2_FIELD_NONE; - try_crop->top = 0; - try_crop->left = 0; - try_crop->width = try_fmt->width; - try_crop->height = try_fmt->height; - if (ssd != sensor->pixel_array) continue; -- cgit v1.2.3 From 624e9896c5bffee146ebb05b9366f8dc3f8b54aa Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Sep 2016 09:51:17 -0300 Subject: [media] smiapp: Remove unnecessary BUG_ON()'s Instead, calculate how much is needed and then allocate the memory dynamically. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 24 ++++++++++++++++++------ drivers/media/i2c/smiapp/smiapp.h | 8 ++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index e5d458420922..9873b3d764db 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -621,7 +621,7 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor) static int smiapp_init_late_controls(struct smiapp_sensor *sensor) { unsigned long *valid_link_freqs = &sensor->valid_link_freqs[ - sensor->csi_format->compressed - SMIAPP_COMPRESSED_BASE]; + sensor->csi_format->compressed - sensor->compressed_min_bpp]; unsigned int max, i; for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) { @@ -754,6 +754,7 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct smiapp_pll *pll = &sensor->pll; + u8 compressed_max_bpp = 0; unsigned int type, n; unsigned int i, pixel_order; int rval; @@ -825,17 +826,28 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) pll->binning_vertical = 1; pll->scale_m = sensor->scale_m; + for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) { + sensor->compressed_min_bpp = + min(smiapp_csi_data_formats[i].compressed, + sensor->compressed_min_bpp); + compressed_max_bpp = + max(smiapp_csi_data_formats[i].compressed, + compressed_max_bpp); + } + + sensor->valid_link_freqs = devm_kcalloc( + &client->dev, + compressed_max_bpp - sensor->compressed_min_bpp + 1, + sizeof(*sensor->valid_link_freqs), GFP_KERNEL); + for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) { const struct smiapp_csi_data_format *f = &smiapp_csi_data_formats[i]; unsigned long *valid_link_freqs = &sensor->valid_link_freqs[ - f->compressed - SMIAPP_COMPRESSED_BASE]; + f->compressed - sensor->compressed_min_bpp]; unsigned int j; - BUG_ON(f->compressed < SMIAPP_COMPRESSED_BASE); - BUG_ON(f->compressed > SMIAPP_COMPRESSED_MAX); - if (!(sensor->default_mbus_frame_fmts & 1 << i)) continue; @@ -1769,7 +1781,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, valid_link_freqs = &sensor->valid_link_freqs[sensor->csi_format->compressed - - SMIAPP_COMPRESSED_BASE]; + - sensor->compressed_min_bpp]; __v4l2_ctrl_modify_range( sensor->link_freq, 0, diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index aae72bc87bf7..e71271ef764b 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -150,11 +150,6 @@ struct smiapp_csi_data_format { #define SMIAPP_PAD_SRC 1 #define SMIAPP_PADS 2 -#define SMIAPP_COMPRESSED_BASE 8 -#define SMIAPP_COMPRESSED_MAX 16 -#define SMIAPP_NR_OF_COMPRESSED (SMIAPP_COMPRESSED_MAX - \ - SMIAPP_COMPRESSED_BASE + 1) - struct smiapp_binning_subtype { u8 horizontal:4; u8 vertical:4; @@ -224,6 +219,7 @@ struct smiapp_sensor { bool streaming; bool dev_init_done; + u8 compressed_min_bpp; u8 *nvm; /* nvm memory buffer */ unsigned int nvm_size; /* bytes */ @@ -233,7 +229,7 @@ struct smiapp_sensor { struct smiapp_pll pll; /* Is a default format supported for a given BPP? */ - unsigned long valid_link_freqs[SMIAPP_NR_OF_COMPRESSED]; + unsigned long *valid_link_freqs; /* Pixel array controls */ struct v4l2_ctrl *analog_gain; -- cgit v1.2.3 From 231d1a014aeb8c2288316572f2fe876c5145b91c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 7 Sep 2016 06:40:13 -0300 Subject: [media] smiapp: Always initialise the sensor in probe Initialise the sensor in probe. The reason why it wasn't previously done in case of platform data was that the probe() of the driver that provided the clock through the set_xclk() callback would need to finish before the probe() function of the smiapp driver. The set_xclk() callback no longer exists. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 9873b3d764db..8a58c641bc47 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2530,8 +2530,9 @@ static int smiapp_register_subdev(struct smiapp_sensor *sensor, return 0; } -static int smiapp_register_subdevs(struct smiapp_sensor *sensor) +static int smiapp_registered(struct v4l2_subdev *subdev) { + struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); int rval; if (sensor->scaler) { @@ -2819,25 +2820,6 @@ out_power_off: return rval; } -static int smiapp_registered(struct v4l2_subdev *subdev) -{ - struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); - struct i2c_client *client = v4l2_get_subdevdata(subdev); - int rval; - - if (!client->dev.of_node) { - rval = smiapp_init(sensor); - if (rval) - return rval; - } - - rval = smiapp_register_subdevs(sensor); - if (rval) - smiapp_cleanup(sensor); - - return rval; -} - static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct smiapp_subdev *ssd = to_smiapp_subdev(sd); @@ -3079,11 +3061,9 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->sensor = sensor; sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; - if (client->dev.of_node) { - rval = smiapp_init(sensor); - if (rval) - goto out_media_entity_cleanup; - } + rval = smiapp_init(sensor); + if (rval) + goto out_media_entity_cleanup; rval = media_entity_pads_init(&sensor->src->sd.entity, 2, sensor->src->pads); -- cgit v1.2.3 From 997695407512c3d0a7bf2f5e589ab288ac6d0f6b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 19 Sep 2016 18:41:14 -0300 Subject: [media] smiapp: Fix resource management in registration failure If the registered() callback failed, resources were left unaccounted for. Fix this, as well as add unregistering the sub-devices in driver unregistered() callback. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 8a58c641bc47..9d7af8b2ae8e 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2524,12 +2524,22 @@ static int smiapp_register_subdev(struct smiapp_sensor *sensor, if (rval) { dev_err(&client->dev, "media_create_pad_link failed\n"); + v4l2_device_unregister_subdev(&ssd->sd); return rval; } return 0; } +static void smiapp_unregistered(struct v4l2_subdev *subdev) +{ + struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); + unsigned int i; + + for (i = 1; i < sensor->ssds_used; i++) + v4l2_device_unregister_subdev(&sensor->ssds[i].sd); +} + static int smiapp_registered(struct v4l2_subdev *subdev) { struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); @@ -2544,10 +2554,19 @@ static int smiapp_registered(struct v4l2_subdev *subdev) return rval; } - return smiapp_register_subdev( + rval = smiapp_register_subdev( sensor, sensor->pixel_array, sensor->binner, SMIAPP_PA_PAD_SRC, SMIAPP_PAD_SINK, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + if (rval) + goto out_err; + + return 0; + +out_err: + smiapp_unregistered(subdev); + + return rval; } static void smiapp_cleanup(struct smiapp_sensor *sensor) @@ -2894,6 +2913,7 @@ static const struct media_entity_operations smiapp_entity_ops = { static const struct v4l2_subdev_internal_ops smiapp_internal_src_ops = { .registered = smiapp_registered, + .unregistered = smiapp_unregistered, .open = smiapp_open, .close = smiapp_close, }; -- cgit v1.2.3 From 3ecb86641b20c98f01df31ee0e22d36cc28660aa Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 12 Sep 2016 06:44:35 -0300 Subject: [media] smiapp: Merge smiapp_init() with smiapp_probe() The smiapp_probe() is the sole caller of smiapp_init(). Unify the two. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 423 ++++++++++++++++----------------- 1 file changed, 204 insertions(+), 219 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 9d7af8b2ae8e..384a13b9733b 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2622,223 +2622,6 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, v4l2_set_subdevdata(&ssd->sd, client); } -static int smiapp_init(struct smiapp_sensor *sensor) -{ - struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); - struct smiapp_pll *pll = &sensor->pll; - unsigned int i; - int rval; - - sensor->vana = devm_regulator_get(&client->dev, "vana"); - if (IS_ERR(sensor->vana)) { - dev_err(&client->dev, "could not get regulator for vana\n"); - return PTR_ERR(sensor->vana); - } - - sensor->ext_clk = devm_clk_get(&client->dev, NULL); - if (IS_ERR(sensor->ext_clk)) { - dev_err(&client->dev, "could not get clock (%ld)\n", - PTR_ERR(sensor->ext_clk)); - return -EPROBE_DEFER; - } - - rval = clk_set_rate(sensor->ext_clk, - sensor->hwcfg->ext_clk); - if (rval < 0) { - dev_err(&client->dev, - "unable to set clock freq to %u\n", - sensor->hwcfg->ext_clk); - return rval; - } - - sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown", - GPIOD_OUT_LOW); - if (IS_ERR(sensor->xshutdown)) - return PTR_ERR(sensor->xshutdown); - - rval = smiapp_power_on(sensor); - if (rval) - return -ENODEV; - - rval = smiapp_identify_module(sensor); - if (rval) { - rval = -ENODEV; - goto out_power_off; - } - - rval = smiapp_get_all_limits(sensor); - if (rval) { - rval = -ENODEV; - goto out_power_off; - } - - /* - * Handle Sensor Module orientation on the board. - * - * The application of H-FLIP and V-FLIP on the sensor is modified by - * the sensor orientation on the board. - * - * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set - * both H-FLIP and V-FLIP for normal operation which also implies - * that a set/unset operation for user space HFLIP and VFLIP v4l2 - * controls will need to be internally inverted. - * - * Rotation also changes the bayer pattern. - */ - if (sensor->hwcfg->module_board_orient == - SMIAPP_MODULE_BOARD_ORIENT_180) - sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP | - SMIAPP_IMAGE_ORIENTATION_VFLIP; - - rval = smiapp_call_quirk(sensor, limits); - if (rval) { - dev_err(&client->dev, "limits quirks failed\n"); - goto out_power_off; - } - - if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) { - u32 val; - - rval = smiapp_read(sensor, - SMIAPP_REG_U8_BINNING_SUBTYPES, &val); - if (rval < 0) { - rval = -ENODEV; - goto out_power_off; - } - sensor->nbinning_subtypes = min_t(u8, val, - SMIAPP_BINNING_SUBTYPES); - - for (i = 0; i < sensor->nbinning_subtypes; i++) { - rval = smiapp_read( - sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val); - if (rval < 0) { - rval = -ENODEV; - goto out_power_off; - } - sensor->binning_subtypes[i] = - *(struct smiapp_binning_subtype *)&val; - - dev_dbg(&client->dev, "binning %xx%x\n", - sensor->binning_subtypes[i].horizontal, - sensor->binning_subtypes[i].vertical); - } - } - sensor->binning_horizontal = 1; - sensor->binning_vertical = 1; - - if (device_create_file(&client->dev, &dev_attr_ident) != 0) { - dev_err(&client->dev, "sysfs ident entry creation failed\n"); - rval = -ENOENT; - goto out_power_off; - } - /* SMIA++ NVM initialization - it will be read from the sensor - * when it is first requested by userspace. - */ - if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) { - sensor->nvm = devm_kzalloc(&client->dev, - sensor->hwcfg->nvm_size, GFP_KERNEL); - if (sensor->nvm == NULL) { - dev_err(&client->dev, "nvm buf allocation failed\n"); - rval = -ENOMEM; - goto out_cleanup; - } - - if (device_create_file(&client->dev, &dev_attr_nvm) != 0) { - dev_err(&client->dev, "sysfs nvm entry failed\n"); - rval = -EBUSY; - goto out_cleanup; - } - } - - /* We consider this as profile 0 sensor if any of these are zero. */ - if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] || - !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] || - !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] || - !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) { - sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0; - } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY] - != SMIAPP_SCALING_CAPABILITY_NONE) { - if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY] - == SMIAPP_SCALING_CAPABILITY_HORIZONTAL) - sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1; - else - sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2; - sensor->scaler = &sensor->ssds[sensor->ssds_used]; - sensor->ssds_used++; - } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY] - == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) { - sensor->scaler = &sensor->ssds[sensor->ssds_used]; - sensor->ssds_used++; - } - sensor->binner = &sensor->ssds[sensor->ssds_used]; - sensor->ssds_used++; - sensor->pixel_array = &sensor->ssds[sensor->ssds_used]; - sensor->ssds_used++; - - sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; - - /* prepare PLL configuration input values */ - pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; - pll->csi2.lanes = sensor->hwcfg->lanes; - pll->ext_clk_freq_hz = sensor->hwcfg->ext_clk; - pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; - /* Profile 0 sensors have no separate OP clock branch. */ - if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) - pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; - - smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2); - smiapp_create_subdev(sensor, sensor->binner, "binner", 2); - smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1); - - dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); - - sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - /* final steps */ - smiapp_read_frame_fmt(sensor); - rval = smiapp_init_controls(sensor); - if (rval < 0) - goto out_cleanup; - - rval = smiapp_call_quirk(sensor, init); - if (rval) - goto out_cleanup; - - rval = smiapp_get_mbus_formats(sensor); - if (rval) { - rval = -ENODEV; - goto out_cleanup; - } - - rval = smiapp_init_late_controls(sensor); - if (rval) { - rval = -ENODEV; - goto out_cleanup; - } - - mutex_lock(&sensor->mutex); - rval = smiapp_update_mode(sensor); - mutex_unlock(&sensor->mutex); - if (rval) { - dev_err(&client->dev, "update mode failed\n"); - goto out_cleanup; - } - - sensor->streaming = false; - sensor->dev_init_done = true; - - smiapp_power_off(sensor); - - return 0; - -out_cleanup: - smiapp_cleanup(sensor); - -out_power_off: - smiapp_power_off(sensor); - return rval; -} - static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct smiapp_subdev *ssd = to_smiapp_subdev(sd); @@ -3061,6 +2844,7 @@ static int smiapp_probe(struct i2c_client *client, { struct smiapp_sensor *sensor; struct smiapp_hwconfig *hwcfg = smiapp_get_hwconfig(&client->dev); + unsigned int i; int rval; if (hwcfg == NULL) @@ -3081,9 +2865,205 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->sensor = sensor; sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; - rval = smiapp_init(sensor); + sensor->vana = devm_regulator_get(&client->dev, "vana"); + if (IS_ERR(sensor->vana)) { + dev_err(&client->dev, "could not get regulator for vana\n"); + return PTR_ERR(sensor->vana); + } + + sensor->ext_clk = devm_clk_get(&client->dev, NULL); + if (IS_ERR(sensor->ext_clk)) { + dev_err(&client->dev, "could not get clock (%ld)\n", + PTR_ERR(sensor->ext_clk)); + return -EPROBE_DEFER; + } + + rval = clk_set_rate(sensor->ext_clk, + sensor->hwcfg->ext_clk); + if (rval < 0) { + dev_err(&client->dev, + "unable to set clock freq to %u\n", + sensor->hwcfg->ext_clk); + return rval; + } + + sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown", + GPIOD_OUT_LOW); + if (IS_ERR(sensor->xshutdown)) + return PTR_ERR(sensor->xshutdown); + + rval = smiapp_power_on(sensor); if (rval) - goto out_media_entity_cleanup; + return -ENODEV; + + rval = smiapp_identify_module(sensor); + if (rval) { + rval = -ENODEV; + goto out_power_off; + } + + rval = smiapp_get_all_limits(sensor); + if (rval) { + rval = -ENODEV; + goto out_power_off; + } + + /* + * Handle Sensor Module orientation on the board. + * + * The application of H-FLIP and V-FLIP on the sensor is modified by + * the sensor orientation on the board. + * + * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set + * both H-FLIP and V-FLIP for normal operation which also implies + * that a set/unset operation for user space HFLIP and VFLIP v4l2 + * controls will need to be internally inverted. + * + * Rotation also changes the bayer pattern. + */ + if (sensor->hwcfg->module_board_orient == + SMIAPP_MODULE_BOARD_ORIENT_180) + sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP | + SMIAPP_IMAGE_ORIENTATION_VFLIP; + + rval = smiapp_call_quirk(sensor, limits); + if (rval) { + dev_err(&client->dev, "limits quirks failed\n"); + goto out_power_off; + } + + if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) { + u32 val; + + rval = smiapp_read(sensor, + SMIAPP_REG_U8_BINNING_SUBTYPES, &val); + if (rval < 0) { + rval = -ENODEV; + goto out_power_off; + } + sensor->nbinning_subtypes = min_t(u8, val, + SMIAPP_BINNING_SUBTYPES); + + for (i = 0; i < sensor->nbinning_subtypes; i++) { + rval = smiapp_read( + sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val); + if (rval < 0) { + rval = -ENODEV; + goto out_power_off; + } + sensor->binning_subtypes[i] = + *(struct smiapp_binning_subtype *)&val; + + dev_dbg(&client->dev, "binning %xx%x\n", + sensor->binning_subtypes[i].horizontal, + sensor->binning_subtypes[i].vertical); + } + } + sensor->binning_horizontal = 1; + sensor->binning_vertical = 1; + + if (device_create_file(&client->dev, &dev_attr_ident) != 0) { + dev_err(&client->dev, "sysfs ident entry creation failed\n"); + rval = -ENOENT; + goto out_power_off; + } + /* SMIA++ NVM initialization - it will be read from the sensor + * when it is first requested by userspace. + */ + if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) { + sensor->nvm = devm_kzalloc(&client->dev, + sensor->hwcfg->nvm_size, GFP_KERNEL); + if (sensor->nvm == NULL) { + dev_err(&client->dev, "nvm buf allocation failed\n"); + rval = -ENOMEM; + goto out_cleanup; + } + + if (device_create_file(&client->dev, &dev_attr_nvm) != 0) { + dev_err(&client->dev, "sysfs nvm entry failed\n"); + rval = -EBUSY; + goto out_cleanup; + } + } + + /* We consider this as profile 0 sensor if any of these are zero. */ + if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] || + !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] || + !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] || + !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) { + sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0; + } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY] + != SMIAPP_SCALING_CAPABILITY_NONE) { + if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY] + == SMIAPP_SCALING_CAPABILITY_HORIZONTAL) + sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1; + else + sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2; + sensor->scaler = &sensor->ssds[sensor->ssds_used]; + sensor->ssds_used++; + } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY] + == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) { + sensor->scaler = &sensor->ssds[sensor->ssds_used]; + sensor->ssds_used++; + } + sensor->binner = &sensor->ssds[sensor->ssds_used]; + sensor->ssds_used++; + sensor->pixel_array = &sensor->ssds[sensor->ssds_used]; + sensor->ssds_used++; + + sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; + + /* prepare PLL configuration input values */ + sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; + sensor->pll.csi2.lanes = sensor->hwcfg->lanes; + sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk; + sensor->pll.scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; + /* Profile 0 sensors have no separate OP clock branch. */ + if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) + sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; + + smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2); + smiapp_create_subdev(sensor, sensor->binner, "binner", 2); + smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1); + + dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); + + sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + + /* final steps */ + smiapp_read_frame_fmt(sensor); + rval = smiapp_init_controls(sensor); + if (rval < 0) + goto out_cleanup; + + rval = smiapp_call_quirk(sensor, init); + if (rval) + goto out_cleanup; + + rval = smiapp_get_mbus_formats(sensor); + if (rval) { + rval = -ENODEV; + goto out_cleanup; + } + + rval = smiapp_init_late_controls(sensor); + if (rval) { + rval = -ENODEV; + goto out_cleanup; + } + + mutex_lock(&sensor->mutex); + rval = smiapp_update_mode(sensor); + mutex_unlock(&sensor->mutex); + if (rval) { + dev_err(&client->dev, "update mode failed\n"); + goto out_cleanup; + } + + sensor->streaming = false; + sensor->dev_init_done = true; + + smiapp_power_off(sensor); rval = media_entity_pads_init(&sensor->src->sd.entity, 2, sensor->src->pads); @@ -3099,6 +3079,11 @@ static int smiapp_probe(struct i2c_client *client, out_media_entity_cleanup: media_entity_cleanup(&sensor->src->sd.entity); +out_cleanup: + smiapp_cleanup(sensor); + +out_power_off: + smiapp_power_off(sensor); return rval; } -- cgit v1.2.3 From 1344bf74c93b87fdc5c8d4f1612470b4c3c2906f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 7 Sep 2016 07:37:47 -0300 Subject: [media] smiapp: Read frame format earlier The information gathered during frame format reading will be required earlier in the initialisation when it was available. Also return an error if frame format cannot be obtained. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 384a13b9733b..6ec17eab70ac 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2908,6 +2908,12 @@ static int smiapp_probe(struct i2c_client *client, goto out_power_off; } + rval = smiapp_read_frame_fmt(sensor); + if (rval) { + rval = -ENODEV; + goto out_power_off; + } + /* * Handle Sensor Module orientation on the board. * @@ -3030,8 +3036,6 @@ static int smiapp_probe(struct i2c_client *client, sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - /* final steps */ - smiapp_read_frame_fmt(sensor); rval = smiapp_init_controls(sensor); if (rval < 0) goto out_cleanup; -- cgit v1.2.3 From a118e61edc3e54bd727a6f6d7193e40270cd3711 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 7 Sep 2016 08:55:34 -0300 Subject: [media] smiapp: Unify setting up sub-devices The initialisation of the source sub-device is somewhat different as it's not created by the smiapp driver itself. Remove redundancy in initialising the two kind of sub-devices. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 6ec17eab70ac..7ac0d4e0cc89 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2591,6 +2591,7 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, if (ssd != sensor->src) v4l2_subdev_init(&ssd->sd, &smiapp_ops); + ssd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ssd->sensor = sensor; ssd->npads = num_pads; @@ -2616,7 +2617,6 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, if (ssd == sensor->src) return; - ssd->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ssd->sd.internal_ops = &smiapp_internal_ops; ssd->sd.owner = THIS_MODULE; v4l2_set_subdevdata(&ssd->sd, client); @@ -2861,9 +2861,6 @@ static int smiapp_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops); sensor->src->sd.internal_ops = &smiapp_internal_src_ops; - sensor->src->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - sensor->src->sensor = sensor; - sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; sensor->vana = devm_regulator_get(&client->dev, "vana"); if (IS_ERR(sensor->vana)) { -- cgit v1.2.3 From df0e40339b48e149f25da9010bc92a39afbf5e66 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 7 Sep 2016 08:39:52 -0300 Subject: [media] smiapp: Use SMIAPP_PADS when referring to number of pads Replace plain value 2 with SMIAPP_PADS when referring to the number of pads. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index e71271ef764b..f9febe0a056d 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -157,9 +157,9 @@ struct smiapp_binning_subtype { struct smiapp_subdev { struct v4l2_subdev sd; - struct media_pad pads[2]; + struct media_pad pads[SMIAPP_PADS]; struct v4l2_rect sink_fmt; - struct v4l2_rect crop[2]; + struct v4l2_rect crop[SMIAPP_PADS]; struct v4l2_rect compose; /* compose on sink */ unsigned short sink_pad; unsigned short source_pad; -- cgit v1.2.3 From 3fc34b7beb89472b61f919ec0f8699e2a3b46d94 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 5 Sep 2016 08:18:34 -0300 Subject: [media] smiapp: Obtain frame layout from the frame descriptor Besides the image data, SMIA++ compliant sensors also provide embedded data in form of registers used to capture the image. Store this information for later use in frame descriptor and routing. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 46 +++++++++++++++++++--------------- drivers/media/i2c/smiapp/smiapp.h | 5 +++- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 7ac0d4e0cc89..a7afcea5a5c5 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -68,10 +68,9 @@ static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); u32 fmt_model_type, fmt_model_subtype, ncol_desc, nrow_desc; unsigned int i; - int rval; + int pixel_count = 0; int line_count = 0; - int embedded_start = -1, embedded_end = -1; - int image_start = 0; + int rval; rval = smiapp_read(sensor, SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE, &fmt_model_type); @@ -166,33 +165,40 @@ static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "%s pixels: %d %s\n", what, pixels, which); - if (i < ncol_desc) + if (i < ncol_desc) { + if (pixelcode == + SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE) + sensor->visible_pixel_start = pixel_count; + pixel_count += pixels; continue; + } /* Handle row descriptors */ - if (pixelcode - == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED) { - embedded_start = line_count; - } else { - if (pixelcode == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE - || pixels >= sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES] / 2) - image_start = line_count; - if (embedded_start != -1 && embedded_end == -1) - embedded_end = line_count; + switch (pixelcode) { + case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED: + if (sensor->embedded_end) + break; + sensor->embedded_start = line_count; + sensor->embedded_end = line_count + pixels; + break; + case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE: + sensor->image_start = line_count; + break; } line_count += pixels; } - if (embedded_start == -1 || embedded_end == -1) { - embedded_start = 0; - embedded_end = 0; + if (sensor->embedded_end > sensor->image_start) { + dev_dbg(&client->dev, + "adjusting image start line to %u (was %u)\n", + sensor->embedded_end, sensor->image_start); + sensor->image_start = sensor->embedded_end; } - sensor->image_start = image_start; - dev_dbg(&client->dev, "embedded data from lines %d to %d\n", - embedded_start, embedded_end); - dev_dbg(&client->dev, "image data starts at line %d\n", image_start); + sensor->embedded_start, sensor->embedded_end); + dev_dbg(&client->dev, "image data starts at line %d\n", + sensor->image_start); return 0; } diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index f9febe0a056d..d7b52a61af4f 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -213,7 +213,10 @@ struct smiapp_sensor { u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */ u8 frame_skip; - u16 image_start; /* Offset to first line after metadata lines */ + u16 embedded_start; /* embedded data start line */ + u16 embedded_end; + u16 image_start; /* image data start line */ + u16 visible_pixel_start; /* start pixel of the visible image */ int power_count; -- cgit v1.2.3 From e43665a9d7b41b4b35069e7d3cf29e8a8a40d554 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 7 Sep 2016 09:53:42 -0300 Subject: [media] smiapp: Improve debug messages from frame layout reading Provide more debugging information on reading the frame layout. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index a7afcea5a5c5..1337b22e2380 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -100,12 +100,11 @@ static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor) u32 pixels; char *which; char *what; + u32 reg; if (fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE) { - rval = smiapp_read( - sensor, - SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(i), - &desc); + reg = SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(i); + rval = smiapp_read(sensor, reg, &desc); if (rval) return rval; @@ -116,10 +115,8 @@ static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor) pixels = desc & SMIAPP_FRAME_FORMAT_DESC_2_PIXELS_MASK; } else if (fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE) { - rval = smiapp_read( - sensor, - SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(i), - &desc); + reg = SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(i); + rval = smiapp_read(sensor, reg, &desc); if (rval) return rval; @@ -158,12 +155,12 @@ static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor) break; default: what = "invalid"; - dev_dbg(&client->dev, "pixelcode %d\n", pixelcode); break; } - dev_dbg(&client->dev, "%s pixels: %d %s\n", - what, pixels, which); + dev_dbg(&client->dev, + "0x%8.8x %s pixels: %d %s (pixelcode %u)\n", reg, + what, pixels, which, pixelcode); if (i < ncol_desc) { if (pixelcode == -- cgit v1.2.3 From 2aa8e838a303c7c9ed4b2761eb8ffe0930320d24 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 8 Sep 2016 05:46:47 -0300 Subject: [media] smiapp: Remove useless newlines and other small cleanups The code probably has been unindented at some point but rewrapping has not been done. Do it now. Also remove a useless memory allocation failure message. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 1337b22e2380..2e8b7bf32c87 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -446,8 +446,7 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP; orient ^= sensor->hvflip_inv_mask; - rval = smiapp_write(sensor, - SMIAPP_REG_U8_IMAGE_ORIENTATION, + rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION, orient); if (rval < 0) return rval; @@ -462,10 +461,8 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) __smiapp_update_exposure_limits(sensor); if (exposure > sensor->exposure->maximum) { - sensor->exposure->val = - sensor->exposure->maximum; - rval = smiapp_set_ctrl( - sensor->exposure); + sensor->exposure->val = sensor->exposure->maximum; + rval = smiapp_set_ctrl(sensor->exposure); if (rval < 0) return rval; } @@ -1322,8 +1319,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) if (!sensor->pixel_array) return 0; - rval = v4l2_ctrl_handler_setup( - &sensor->pixel_array->ctrl_handler); + rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler); if (rval) goto out_cci_addr_fail; @@ -1629,7 +1625,8 @@ static int __smiapp_get_format(struct v4l2_subdev *subdev, struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(subdev, cfg, + fmt->pad); } else { struct v4l2_rect *r; @@ -1729,7 +1726,6 @@ static void smiapp_propagate(struct v4l2_subdev *subdev, static const struct smiapp_csi_data_format *smiapp_validate_csi_data_format(struct smiapp_sensor *sensor, u32 code) { - const struct smiapp_csi_data_format *csi_format = sensor->csi_format; unsigned int i; for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) { @@ -1738,7 +1734,7 @@ static const struct smiapp_csi_data_format return &smiapp_csi_data_formats[i]; } - return csi_format; + return sensor->csi_format; } static int smiapp_set_format_source(struct v4l2_subdev *subdev, @@ -2072,8 +2068,7 @@ static int smiapp_set_compose(struct v4l2_subdev *subdev, smiapp_set_compose_scaler(subdev, cfg, sel, crops, comp); *comp = sel->r; - smiapp_propagate(subdev, cfg, sel->which, - V4L2_SEL_TGT_COMPOSE); + smiapp_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_COMPOSE); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) return smiapp_update_mode(sensor); @@ -2150,9 +2145,8 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, ->height; src_size = &_r; } else { - src_size = - v4l2_subdev_get_try_compose( - subdev, cfg, ssd->sink_pad); + src_size = v4l2_subdev_get_try_compose( + subdev, cfg, ssd->sink_pad); } } @@ -2638,7 +2632,8 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) for (i = 0; i < ssd->npads; i++) { struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, i); - struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, i); + struct v4l2_rect *try_crop = + v4l2_subdev_get_try_crop(sd, fh->pad, i); struct v4l2_rect *try_comp; smiapp_get_native_size(ssd, try_crop); @@ -2878,8 +2873,7 @@ static int smiapp_probe(struct i2c_client *client, return -EPROBE_DEFER; } - rval = clk_set_rate(sensor->ext_clk, - sensor->hwcfg->ext_clk); + rval = clk_set_rate(sensor->ext_clk, sensor->hwcfg->ext_clk); if (rval < 0) { dev_err(&client->dev, "unable to set clock freq to %u\n", @@ -2980,7 +2974,6 @@ static int smiapp_probe(struct i2c_client *client, sensor->nvm = devm_kzalloc(&client->dev, sensor->hwcfg->nvm_size, GFP_KERNEL); if (sensor->nvm == NULL) { - dev_err(&client->dev, "nvm buf allocation failed\n"); rval = -ENOMEM; goto out_cleanup; } -- cgit v1.2.3 From 1b81717ed7be8a88345dde1e0cffcc31a7693d81 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 8 Sep 2016 05:49:27 -0300 Subject: [media] smiapp: Obtain correct media bus code for try format The media bus code obtained for try format may have been a code that the sensor did not even support. Use a supported code with the current pixel order. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 2e8b7bf32c87..5f4680d9d822 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2623,8 +2623,6 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct smiapp_subdev *ssd = to_smiapp_subdev(sd); struct smiapp_sensor *sensor = ssd->sensor; - u32 mbus_code = - smiapp_csi_data_formats[smiapp_pixel_order(sensor)].code; unsigned int i; mutex_lock(&sensor->mutex); @@ -2640,7 +2638,7 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) try_fmt->width = try_crop->width; try_fmt->height = try_crop->height; - try_fmt->code = mbus_code; + try_fmt->code = sensor->internal_csi_format->code; try_fmt->field = V4L2_FIELD_NONE; if (ssd != sensor->pixel_array) -- cgit v1.2.3 From fbffb28f0337801d284d13c3a559e85697726afb Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 8 Sep 2016 09:08:26 -0300 Subject: [media] smiapp: Drop a debug print on frame size and bit depth The first time the sensor is powered on, the information is not yet available. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 5f4680d9d822..8f9690e375bf 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -926,12 +926,6 @@ static int smiapp_update_mode(struct smiapp_sensor *sensor) unsigned int binning_mode; int rval; - dev_dbg(&client->dev, "frame size: %dx%d\n", - sensor->src->crop[SMIAPP_PAD_SRC].width, - sensor->src->crop[SMIAPP_PAD_SRC].height); - dev_dbg(&client->dev, "csi format width: %d\n", - sensor->csi_format->width); - /* Binning has to be set up here; it affects limits */ if (sensor->binning_horizontal == 1 && sensor->binning_vertical == 1) { -- cgit v1.2.3 From b08726bf2ea03d1eabf8908c70a3518fa502313b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 8 Sep 2016 10:50:07 -0300 Subject: [media] smiapp-pll: Don't complain aloud about failing PLL calculation Don't complain about a failure to compute the pre_pll divisor. The function is used to determine whether a particular combination of bits per sample value and a link frequency can be used, in which case there are lots of unnecessary driver messages. During normal operation the failure generally does not happen. Use dev_dbg() instead. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index e3348db56c46..771db56332b2 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -479,7 +479,8 @@ int smiapp_pll_calculate(struct device *dev, return 0; } - dev_info(dev, "unable to compute pre_pll divisor\n"); + dev_dbg(dev, "unable to compute pre_pll divisor\n"); + return rval; } EXPORT_SYMBOL_GPL(smiapp_pll_calculate); -- cgit v1.2.3 From 88b3e311b52679a5c81af6bb0495d2c45049bb07 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 Sep 2016 11:25:42 -0300 Subject: [media] smiapp: Drop BUG_ON() in suspend path Checking that the mutex is not acquired is unnecessary for user processes are stopped by this point. Drop the check. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 8f9690e375bf..1891c28ca6a4 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2709,8 +2709,6 @@ static int smiapp_suspend(struct device *dev) struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); bool streaming; - BUG_ON(mutex_is_locked(&sensor->mutex)); - if (sensor->power_count == 0) return 0; -- cgit v1.2.3 From df77542ede76774cfbdc852d0e09b6f800941be1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 Sep 2016 19:16:32 -0300 Subject: [media] smiapp: Set device for pixel array and binner The dev field of the v4l2_subdev was left NULL for the pixel array and binner sub-devices. Fix this. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 1891c28ca6a4..3ea4f12ecee2 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2610,6 +2610,7 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor, ssd->sd.internal_ops = &smiapp_internal_ops; ssd->sd.owner = THIS_MODULE; + ssd->sd.dev = &client->dev; v4l2_set_subdevdata(&ssd->sd, client); } -- cgit v1.2.3 From 4ecc2d75c0c5fc959d207ef90da19df7771d01c9 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 14 Sep 2016 11:58:17 -0300 Subject: [media] smiapp: Set use suspend and resume ops for other functions Use the suspend and resume ops for freeze, thaw, poweroff and restore callbacks as well. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 3ea4f12ecee2..88ad4b97ba85 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -3111,8 +3111,7 @@ static const struct i2c_device_id smiapp_id_table[] = { MODULE_DEVICE_TABLE(i2c, smiapp_id_table); static const struct dev_pm_ops smiapp_pm_ops = { - .suspend = smiapp_suspend, - .resume = smiapp_resume, + SET_SYSTEM_SLEEP_PM_OPS(smiapp_suspend, smiapp_resume) }; static struct i2c_driver smiapp_i2c_driver = { -- cgit v1.2.3 From cbba45d43631d0414266d7e79827da3f491f1b1e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 Sep 2016 10:01:03 -0300 Subject: [media] smiapp: Use runtime PM Switch to runtime PM in sensor power management. The internal power count is thus removed. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 131 +++++++++++++++++++++------------ drivers/media/i2c/smiapp/smiapp.h | 11 +-- 2 files changed, 83 insertions(+), 59 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 88ad4b97ba85..68adc1b28985 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1202,9 +1203,17 @@ out: * Power management */ -static int smiapp_power_on(struct smiapp_sensor *sensor) +static int smiapp_power_on(struct device *dev) { - struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *subdev = i2c_get_clientdata(client); + struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); + /* + * The sub-device related to the I2C device is always the + * source one, i.e. ssds[0]. + */ + struct smiapp_sensor *sensor = + container_of(ssd, struct smiapp_sensor, ssds[0]); unsigned int sleep; int rval; @@ -1330,16 +1339,24 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) return 0; out_cci_addr_fail: + gpiod_set_value(sensor->xshutdown, 0); clk_disable_unprepare(sensor->ext_clk); out_xclk_fail: regulator_disable(sensor->vana); + return rval; } -static void smiapp_power_off(struct smiapp_sensor *sensor) +static int smiapp_power_off(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *subdev = i2c_get_clientdata(client); + struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); + struct smiapp_sensor *sensor = + container_of(ssd, struct smiapp_sensor, ssds[0]); + /* * Currently power/clock to lens are enable/disabled separately * but they are essentially the same signals. So if the sensor is @@ -1357,31 +1374,26 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) usleep_range(5000, 5000); regulator_disable(sensor->vana); sensor->streaming = false; + + return 0; } static int smiapp_set_power(struct v4l2_subdev *subdev, int on) { - struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); - int ret = 0; + int rval = 0; - mutex_lock(&sensor->power_mutex); + if (on) { + rval = pm_runtime_get_sync(subdev->dev); + if (rval >= 0) + return 0; - if (on && !sensor->power_count) { - /* Power on and perform initialisation. */ - ret = smiapp_power_on(sensor); - if (ret < 0) - goto out; - } else if (!on && sensor->power_count == 1) { - smiapp_power_off(sensor); + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(subdev->dev); } - /* Update the power count. */ - sensor->power_count += on ? 1 : -1; - WARN_ON(sensor->power_count < 0); + pm_runtime_put(subdev->dev); -out: - mutex_unlock(&sensor->power_mutex); - return ret; + return rval; } /* ----------------------------------------------------------------------------- @@ -2310,15 +2322,25 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr, return -EBUSY; if (!sensor->nvm_size) { + int rval; + /* NVM not read yet - read it now */ sensor->nvm_size = sensor->hwcfg->nvm_size; - if (smiapp_set_power(subdev, 1) < 0) + + rval = pm_runtime_get_sync(&client->dev); + if (rval < 0) { + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(&client->dev); + pm_runtime_put(&client->dev); return -ENODEV; + } + if (smiapp_read_nvm(sensor, sensor->nvm)) { dev_err(&client->dev, "nvm read failed\n"); return -ENODEV; } - smiapp_set_power(subdev, 0); + + pm_runtime_put(&client->dev); } /* * NVM is still way below a PAGE_SIZE, so we can safely @@ -2619,6 +2641,7 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct smiapp_subdev *ssd = to_smiapp_subdev(sd); struct smiapp_sensor *sensor = ssd->sensor; unsigned int i; + int rval; mutex_lock(&sensor->mutex); @@ -2645,12 +2668,22 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_unlock(&sensor->mutex); - return smiapp_set_power(sd, 1); + rval = pm_runtime_get_sync(sd->dev); + if (rval >= 0) + return 0; + + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(sd->dev); + pm_runtime_put(sd->dev); + + return rval; } static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - return smiapp_set_power(sd, 0); + pm_runtime_put(sd->dev); + + return 0; } static const struct v4l2_subdev_video_ops smiapp_video_ops = { @@ -2708,18 +2741,20 @@ static int smiapp_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); - bool streaming; + bool streaming = sensor->streaming; + int rval; - if (sensor->power_count == 0) - return 0; + rval = pm_runtime_get_sync(dev); + if (rval < 0) { + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(&client->dev); + pm_runtime_put(dev); + return -EAGAIN; + } if (sensor->streaming) smiapp_stop_streaming(sensor); - streaming = sensor->streaming; - - smiapp_power_off(sensor); - /* save state for resume */ sensor->streaming = streaming; @@ -2731,14 +2766,9 @@ static int smiapp_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); - int rval; - - if (sensor->power_count == 0) - return 0; + int rval = 0; - rval = smiapp_power_on(sensor); - if (rval) - return rval; + pm_runtime_put(dev); if (sensor->streaming) rval = smiapp_start_streaming(sensor); @@ -2845,7 +2875,6 @@ static int smiapp_probe(struct i2c_client *client, sensor->hwcfg = hwcfg; mutex_init(&sensor->mutex); - mutex_init(&sensor->power_mutex); sensor->src = &sensor->ssds[sensor->ssds_used]; v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops); @@ -2877,9 +2906,13 @@ static int smiapp_probe(struct i2c_client *client, if (IS_ERR(sensor->xshutdown)) return PTR_ERR(sensor->xshutdown); - rval = smiapp_power_on(sensor); - if (rval) - return -ENODEV; + pm_runtime_enable(&client->dev); + + rval = pm_runtime_get_sync(&client->dev); + if (rval < 0) { + rval = -ENODEV; + goto out_power_off; + } rval = smiapp_identify_module(sensor); if (rval) { @@ -3051,8 +3084,6 @@ static int smiapp_probe(struct i2c_client *client, sensor->streaming = false; sensor->dev_init_done = true; - smiapp_power_off(sensor); - rval = media_entity_pads_init(&sensor->src->sd.entity, 2, sensor->src->pads); if (rval < 0) @@ -3062,6 +3093,8 @@ static int smiapp_probe(struct i2c_client *client, if (rval < 0) goto out_media_entity_cleanup; + pm_runtime_put(&client->dev); + return 0; out_media_entity_cleanup: @@ -3071,7 +3104,9 @@ out_cleanup: smiapp_cleanup(sensor); out_power_off: - smiapp_power_off(sensor); + pm_runtime_put(&client->dev); + pm_runtime_disable(&client->dev); + return rval; } @@ -3083,11 +3118,8 @@ static int smiapp_remove(struct i2c_client *client) v4l2_async_unregister_subdev(subdev); - if (sensor->power_count) { - gpiod_set_value(sensor->xshutdown, 0); - clk_disable_unprepare(sensor->ext_clk); - sensor->power_count = 0; - } + pm_runtime_suspend(&client->dev); + pm_runtime_disable(&client->dev); for (i = 0; i < sensor->ssds_used; i++) { v4l2_device_unregister_subdev(&sensor->ssds[i].sd); @@ -3112,6 +3144,7 @@ MODULE_DEVICE_TABLE(i2c, smiapp_id_table); static const struct dev_pm_ops smiapp_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(smiapp_suspend, smiapp_resume) + SET_RUNTIME_PM_OPS(smiapp_power_off, smiapp_power_on, NULL) }; static struct i2c_driver smiapp_i2c_driver = { diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index d7b52a61af4f..f74d695018b9 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -176,16 +176,9 @@ struct smiapp_sensor { * "mutex" is used to serialise access to all fields here * except v4l2_ctrls at the end of the struct. "mutex" is also * used to serialise access to file handle specific - * information. The exception to this rule is the power_mutex - * below. + * information. */ struct mutex mutex; - /* - * power_mutex is used to serialise power management related - * activities. Acquiring "mutex" at that time isn't necessary - * since there are no other users anyway. - */ - struct mutex power_mutex; struct smiapp_subdev ssds[SMIAPP_SUBDEVS]; u32 ssds_used; struct smiapp_subdev *src; @@ -218,8 +211,6 @@ struct smiapp_sensor { u16 image_start; /* image data start line */ u16 visible_pixel_start; /* start pixel of the visible image */ - int power_count; - bool streaming; bool dev_init_done; u8 compressed_min_bpp; -- cgit v1.2.3 From 93bef23024983d707248c25a849f5860119cd5e4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 14 Sep 2016 12:29:23 -0300 Subject: [media] smiapp: Implement support for autosuspend Delay suspending the device by 1000 ms by default. This is done on explicit power off through s_power() callback, through releasing the file descriptor, NVM read or when the probe finishes. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 68adc1b28985..59872b31f832 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -1380,17 +1380,22 @@ static int smiapp_power_off(struct device *dev) static int smiapp_set_power(struct v4l2_subdev *subdev, int on) { - int rval = 0; + int rval; - if (on) { - rval = pm_runtime_get_sync(subdev->dev); - if (rval >= 0) - return 0; + if (!on) { + pm_runtime_mark_last_busy(subdev->dev); + pm_runtime_put_autosuspend(subdev->dev); - if (rval != -EBUSY && rval != -EAGAIN) - pm_runtime_set_active(subdev->dev); + return 0; } + rval = pm_runtime_get_sync(subdev->dev); + if (rval >= 0) + return 0; + + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(subdev->dev); + pm_runtime_put(subdev->dev); return rval; @@ -2340,7 +2345,8 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr, return -ENODEV; } - pm_runtime_put(&client->dev); + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); } /* * NVM is still way below a PAGE_SIZE, so we can safely @@ -2681,7 +2687,8 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - pm_runtime_put(sd->dev); + pm_runtime_mark_last_busy(sd->dev); + pm_runtime_put_autosuspend(sd->dev); return 0; } @@ -3093,7 +3100,9 @@ static int smiapp_probe(struct i2c_client *client, if (rval < 0) goto out_media_entity_cleanup; - pm_runtime_put(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, 1000); + pm_runtime_use_autosuspend(&client->dev); + pm_runtime_put_autosuspend(&client->dev); return 0; -- cgit v1.2.3 From 66b2ab271afc0888b87a44dc946cc68067ba0985 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 18 Aug 2016 11:33:27 -0300 Subject: [media] videodev2.h Add HSV formats These formats store the color information of the image in a geometrical representation. The colors are mapped into a cylinder, where the angle is the HUE, the height is the VALUE and the distance to the center is the SATURATION. This is a very useful format for image segmentation algorithms. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++ include/uapi/linux/videodev2.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 39e19b4222be..181381d1dc77 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1200,6 +1200,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; + case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; + case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 2da477c04479..6b480c91778e 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -587,6 +587,10 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ +/* HSV formats */ +#define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') +#define V4L2_PIX_FMT_HSV32 v4l2_fourcc('H', 'S', 'V', '4') + /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ -- cgit v1.2.3 From 9bef7546b09fdefe56918f1d1aba55e08870cdad Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 18 Aug 2016 11:33:28 -0300 Subject: [media] Documentation: Add HSV format Describe the HSV formats Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/hsv-formats.rst | 19 +++ Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst | 156 +++++++++++++++++++++ Documentation/media/uapi/v4l/pixfmt.rst | 1 + Documentation/media/uapi/v4l/v4l2.rst | 5 + 4 files changed, 181 insertions(+) create mode 100644 Documentation/media/uapi/v4l/hsv-formats.rst create mode 100644 Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst diff --git a/Documentation/media/uapi/v4l/hsv-formats.rst b/Documentation/media/uapi/v4l/hsv-formats.rst new file mode 100644 index 000000000000..f0f2615eaa95 --- /dev/null +++ b/Documentation/media/uapi/v4l/hsv-formats.rst @@ -0,0 +1,19 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _hsv-formats: + +*********** +HSV Formats +*********** + +These formats store the color information of the image +in a geometrical representation. The colors are mapped into a +cylinder, where the angle is the HUE, the height is the VALUE +and the distance to the center is the SATURATION. This is a very +useful format for image segmentation algorithms. + + +.. toctree:: + :maxdepth: 1 + + pixfmt-packed-hsv diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst new file mode 100644 index 000000000000..4a579727f61c --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst @@ -0,0 +1,156 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _packed-hsv: + +****************** +Packed HSV formats +****************** + +Description +=========== + +The *hue* (h) is measured in degrees, one LSB represents two degrees. +The *saturation* (s) and the *value* (v) are measured in percentage of the +cylinder: 0 being the smallest value and 255 the maximum. + + +The values are packed in 24 or 32 bit formats. + +.. raw:: latex + + \newline\begin{adjustbox}{width=\columnwidth} + +.. tabularcolumns:: |p{4.2cm}|p{1.0cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| + +.. _packed-hsv-formats: + +.. flat-table:: Packed HSV Image Formats + :header-rows: 2 + :stub-columns: 0 + + * - Identifier + - Code + - + - :cspan:`7` Byte 0 in memory + - + - :cspan:`7` Byte 1 + - + - :cspan:`7` Byte 2 + - + - :cspan:`7` Byte 3 + * - + - + - Bit + - 7 + - 6 + - 5 + - 4 + - 3 + - 2 + - 1 + - 0 + - + - 7 + - 6 + - 5 + - 4 + - 3 + - 2 + - 1 + - 0 + - + - 7 + - 6 + - 5 + - 4 + - 3 + - 2 + - 1 + - 0 + - + - 7 + - 6 + - 5 + - 4 + - 3 + - 2 + - 1 + - 0 + * .. _V4L2-PIX-FMT-HSV32: + + - ``V4L2_PIX_FMT_HSV32`` + - 'HSV4' + - + - + - + - + - + - + - + - + - + - + - h\ :sub:`7` + - h\ :sub:`6` + - h\ :sub:`5` + - h\ :sub:`4` + - h\ :sub:`3` + - h\ :sub:`2` + - h\ :sub:`1` + - h\ :sub:`0` + - + - s\ :sub:`7` + - s\ :sub:`6` + - s\ :sub:`5` + - s\ :sub:`4` + - s\ :sub:`3` + - s\ :sub:`2` + - s\ :sub:`1` + - s\ :sub:`0` + - + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + * .. _V4L2-PIX-FMT-HSV24: + + - ``V4L2_PIX_FMT_HSV24`` + - 'HSV3' + - + - h\ :sub:`7` + - h\ :sub:`6` + - h\ :sub:`5` + - h\ :sub:`4` + - h\ :sub:`3` + - h\ :sub:`2` + - h\ :sub:`1` + - h\ :sub:`0` + - + - s\ :sub:`7` + - s\ :sub:`6` + - s\ :sub:`5` + - s\ :sub:`4` + - s\ :sub:`3` + - s\ :sub:`2` + - s\ :sub:`1` + - s\ :sub:`0` + - + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - + - +.. raw:: latex + + \end{adjustbox}\newline\newline + +Bit 7 is the most significant bit. diff --git a/Documentation/media/uapi/v4l/pixfmt.rst b/Documentation/media/uapi/v4l/pixfmt.rst index 4d297f6eb5f1..4f184c7aedab 100644 --- a/Documentation/media/uapi/v4l/pixfmt.rst +++ b/Documentation/media/uapi/v4l/pixfmt.rst @@ -29,6 +29,7 @@ see also :ref:`VIDIOC_G_FBUF `.) pixfmt-indexed pixfmt-rgb yuv-formats + hsv-formats depth-formats pixfmt-013 sdr-formats diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst index 55b959dda07e..683f92ed023f 100644 --- a/Documentation/media/uapi/v4l/v4l2.rst +++ b/Documentation/media/uapi/v4l/v4l2.rst @@ -89,6 +89,11 @@ part can be used and distributed without restrictions. Revision History **************** +:revision: 4.10 / 2016-07-15 (*rr*) + +Introduce HSV formats. + + :revision: 4.5 / 2015-10-29 (*rr*) Extend VIDIOC_G_EXT_CTRLS;. Replace ctrl_class with a new union with -- cgit v1.2.3 From 05b6f8a5526fa20d5ac5747148ae327b045f4f37 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Fri, 15 Jul 2016 13:04:51 -0300 Subject: [media] Documentation: Add Ricardo Ribalda My initials were on the Changelog, but there was no link to my name. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/v4l2.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst index 683f92ed023f..f52a11c949d3 100644 --- a/Documentation/media/uapi/v4l/v4l2.rst +++ b/Documentation/media/uapi/v4l/v4l2.rst @@ -68,6 +68,10 @@ Authors, in alphabetical order: - SDR API. +- Ribalda, Ricardo + + - Introduce HSV formats and other minor changes. + - Rubli, Martin - Designed and documented the VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS ioctls. -- cgit v1.2.3 From 646895e9361af5ea501d0325f9b0251080a32854 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Fri, 15 Jul 2016 06:09:47 -0300 Subject: [media] vivid: Code refactor for color encoding Replace is_yuv with color_enc Which can be used by other color encodings such us HSV. This change should ease the review of the following patches. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 49 +++++++++++++++-------- drivers/media/platform/vivid/vivid-core.h | 2 +- drivers/media/platform/vivid/vivid-vid-common.c | 52 ++++++++++++------------- include/media/v4l2-tpg.h | 7 +++- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 1684810cab83..c4153307bfc5 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -237,13 +237,13 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y16: case V4L2_PIX_FMT_Y16_BE: - tpg->is_yuv = false; + tpg->color_enc = TGP_COLOR_ENC_RGB; break; case V4L2_PIX_FMT_YUV444: case V4L2_PIX_FMT_YUV555: case V4L2_PIX_FMT_YUV565: case V4L2_PIX_FMT_YUV32: - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_YUV420M: case V4L2_PIX_FMT_YVU420M: @@ -256,7 +256,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->hdownsampling[1] = 2; tpg->hdownsampling[2] = 2; tpg->planes = 3; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_YUV422M: case V4L2_PIX_FMT_YVU422M: @@ -268,7 +268,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->hdownsampling[1] = 2; tpg->hdownsampling[2] = 2; tpg->planes = 3; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_NV16M: case V4L2_PIX_FMT_NV61M: @@ -280,7 +280,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->hdownsampling[1] = 1; tpg->hmask[1] = ~1; tpg->planes = 2; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV21M: @@ -292,7 +292,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->hdownsampling[1] = 1; tpg->hmask[1] = ~1; tpg->planes = 2; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_YUV444M: case V4L2_PIX_FMT_YVU444M: @@ -302,21 +302,21 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->vdownsampling[2] = 1; tpg->hdownsampling[1] = 1; tpg->hdownsampling[2] = 1; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_NV24: case V4L2_PIX_FMT_NV42: tpg->vdownsampling[1] = 1; tpg->hdownsampling[1] = 1; tpg->planes = 2; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_VYUY: tpg->hmask[0] = ~1; - tpg->is_yuv = true; + tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; default: return false; @@ -775,7 +775,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) * Remember that r, g and b are still in the 0 - 0xff0 range. */ if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED && - tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL && !tpg->is_yuv) { + tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL && + tpg->color_enc == TGP_COLOR_ENC_RGB) { /* * Convert from full range (which is what r, g and b are) * to limited range (which is the 'real' RGB range), which @@ -785,7 +786,9 @@ static void precalculate_color(struct tpg_data *tpg, int k) g = (g * 219) / 255 + (16 << 4); b = (b * 219) / 255 + (16 << 4); } else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED && - tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED && !tpg->is_yuv) { + tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED && + tpg->color_enc == TGP_COLOR_ENC_RGB) { + /* * Clamp r, g and b to the limited range and convert to full * range since that's what we deliver. @@ -818,7 +821,7 @@ static void precalculate_color(struct tpg_data *tpg, int k) cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128); cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128); - if (tpg->is_yuv) { + if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) { tpg->colors[k][0] = clamp(y >> 4, 1, 254); tpg->colors[k][1] = clamp(cb >> 4, 1, 254); tpg->colors[k][2] = clamp(cr >> 4, 1, 254); @@ -827,7 +830,7 @@ static void precalculate_color(struct tpg_data *tpg, int k) ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); } - if (tpg->is_yuv) { + if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) { /* Convert to YCbCr */ int y, cb, cr; @@ -1840,7 +1843,8 @@ static void tpg_recalc(struct tpg_data *tpg) if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT) tpg->real_quantization = - V4L2_MAP_QUANTIZATION_DEFAULT(!tpg->is_yuv, + V4L2_MAP_QUANTIZATION_DEFAULT( + tpg->color_enc != TGP_COLOR_ENC_YCBCR, tpg->colorspace, tpg->real_ycbcr_enc); tpg_precalculate_colors(tpg); @@ -1887,11 +1891,24 @@ static int tpg_pattern_avg(const struct tpg_data *tpg, return -1; } +static const char *tpg_color_enc_str(enum tgp_color_enc + color_enc) +{ + switch (color_enc) { + case TGP_COLOR_ENC_YCBCR: + return "Y'CbCr"; + case TGP_COLOR_ENC_RGB: + default: + return "R'G'B"; + + } +} + void tpg_log_status(struct tpg_data *tpg) { pr_info("tpg source WxH: %ux%u (%s)\n", - tpg->src_width, tpg->src_height, - tpg->is_yuv ? "YCbCr" : "RGB"); + tpg->src_width, tpg->src_height, + tpg_color_enc_str(tpg->color_enc)); pr_info("tpg field: %u\n", tpg->field); pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height, tpg->crop.left, tpg->crop.top); diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index a7daa40d0a49..b59b49456d45 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -80,7 +80,7 @@ extern unsigned vivid_debug; struct vivid_fmt { u32 fourcc; /* v4l2 format id */ - bool is_yuv; + enum tgp_color_enc color_enc; bool can_do_overlay; u8 vdownsampling[TPG_MAX_PLANES]; u32 alpha_mask; diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index fcda3ae4e6b0..f4c35ba5f070 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -48,7 +48,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUYV, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, .data_offset = { PLANE0_DATA_OFFSET }, @@ -57,7 +57,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_UYVY, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -65,7 +65,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YVYU, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -73,7 +73,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_VYUY, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -81,7 +81,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUV422P, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 1, }, @@ -89,7 +89,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUV420, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 1, }, @@ -97,7 +97,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YVU420, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 1, }, @@ -105,7 +105,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV12, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -113,7 +113,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV21, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -121,7 +121,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV16, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -129,7 +129,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV61, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -137,7 +137,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV24, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -145,7 +145,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV42, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 1, }, @@ -184,7 +184,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_GREY, .vdownsampling = { 1 }, .bit_depth = { 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -192,7 +192,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_Y16, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -200,7 +200,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_Y16_BE, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 1, .buffers = 1, }, @@ -452,7 +452,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV16M, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 2, .data_offset = { PLANE0_DATA_OFFSET, 0 }, @@ -461,7 +461,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV61M, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 2, .data_offset = { 0, PLANE0_DATA_OFFSET }, @@ -470,7 +470,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUV420M, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, @@ -478,7 +478,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YVU420M, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, @@ -486,7 +486,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV12M, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 2, }, @@ -494,7 +494,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_NV21M, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 2, .buffers = 2, }, @@ -502,7 +502,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUV422M, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, @@ -510,7 +510,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YVU422M, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 4, 4 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, @@ -518,7 +518,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YUV444M, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, @@ -526,7 +526,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_YVU444M, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 8, 8 }, - .is_yuv = true, + .color_enc = TGP_COLOR_ENC_YCBCR, .planes = 3, .buffers = 3, }, diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h index 329bebfa930c..b4cb8f34cd87 100644 --- a/include/media/v4l2-tpg.h +++ b/include/media/v4l2-tpg.h @@ -87,6 +87,11 @@ enum tpg_move_mode { TPG_MOVE_POS_FAST, }; +enum tgp_color_enc { + TGP_COLOR_ENC_RGB, + TGP_COLOR_ENC_YCBCR, +}; + extern const char * const tpg_aspect_strings[]; #define TPG_MAX_PLANES 3 @@ -119,7 +124,7 @@ struct tpg_data { u8 saturation; s16 hue; u32 fourcc; - bool is_yuv; + enum tgp_color_enc color_enc; u32 colorspace; u32 xfer_func; u32 ycbcr_enc; -- cgit v1.2.3 From 54fb15348385a1acf5a7bc1417bdd94c9d5115bb Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Fri, 15 Jul 2016 10:20:08 -0300 Subject: [media] vivid: Add support for HSV formats This patch adds support for V4L2_PIX_FMT_HSV24 and V4L2_PIX_FMT_HSV32. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 93 +++++++++++++++++++++++-- drivers/media/platform/vivid/vivid-vid-common.c | 14 ++++ include/media/v4l2-tpg.h | 1 + 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index c4153307bfc5..67e0aaf067b7 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -318,6 +318,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) tpg->hmask[0] = ~1; tpg->color_enc = TGP_COLOR_ENC_YCBCR; break; + case V4L2_PIX_FMT_HSV24: + case V4L2_PIX_FMT_HSV32: + tpg->color_enc = TGP_COLOR_ENC_HSV; + break; default: return false; } @@ -351,6 +355,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) break; case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_HSV24: tpg->twopixelsize[0] = 2 * 3; break; case V4L2_PIX_FMT_BGR666: @@ -361,6 +366,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_ARGB32: case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_YUV32: + case V4L2_PIX_FMT_HSV32: tpg->twopixelsize[0] = 2 * 4; break; case V4L2_PIX_FMT_NV12: @@ -490,6 +496,64 @@ static inline int linear_to_rec709(int v) return tpg_linear_to_rec709[v]; } +static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b, + int *h, int *s, int *v) +{ + int max_rgb, min_rgb, diff_rgb; + int aux; + int third; + + r >>= 4; + g >>= 4; + b >>= 4; + + /* Value */ + max_rgb = max3(r, g, b); + *v = max_rgb; + if (!max_rgb) { + *h = 0; + *s = 0; + return; + } + + /* Saturation */ + min_rgb = min3(r, g, b); + diff_rgb = max_rgb - min_rgb; + aux = 255 * diff_rgb; + aux += max_rgb / 2; + aux /= max_rgb; + *s = aux; + if (!aux) { + *h = 0; + return; + } + + /* Hue */ + if (max_rgb == r) { + aux = g - b; + third = 0; + } else if (max_rgb == g) { + aux = b - r; + third = 60; + } else { + aux = r - g; + third = 120; + } + + aux *= 30; + aux += diff_rgb / 2; + aux /= diff_rgb; + aux += third; + + /* Clamp Hue */ + if (aux < 0) + aux += 180; + else if (aux > 180) + aux -= 180; + *h = aux; + +} + static void rgb2ycbcr(const int m[3][3], int r, int g, int b, int y_offset, int *y, int *cb, int *cr) { @@ -830,7 +894,19 @@ static void precalculate_color(struct tpg_data *tpg, int k) ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); } - if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) { + switch (tpg->color_enc) { + case TGP_COLOR_ENC_HSV: + { + int h, s, v; + + color_to_hsv(tpg, r, g, b, &h, &s, &v); + tpg->colors[k][0] = h; + tpg->colors[k][1] = s; + tpg->colors[k][2] = v; + break; + } + case TGP_COLOR_ENC_YCBCR: + { /* Convert to YCbCr */ int y, cb, cr; @@ -864,7 +940,10 @@ static void precalculate_color(struct tpg_data *tpg, int k) tpg->colors[k][0] = y; tpg->colors[k][1] = cb; tpg->colors[k][2] = cr; - } else { + break; + } + case TGP_COLOR_ENC_RGB: + { if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { r = (r * 219) / 255 + (16 << 4); g = (g * 219) / 255 + (16 << 4); @@ -914,6 +993,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) tpg->colors[k][0] = r; tpg->colors[k][1] = g; tpg->colors[k][2] = b; + break; + } } } @@ -939,8 +1020,8 @@ static void gen_twopix(struct tpg_data *tpg, alpha = 0; if (color == TPG_COLOR_RANDOM) precalculate_color(tpg, color); - r_y = tpg->colors[color][0]; /* R or precalculated Y */ - g_u = tpg->colors[color][1]; /* G or precalculated U */ + r_y = tpg->colors[color][0]; /* R or precalculated Y, H */ + g_u = tpg->colors[color][1]; /* G or precalculated U, V */ b_v = tpg->colors[color][2]; /* B or precalculated V */ switch (tpg->fourcc) { @@ -1122,6 +1203,7 @@ static void gen_twopix(struct tpg_data *tpg, buf[0][offset + 1] = (g_u << 5) | b_v; break; case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_HSV24: buf[0][offset] = r_y; buf[0][offset + 1] = g_u; buf[0][offset + 2] = b_v; @@ -1139,6 +1221,7 @@ static void gen_twopix(struct tpg_data *tpg, break; case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_HSV32: alpha = 0; /* fall through */ case V4L2_PIX_FMT_YUV32: @@ -1895,6 +1978,8 @@ static const char *tpg_color_enc_str(enum tgp_color_enc color_enc) { switch (color_enc) { + case TGP_COLOR_ENC_HSV: + return "HSV"; case TGP_COLOR_ENC_YCBCR: return "Y'CbCr"; case TGP_COLOR_ENC_RGB: diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index f4c35ba5f070..20822b5111b3 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -445,6 +445,20 @@ struct vivid_fmt vivid_formats[] = { .planes = 1, .buffers = 1, }, + { + .fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */ + .vdownsampling = { 1 }, + .bit_depth = { 24 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_HSV32, /* HSV 32bits */ + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + }, /* Multiplanar formats */ diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h index b4cb8f34cd87..4a40f9b79053 100644 --- a/include/media/v4l2-tpg.h +++ b/include/media/v4l2-tpg.h @@ -90,6 +90,7 @@ enum tpg_move_mode { enum tgp_color_enc { TGP_COLOR_ENC_RGB, TGP_COLOR_ENC_YCBCR, + TGP_COLOR_ENC_HSV, }; extern const char * const tpg_aspect_strings[]; -- cgit v1.2.3 From 25e90073497b94c3469f083cc0c66563c18c0788 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Fri, 15 Jul 2016 10:21:46 -0300 Subject: [media] vivid: Rename variable r_y and g_u now also contain the H and V components on the HSV formats. Rename the variables to reflect this. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 209 +++++++++++++------------- 1 file changed, 105 insertions(+), 104 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 67e0aaf067b7..0aeabe92ff32 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -1012,7 +1012,7 @@ static void gen_twopix(struct tpg_data *tpg, { unsigned offset = odd * tpg->twopixelsize[0] / 2; u8 alpha = tpg->alpha_component; - u8 r_y, g_u, b_v; + u8 r_y_h, g_u_s, b_v; if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED && color != TPG_COLOR_100_RED && @@ -1020,161 +1020,161 @@ static void gen_twopix(struct tpg_data *tpg, alpha = 0; if (color == TPG_COLOR_RANDOM) precalculate_color(tpg, color); - r_y = tpg->colors[color][0]; /* R or precalculated Y, H */ - g_u = tpg->colors[color][1]; /* G or precalculated U, V */ + r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */ + g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */ b_v = tpg->colors[color][2]; /* B or precalculated V */ switch (tpg->fourcc) { case V4L2_PIX_FMT_GREY: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; break; case V4L2_PIX_FMT_Y16: /* - * Ideally both bytes should be set to r_y, but then you won't + * Ideally both bytes should be set to r_y_h, but then you won't * be able to detect endian problems. So keep it 0 except for - * the corner case where r_y is 0xff so white really will be + * the corner case where r_y_h is 0xff so white really will be * white (0xffff). */ - buf[0][offset] = r_y == 0xff ? r_y : 0; - buf[0][offset+1] = r_y; + buf[0][offset] = r_y_h == 0xff ? r_y_h : 0; + buf[0][offset+1] = r_y_h; break; case V4L2_PIX_FMT_Y16_BE: /* See comment for V4L2_PIX_FMT_Y16 above */ - buf[0][offset] = r_y; - buf[0][offset+1] = r_y == 0xff ? r_y : 0; + buf[0][offset] = r_y_h; + buf[0][offset+1] = r_y_h == 0xff ? r_y_h : 0; break; case V4L2_PIX_FMT_YUV422M: case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV420M: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { - buf[1][0] = (buf[1][0] + g_u) / 2; + buf[1][0] = (buf[1][0] + g_u_s) / 2; buf[2][0] = (buf[2][0] + b_v) / 2; buf[1][1] = buf[1][0]; buf[2][1] = buf[2][0]; break; } - buf[1][0] = g_u; + buf[1][0] = g_u_s; buf[2][0] = b_v; break; case V4L2_PIX_FMT_YVU422M: case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_YVU420M: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { buf[1][0] = (buf[1][0] + b_v) / 2; - buf[2][0] = (buf[2][0] + g_u) / 2; + buf[2][0] = (buf[2][0] + g_u_s) / 2; buf[1][1] = buf[1][0]; buf[2][1] = buf[2][0]; break; } buf[1][0] = b_v; - buf[2][0] = g_u; + buf[2][0] = g_u_s; break; case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV16M: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { - buf[1][0] = (buf[1][0] + g_u) / 2; + buf[1][0] = (buf[1][0] + g_u_s) / 2; buf[1][1] = (buf[1][1] + b_v) / 2; break; } - buf[1][0] = g_u; + buf[1][0] = g_u_s; buf[1][1] = b_v; break; case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV21M: case V4L2_PIX_FMT_NV61: case V4L2_PIX_FMT_NV61M: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { buf[1][0] = (buf[1][0] + b_v) / 2; - buf[1][1] = (buf[1][1] + g_u) / 2; + buf[1][1] = (buf[1][1] + g_u_s) / 2; break; } buf[1][0] = b_v; - buf[1][1] = g_u; + buf[1][1] = g_u_s; break; case V4L2_PIX_FMT_YUV444M: - buf[0][offset] = r_y; - buf[1][offset] = g_u; + buf[0][offset] = r_y_h; + buf[1][offset] = g_u_s; buf[2][offset] = b_v; break; case V4L2_PIX_FMT_YVU444M: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; buf[1][offset] = b_v; - buf[2][offset] = g_u; + buf[2][offset] = g_u_s; break; case V4L2_PIX_FMT_NV24: - buf[0][offset] = r_y; - buf[1][2 * offset] = g_u; + buf[0][offset] = r_y_h; + buf[1][2 * offset] = g_u_s; buf[1][2 * offset + 1] = b_v; break; case V4L2_PIX_FMT_NV42: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; buf[1][2 * offset] = b_v; - buf[1][2 * offset + 1] = g_u; + buf[1][2 * offset + 1] = g_u_s; break; case V4L2_PIX_FMT_YUYV: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { - buf[0][1] = (buf[0][1] + g_u) / 2; + buf[0][1] = (buf[0][1] + g_u_s) / 2; buf[0][3] = (buf[0][3] + b_v) / 2; break; } - buf[0][1] = g_u; + buf[0][1] = g_u_s; buf[0][3] = b_v; break; case V4L2_PIX_FMT_UYVY: - buf[0][offset + 1] = r_y; + buf[0][offset + 1] = r_y_h; if (odd) { - buf[0][0] = (buf[0][0] + g_u) / 2; + buf[0][0] = (buf[0][0] + g_u_s) / 2; buf[0][2] = (buf[0][2] + b_v) / 2; break; } - buf[0][0] = g_u; + buf[0][0] = g_u_s; buf[0][2] = b_v; break; case V4L2_PIX_FMT_YVYU: - buf[0][offset] = r_y; + buf[0][offset] = r_y_h; if (odd) { buf[0][1] = (buf[0][1] + b_v) / 2; - buf[0][3] = (buf[0][3] + g_u) / 2; + buf[0][3] = (buf[0][3] + g_u_s) / 2; break; } buf[0][1] = b_v; - buf[0][3] = g_u; + buf[0][3] = g_u_s; break; case V4L2_PIX_FMT_VYUY: - buf[0][offset + 1] = r_y; + buf[0][offset + 1] = r_y_h; if (odd) { buf[0][0] = (buf[0][0] + b_v) / 2; - buf[0][2] = (buf[0][2] + g_u) / 2; + buf[0][2] = (buf[0][2] + g_u_s) / 2; break; } buf[0][0] = b_v; - buf[0][2] = g_u; + buf[0][2] = g_u_s; break; case V4L2_PIX_FMT_RGB332: - buf[0][offset] = (r_y << 5) | (g_u << 2) | b_v; + buf[0][offset] = (r_y_h << 5) | (g_u_s << 2) | b_v; break; case V4L2_PIX_FMT_YUV565: case V4L2_PIX_FMT_RGB565: - buf[0][offset] = (g_u << 5) | b_v; - buf[0][offset + 1] = (r_y << 3) | (g_u >> 3); + buf[0][offset] = (g_u_s << 5) | b_v; + buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 3); break; case V4L2_PIX_FMT_RGB565X: - buf[0][offset] = (r_y << 3) | (g_u >> 3); - buf[0][offset + 1] = (g_u << 5) | b_v; + buf[0][offset] = (r_y_h << 3) | (g_u_s >> 3); + buf[0][offset + 1] = (g_u_s << 5) | b_v; break; case V4L2_PIX_FMT_RGB444: case V4L2_PIX_FMT_XRGB444: @@ -1182,8 +1182,8 @@ static void gen_twopix(struct tpg_data *tpg, /* fall through */ case V4L2_PIX_FMT_YUV444: case V4L2_PIX_FMT_ARGB444: - buf[0][offset] = (g_u << 4) | b_v; - buf[0][offset + 1] = (alpha & 0xf0) | r_y; + buf[0][offset] = (g_u_s << 4) | b_v; + buf[0][offset + 1] = (alpha & 0xf0) | r_y_h; break; case V4L2_PIX_FMT_RGB555: case V4L2_PIX_FMT_XRGB555: @@ -1191,32 +1191,33 @@ static void gen_twopix(struct tpg_data *tpg, /* fall through */ case V4L2_PIX_FMT_YUV555: case V4L2_PIX_FMT_ARGB555: - buf[0][offset] = (g_u << 5) | b_v; - buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); + buf[0][offset] = (g_u_s << 5) | b_v; + buf[0][offset + 1] = (alpha & 0x80) | (r_y_h << 2) + | (g_u_s >> 3); break; case V4L2_PIX_FMT_RGB555X: case V4L2_PIX_FMT_XRGB555X: alpha = 0; /* fall through */ case V4L2_PIX_FMT_ARGB555X: - buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); - buf[0][offset + 1] = (g_u << 5) | b_v; + buf[0][offset] = (alpha & 0x80) | (r_y_h << 2) | (g_u_s >> 3); + buf[0][offset + 1] = (g_u_s << 5) | b_v; break; case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_HSV24: - buf[0][offset] = r_y; - buf[0][offset + 1] = g_u; + buf[0][offset] = r_y_h; + buf[0][offset + 1] = g_u_s; buf[0][offset + 2] = b_v; break; case V4L2_PIX_FMT_BGR24: buf[0][offset] = b_v; - buf[0][offset + 1] = g_u; - buf[0][offset + 2] = r_y; + buf[0][offset + 1] = g_u_s; + buf[0][offset + 2] = r_y_h; break; case V4L2_PIX_FMT_BGR666: - buf[0][offset] = (b_v << 2) | (g_u >> 4); - buf[0][offset + 1] = (g_u << 4) | (r_y >> 2); - buf[0][offset + 2] = r_y << 6; + buf[0][offset] = (b_v << 2) | (g_u_s >> 4); + buf[0][offset + 1] = (g_u_s << 4) | (r_y_h >> 2); + buf[0][offset + 2] = r_y_h << 6; buf[0][offset + 3] = 0; break; case V4L2_PIX_FMT_RGB32: @@ -1227,8 +1228,8 @@ static void gen_twopix(struct tpg_data *tpg, case V4L2_PIX_FMT_YUV32: case V4L2_PIX_FMT_ARGB32: buf[0][offset] = alpha; - buf[0][offset + 1] = r_y; - buf[0][offset + 2] = g_u; + buf[0][offset + 1] = r_y_h; + buf[0][offset + 2] = g_u_s; buf[0][offset + 3] = b_v; break; case V4L2_PIX_FMT_BGR32: @@ -1237,87 +1238,87 @@ static void gen_twopix(struct tpg_data *tpg, /* fall through */ case V4L2_PIX_FMT_ABGR32: buf[0][offset] = b_v; - buf[0][offset + 1] = g_u; - buf[0][offset + 2] = r_y; + buf[0][offset + 1] = g_u_s; + buf[0][offset + 2] = r_y_h; buf[0][offset + 3] = alpha; break; case V4L2_PIX_FMT_SBGGR8: - buf[0][offset] = odd ? g_u : b_v; - buf[1][offset] = odd ? r_y : g_u; + buf[0][offset] = odd ? g_u_s : b_v; + buf[1][offset] = odd ? r_y_h : g_u_s; break; case V4L2_PIX_FMT_SGBRG8: - buf[0][offset] = odd ? b_v : g_u; - buf[1][offset] = odd ? g_u : r_y; + buf[0][offset] = odd ? b_v : g_u_s; + buf[1][offset] = odd ? g_u_s : r_y_h; break; case V4L2_PIX_FMT_SGRBG8: - buf[0][offset] = odd ? r_y : g_u; - buf[1][offset] = odd ? g_u : b_v; + buf[0][offset] = odd ? r_y_h : g_u_s; + buf[1][offset] = odd ? g_u_s : b_v; break; case V4L2_PIX_FMT_SRGGB8: - buf[0][offset] = odd ? g_u : r_y; - buf[1][offset] = odd ? b_v : g_u; + buf[0][offset] = odd ? g_u_s : r_y_h; + buf[1][offset] = odd ? b_v : g_u_s; break; case V4L2_PIX_FMT_SBGGR10: - buf[0][offset] = odd ? g_u << 2 : b_v << 2; - buf[0][offset + 1] = odd ? g_u >> 6 : b_v >> 6; - buf[1][offset] = odd ? r_y << 2 : g_u << 2; - buf[1][offset + 1] = odd ? r_y >> 6 : g_u >> 6; + buf[0][offset] = odd ? g_u_s << 2 : b_v << 2; + buf[0][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6; + buf[1][offset] = odd ? r_y_h << 2 : g_u_s << 2; + buf[1][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6; buf[0][offset] |= (buf[0][offset] >> 2) & 3; buf[1][offset] |= (buf[1][offset] >> 2) & 3; break; case V4L2_PIX_FMT_SGBRG10: - buf[0][offset] = odd ? b_v << 2 : g_u << 2; - buf[0][offset + 1] = odd ? b_v >> 6 : g_u >> 6; - buf[1][offset] = odd ? g_u << 2 : r_y << 2; - buf[1][offset + 1] = odd ? g_u >> 6 : r_y >> 6; + buf[0][offset] = odd ? b_v << 2 : g_u_s << 2; + buf[0][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6; + buf[1][offset] = odd ? g_u_s << 2 : r_y_h << 2; + buf[1][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6; buf[0][offset] |= (buf[0][offset] >> 2) & 3; buf[1][offset] |= (buf[1][offset] >> 2) & 3; break; case V4L2_PIX_FMT_SGRBG10: - buf[0][offset] = odd ? r_y << 2 : g_u << 2; - buf[0][offset + 1] = odd ? r_y >> 6 : g_u >> 6; - buf[1][offset] = odd ? g_u << 2 : b_v << 2; - buf[1][offset + 1] = odd ? g_u >> 6 : b_v >> 6; + buf[0][offset] = odd ? r_y_h << 2 : g_u_s << 2; + buf[0][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6; + buf[1][offset] = odd ? g_u_s << 2 : b_v << 2; + buf[1][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6; buf[0][offset] |= (buf[0][offset] >> 2) & 3; buf[1][offset] |= (buf[1][offset] >> 2) & 3; break; case V4L2_PIX_FMT_SRGGB10: - buf[0][offset] = odd ? g_u << 2 : r_y << 2; - buf[0][offset + 1] = odd ? g_u >> 6 : r_y >> 6; - buf[1][offset] = odd ? b_v << 2 : g_u << 2; - buf[1][offset + 1] = odd ? b_v >> 6 : g_u >> 6; + buf[0][offset] = odd ? g_u_s << 2 : r_y_h << 2; + buf[0][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6; + buf[1][offset] = odd ? b_v << 2 : g_u_s << 2; + buf[1][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6; buf[0][offset] |= (buf[0][offset] >> 2) & 3; buf[1][offset] |= (buf[1][offset] >> 2) & 3; break; case V4L2_PIX_FMT_SBGGR12: - buf[0][offset] = odd ? g_u << 4 : b_v << 4; - buf[0][offset + 1] = odd ? g_u >> 4 : b_v >> 4; - buf[1][offset] = odd ? r_y << 4 : g_u << 4; - buf[1][offset + 1] = odd ? r_y >> 4 : g_u >> 4; + buf[0][offset] = odd ? g_u_s << 4 : b_v << 4; + buf[0][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4; + buf[1][offset] = odd ? r_y_h << 4 : g_u_s << 4; + buf[1][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4; buf[0][offset] |= (buf[0][offset] >> 4) & 0xf; buf[1][offset] |= (buf[1][offset] >> 4) & 0xf; break; case V4L2_PIX_FMT_SGBRG12: - buf[0][offset] = odd ? b_v << 4 : g_u << 4; - buf[0][offset + 1] = odd ? b_v >> 4 : g_u >> 4; - buf[1][offset] = odd ? g_u << 4 : r_y << 4; - buf[1][offset + 1] = odd ? g_u >> 4 : r_y >> 4; + buf[0][offset] = odd ? b_v << 4 : g_u_s << 4; + buf[0][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4; + buf[1][offset] = odd ? g_u_s << 4 : r_y_h << 4; + buf[1][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4; buf[0][offset] |= (buf[0][offset] >> 4) & 0xf; buf[1][offset] |= (buf[1][offset] >> 4) & 0xf; break; case V4L2_PIX_FMT_SGRBG12: - buf[0][offset] = odd ? r_y << 4 : g_u << 4; - buf[0][offset + 1] = odd ? r_y >> 4 : g_u >> 4; - buf[1][offset] = odd ? g_u << 4 : b_v << 4; - buf[1][offset + 1] = odd ? g_u >> 4 : b_v >> 4; + buf[0][offset] = odd ? r_y_h << 4 : g_u_s << 4; + buf[0][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4; + buf[1][offset] = odd ? g_u_s << 4 : b_v << 4; + buf[1][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4; buf[0][offset] |= (buf[0][offset] >> 4) & 0xf; buf[1][offset] |= (buf[1][offset] >> 4) & 0xf; break; case V4L2_PIX_FMT_SRGGB12: - buf[0][offset] = odd ? g_u << 4 : r_y << 4; - buf[0][offset + 1] = odd ? g_u >> 4 : r_y >> 4; - buf[1][offset] = odd ? b_v << 4 : g_u << 4; - buf[1][offset + 1] = odd ? b_v >> 4 : g_u >> 4; + buf[0][offset] = odd ? g_u_s << 4 : r_y_h << 4; + buf[0][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4; + buf[1][offset] = odd ? b_v << 4 : g_u_s << 4; + buf[1][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4; buf[0][offset] |= (buf[0][offset] >> 4) & 0xf; buf[1][offset] |= (buf[1][offset] >> 4) & 0xf; break; -- cgit v1.2.3 From ca2b32da5988159d4d997aac9e4a87447046aedf Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Sat, 16 Jul 2016 05:58:09 -0300 Subject: [media] vivid: Introduce TPG_COLOR_ENC_LUMA Simplifies handling of Gray formats. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 26 +++++++++++++++++++------ drivers/media/platform/vivid/vivid-vid-common.c | 6 +++--- include/media/v4l2-tpg.h | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 0aeabe92ff32..920c8495f3dd 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -234,10 +234,12 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_XBGR32: case V4L2_PIX_FMT_ARGB32: case V4L2_PIX_FMT_ABGR32: + tpg->color_enc = TGP_COLOR_ENC_RGB; + break; case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y16: case V4L2_PIX_FMT_Y16_BE: - tpg->color_enc = TGP_COLOR_ENC_RGB; + tpg->color_enc = TGP_COLOR_ENC_LUMA; break; case V4L2_PIX_FMT_YUV444: case V4L2_PIX_FMT_YUV555: @@ -823,9 +825,9 @@ static void precalculate_color(struct tpg_data *tpg, int k) g <<= 4; b <<= 4; } - if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY || - tpg->fourcc == V4L2_PIX_FMT_Y16 || - tpg->fourcc == V4L2_PIX_FMT_Y16_BE) { + + if (tpg->qual == TPG_QUAL_GRAY || + tpg->color_enc == TGP_COLOR_ENC_LUMA) { /* Rec. 709 Luma function */ /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16; @@ -865,8 +867,9 @@ static void precalculate_color(struct tpg_data *tpg, int k) b = (b - (16 << 4)) * 255 / 219; } - if (tpg->brightness != 128 || tpg->contrast != 128 || - tpg->saturation != 128 || tpg->hue) { + if ((tpg->brightness != 128 || tpg->contrast != 128 || + tpg->saturation != 128 || tpg->hue) && + tpg->color_enc != TGP_COLOR_ENC_LUMA) { /* Implement these operations */ int y, cb, cr; int tmp_cb, tmp_cr; @@ -892,6 +895,10 @@ static void precalculate_color(struct tpg_data *tpg, int k) return; } ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); + } else if ((tpg->brightness != 128 || tpg->contrast != 128) && + tpg->color_enc == TGP_COLOR_ENC_LUMA) { + r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128; + r += (tpg->brightness << 4) - (128 << 4); } switch (tpg->color_enc) { @@ -942,6 +949,11 @@ static void precalculate_color(struct tpg_data *tpg, int k) tpg->colors[k][2] = cr; break; } + case TGP_COLOR_ENC_LUMA: + { + tpg->colors[k][0] = r >> 4; + break; + } case TGP_COLOR_ENC_RGB: { if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { @@ -1983,6 +1995,8 @@ static const char *tpg_color_enc_str(enum tgp_color_enc return "HSV"; case TGP_COLOR_ENC_YCBCR: return "Y'CbCr"; + case TGP_COLOR_ENC_LUMA: + return "Luma"; case TGP_COLOR_ENC_RGB: default: return "R'G'B"; diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 20822b5111b3..e0df44151461 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -184,7 +184,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_GREY, .vdownsampling = { 1 }, .bit_depth = { 8 }, - .color_enc = TGP_COLOR_ENC_YCBCR, + .color_enc = TGP_COLOR_ENC_LUMA, .planes = 1, .buffers = 1, }, @@ -192,7 +192,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_Y16, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .color_enc = TGP_COLOR_ENC_YCBCR, + .color_enc = TGP_COLOR_ENC_LUMA, .planes = 1, .buffers = 1, }, @@ -200,7 +200,7 @@ struct vivid_fmt vivid_formats[] = { .fourcc = V4L2_PIX_FMT_Y16_BE, .vdownsampling = { 1 }, .bit_depth = { 16 }, - .color_enc = TGP_COLOR_ENC_YCBCR, + .color_enc = TGP_COLOR_ENC_LUMA, .planes = 1, .buffers = 1, }, diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h index 4a40f9b79053..8abed92317e8 100644 --- a/include/media/v4l2-tpg.h +++ b/include/media/v4l2-tpg.h @@ -91,6 +91,7 @@ enum tgp_color_enc { TGP_COLOR_ENC_RGB, TGP_COLOR_ENC_YCBCR, TGP_COLOR_ENC_HSV, + TGP_COLOR_ENC_LUMA, }; extern const char * const tpg_aspect_strings[]; -- cgit v1.2.3 From 7a20f3985fb6eb74c93e5f36cf1d375a3b013d77 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Sat, 16 Jul 2016 06:26:23 -0300 Subject: [media] vivid: Fix YUV555 and YUV565 handling precalculate_color() had a optimization that avoided duplicated conversion for YUV formats. This optimization did not take into consideration YUV444, YUV555, YUV565 or limited range quantization. This patch keeps the optimization, but fixes the wrong handling. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 920c8495f3dd..7364ced09abc 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -795,6 +795,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) int r = tpg_colors[col].r; int g = tpg_colors[col].g; int b = tpg_colors[col].b; + int y, cb, cr; + bool ycbcr_valid = false; if (k == TPG_COLOR_TEXTBG) { col = tpg_get_textbg_color(tpg); @@ -871,7 +873,6 @@ static void precalculate_color(struct tpg_data *tpg, int k) tpg->saturation != 128 || tpg->hue) && tpg->color_enc != TGP_COLOR_ENC_LUMA) { /* Implement these operations */ - int y, cb, cr; int tmp_cb, tmp_cr; /* First convert to YCbCr */ @@ -888,13 +889,10 @@ static void precalculate_color(struct tpg_data *tpg, int k) cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128); cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128); - if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) { - tpg->colors[k][0] = clamp(y >> 4, 1, 254); - tpg->colors[k][1] = clamp(cb >> 4, 1, 254); - tpg->colors[k][2] = clamp(cr >> 4, 1, 254); - return; - } - ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); + if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) + ycbcr_valid = true; + else + ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); } else if ((tpg->brightness != 128 || tpg->contrast != 128) && tpg->color_enc == TGP_COLOR_ENC_LUMA) { r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128; @@ -915,9 +913,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) case TGP_COLOR_ENC_YCBCR: { /* Convert to YCbCr */ - int y, cb, cr; - - color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr); + if (!ycbcr_valid) + color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr); if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { y = clamp(y, 16 << 4, 235 << 4); -- cgit v1.2.3 From f1eb926d1d79a210c8a2bac2f0438163f436a077 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Sat, 16 Jul 2016 06:34:19 -0300 Subject: [media] vivid: Local optimization Avoid duplicated clamps when possible. Suggested-by: Philipp Zabel Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 7364ced09abc..ed37ae307cac 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -916,14 +916,18 @@ static void precalculate_color(struct tpg_data *tpg, int k) if (!ycbcr_valid) color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr); + y >>= 4; + cb >>= 4; + cr >>= 4; if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { - y = clamp(y, 16 << 4, 235 << 4); - cb = clamp(cb, 16 << 4, 240 << 4); - cr = clamp(cr, 16 << 4, 240 << 4); + y = clamp(y, 16, 235); + cb = clamp(cb, 16, 240); + cr = clamp(cr, 16, 240); + } else { + y = clamp(y, 1, 254); + cb = clamp(cb, 1, 254); + cr = clamp(cr, 1, 254); } - y = clamp(y >> 4, 1, 254); - cb = clamp(cb >> 4, 1, 254); - cr = clamp(cr >> 4, 1, 254); switch (tpg->fourcc) { case V4L2_PIX_FMT_YUV444: y >>= 4; -- cgit v1.2.3 From 8a0d62af93026de424d75906e3651ba653197668 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Mon, 22 Aug 2016 06:28:07 -0300 Subject: [media] videodev2.h Add HSV encoding Some hardware maps the Hue between 0 and 255 instead of 0-179. Support this format with a new field hsv_enc. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 6b480c91778e..4364ce6b0aa6 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -334,6 +334,19 @@ enum v4l2_ycbcr_encoding { V4L2_YCBCR_ENC_SMPTE240M = 8, }; +/* + * enum v4l2_hsv_encoding values should not collide with the ones from + * enum v4l2_ycbcr_encoding. + */ +enum v4l2_hsv_encoding { + + /* Hue mapped to 0 - 179 */ + V4L2_HSV_ENC_180 = 128, + + /* Hue mapped to 0-255 */ + V4L2_HSV_ENC_256 = 129, +}; + /* * Determine how YCBCR_ENC_DEFAULT should map to a proper Y'CbCr encoding. * This depends on the colorspace. @@ -362,9 +375,10 @@ enum v4l2_quantization { * This depends on whether the image is RGB or not, the colorspace and the * Y'CbCr encoding. */ -#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, colsp, ycbcr_enc) \ - (((is_rgb) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : \ - (((is_rgb) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || \ +#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv, colsp, ycbcr_enc) \ + (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? \ + V4L2_QUANTIZATION_LIM_RANGE : \ + (((is_rgb_or_hsv) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || \ (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) || \ (colsp) == V4L2_COLORSPACE_ADOBERGB || (colsp) == V4L2_COLORSPACE_SRGB ? \ V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) @@ -462,7 +476,12 @@ struct v4l2_pix_format { __u32 colorspace; /* enum v4l2_colorspace */ __u32 priv; /* private data, depends on pixelformat */ __u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */ - __u32 ycbcr_enc; /* enum v4l2_ycbcr_encoding */ + union { + /* enum v4l2_ycbcr_encoding */ + __u32 ycbcr_enc; + /* enum v4l2_hsv_encoding */ + __u32 hsv_enc; + }; __u32 quantization; /* enum v4l2_quantization */ __u32 xfer_func; /* enum v4l2_xfer_func */ }; @@ -2012,7 +2031,10 @@ struct v4l2_pix_format_mplane { struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; __u8 num_planes; __u8 flags; - __u8 ycbcr_enc; + union { + __u8 ycbcr_enc; + __u8 hsv_enc; + }; __u8 quantization; __u8 xfer_func; __u8 reserved[7]; -- cgit v1.2.3 From 5f3d32ec739fcfe83bb3e39a0ca44f3b097e5a94 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 18 Aug 2016 11:33:37 -0300 Subject: [media] Documentation: Add HSV encodings Describe the hsv_enc field and its use. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-002.rst | 5 ++++ Documentation/media/uapi/v4l/pixfmt-003.rst | 5 ++++ Documentation/media/uapi/v4l/pixfmt-006.rst | 31 +++++++++++++++++++--- Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst | 3 ++- Documentation/media/videodev2.h.rst.exceptions | 4 +++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Documentation/media/uapi/v4l/pixfmt-002.rst b/Documentation/media/uapi/v4l/pixfmt-002.rst index 0d9e697f5d4e..2ee164c25637 100644 --- a/Documentation/media/uapi/v4l/pixfmt-002.rst +++ b/Documentation/media/uapi/v4l/pixfmt-002.rst @@ -121,6 +121,11 @@ Single-planar format structure - This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output streams, see :ref:`colorspaces`. + * - enum :c:type:`v4l2_hsv_encoding` + - ``hsv_enc`` + - This information supplements the ``colorspace`` and must be set by + the driver for capture streams and by the application for output + streams, see :ref:`colorspaces`. * - enum :c:type:`v4l2_quantization` - ``quantization`` - This information supplements the ``colorspace`` and must be set by diff --git a/Documentation/media/uapi/v4l/pixfmt-003.rst b/Documentation/media/uapi/v4l/pixfmt-003.rst index ae9ea7a791de..337e8188caf1 100644 --- a/Documentation/media/uapi/v4l/pixfmt-003.rst +++ b/Documentation/media/uapi/v4l/pixfmt-003.rst @@ -78,6 +78,11 @@ describing all planes of that format. - This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output streams, see :ref:`colorspaces`. + * - enum :c:type:`v4l2_hsv_encoding` + - ``hsv_enc`` + - This information supplements the ``colorspace`` and must be set by + the driver for capture streams and by the application for output + streams, see :ref:`colorspaces`. * - enum :c:type:`v4l2_quantization` - ``quantization`` - This information supplements the ``colorspace`` and must be set by diff --git a/Documentation/media/uapi/v4l/pixfmt-006.rst b/Documentation/media/uapi/v4l/pixfmt-006.rst index a9890ff6038b..7ae7dcf73f63 100644 --- a/Documentation/media/uapi/v4l/pixfmt-006.rst +++ b/Documentation/media/uapi/v4l/pixfmt-006.rst @@ -19,9 +19,16 @@ colorspace field of struct :c:type:`v4l2_pix_format` or struct :c:type:`v4l2_pix_format_mplane` needs to be filled in. -.. note:: +.. _hsv-colorspace: - The default R'G'B' quantization is full range for all +On :ref:`HSV formats ` the *Hue* is defined as the angle on +the cylindrical color representation. Usually this angle is measured in +degrees, i.e. 0-360. When we map this angle value into 8 bits, there are +two basic ways to do it: Divide the angular value by 2 (0-179), or use the +whole range, 0-255, dividing the angular value by 1.41. The enum +:c:type:`v4l2_hsv_encoding` specifies which encoding is used. + +.. note:: The default R'G'B' quantization is full range for all colorspaces except for BT.2020 which uses limited range R'G'B' quantization. @@ -123,6 +130,24 @@ needs to be filled in. +.. c:type:: v4l2_hsv_encoding + +.. tabularcolumns:: |p{6.5cm}|p{11.0cm}| + +.. flat-table:: V4L2 HSV Encodings + :header-rows: 1 + :stub-columns: 0 + + * - Identifier + - Details + * - ``V4L2_HSV_ENC_180`` + - For the Hue, each LSB is two degrees. + * - ``V4L2_HSV_ENC_256`` + - For the Hue, the 360 degrees are mapped into 8 bits, i.e. each + LSB is roughly 1.41 degrees. + + + .. c:type:: v4l2_quantization .. tabularcolumns:: |p{6.5cm}|p{11.0cm}| @@ -136,7 +161,7 @@ needs to be filled in. * - ``V4L2_QUANTIZATION_DEFAULT`` - Use the default quantization encoding as defined by the colorspace. This is always full range for R'G'B' (except for the - BT.2020 colorspace) and usually limited range for Y'CbCr. + BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr. * - ``V4L2_QUANTIZATION_FULL_RANGE`` - Use the full range quantization encoding. I.e. the range [0…1] is mapped to [0…255] (with possible clipping to [1…254] to avoid the diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst index 4a579727f61c..3fdb34ce2f09 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst @@ -9,7 +9,8 @@ Packed HSV formats Description =========== -The *hue* (h) is measured in degrees, one LSB represents two degrees. +The *hue* (h) is measured in degrees, the equivalence between degrees and LSBs +depends on the hsv-encoding used, see :ref:`colorspaces`. The *saturation* (s) and the *value* (v) are measured in percentage of the cylinder: 0 being the smallest value and 255 the maximum. diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index 1d3f27d922b2..12622b2593fa 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -87,6 +87,10 @@ replace symbol V4L2_YCBCR_ENC_XV601 :c:type:`v4l2_ycbcr_encoding` replace symbol V4L2_YCBCR_ENC_XV709 :c:type:`v4l2_ycbcr_encoding` replace symbol V4L2_YCBCR_ENC_SMPTE240M :c:type:`v4l2_ycbcr_encoding` +# Documented enum v4l2_hsv_encoding +replace symbol V4L2_HSV_ENC_180 :c:type:`v4l2_hsv_encoding` +replace symbol V4L2_HSV_ENC_256 :c:type:`v4l2_hsv_encoding` + # Documented enum v4l2_quantization replace symbol V4L2_QUANTIZATION_DEFAULT :c:type:`v4l2_quantization` replace symbol V4L2_QUANTIZATION_FULL_RANGE :c:type:`v4l2_quantization` -- cgit v1.2.3 From 429175e41f01419ad81f144acabb09be904682cd Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Mon, 18 Jul 2016 09:16:15 -0300 Subject: [media] vivid: Add support for HSV encoding Support HSV encoding. Most of the logic is replicated from ycbcr_enc. Signed-off-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 25 +++++++++++++++++-------- drivers/media/platform/vivid/vivid-core.h | 1 + drivers/media/platform/vivid/vivid-ctrls.c | 25 +++++++++++++++++++++++++ drivers/media/platform/vivid/vivid-vid-cap.c | 17 +++++++++++++++-- drivers/media/platform/vivid/vivid-vid-common.c | 2 ++ drivers/media/platform/vivid/vivid-vid-out.c | 1 + include/media/v4l2-tpg.h | 15 +++++++++++++++ 7 files changed, 76 insertions(+), 10 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index ed37ae307cac..28d7b072d867 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -504,6 +504,7 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b, int max_rgb, min_rgb, diff_rgb; int aux; int third; + int third_size; r >>= 4; g >>= 4; @@ -530,30 +531,36 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b, return; } + third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85; + /* Hue */ if (max_rgb == r) { aux = g - b; third = 0; } else if (max_rgb == g) { aux = b - r; - third = 60; + third = third_size; } else { aux = r - g; - third = 120; + third = third_size * 2; } - aux *= 30; + aux *= third_size / 2; aux += diff_rgb / 2; aux /= diff_rgb; aux += third; /* Clamp Hue */ - if (aux < 0) - aux += 180; - else if (aux > 180) - aux -= 180; - *h = aux; + if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) { + if (aux < 0) + aux += 180; + else if (aux > 180) + aux -= 180; + } else { + aux = aux & 0xff; + } + *h = aux; } static void rgb2ycbcr(const int m[3][3], int r, int g, int b, @@ -1928,6 +1935,7 @@ static void tpg_recalc(struct tpg_data *tpg) tpg->recalc_lines = true; tpg->real_xfer_func = tpg->xfer_func; tpg->real_ycbcr_enc = tpg->ycbcr_enc; + tpg->real_hsv_enc = tpg->hsv_enc; tpg->real_quantization = tpg->quantization; if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT) @@ -2018,6 +2026,7 @@ void tpg_log_status(struct tpg_data *tpg) pr_info("tpg colorspace: %d\n", tpg->colorspace); pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func); pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc); + pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc); pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization); pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range); } diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index b59b49456d45..5cdf95bdc4d1 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -346,6 +346,7 @@ struct vivid_dev { struct v4l2_dv_timings dv_timings_out; u32 colorspace_out; u32 ycbcr_enc_out; + u32 hsv_enc_out; u32 quantization_out; u32 xfer_func_out; u32 service_set_out; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index aceb38d9f7e7..34731f71cc00 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -79,6 +79,7 @@ #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) +#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) @@ -378,6 +379,14 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) vivid_send_source_change(dev, HDMI); vivid_send_source_change(dev, WEBCAM); break; + case VIVID_CID_HSV_ENC: + tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 : + V4L2_HSV_ENC_180); + vivid_send_source_change(dev, TV); + vivid_send_source_change(dev, SVID); + vivid_send_source_change(dev, HDMI); + vivid_send_source_change(dev, WEBCAM); + break; case VIVID_CID_QUANTIZATION: tpg_s_quantization(&dev->tpg, ctrl->val); vivid_send_source_change(dev, TV); @@ -778,6 +787,21 @@ static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = { .qmenu = vivid_ctrl_ycbcr_enc_strings, }; +static const char * const vivid_ctrl_hsv_enc_strings[] = { + "Hue 0-179", + "Hue 0-256", + NULL, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_HSV_ENC, + .name = "HSV Encoding", + .type = V4L2_CTRL_TYPE_MENU, + .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2, + .qmenu = vivid_ctrl_hsv_enc_strings, +}; + static const char * const vivid_ctrl_quantization_strings[] = { "Default", "Full Range", @@ -1454,6 +1478,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, &vivid_ctrl_colorspace, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); + v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); } diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index d5c84ecf2027..c52dd8787794 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -510,6 +510,13 @@ static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev) return dev->ycbcr_enc_out; } +static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev) +{ + if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + return tpg_g_hsv_enc(&dev->tpg); + return dev->hsv_enc_out; +} + static unsigned vivid_quantization_cap(struct vivid_dev *dev) { if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) @@ -530,7 +537,10 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv, mp->pixelformat = dev->fmt_cap->fourcc; mp->colorspace = vivid_colorspace_cap(dev); mp->xfer_func = vivid_xfer_func_cap(dev); - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV) + mp->hsv_enc = vivid_hsv_enc_cap(dev); + else + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); mp->quantization = vivid_quantization_cap(dev); mp->num_planes = dev->fmt_cap->buffers; for (p = 0; p < mp->num_planes; p++) { @@ -618,7 +628,10 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); } mp->colorspace = vivid_colorspace_cap(dev); - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + if (fmt->color_enc == TGP_COLOR_ENC_HSV) + mp->hsv_enc = vivid_hsv_enc_cap(dev); + else + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); mp->xfer_func = vivid_xfer_func_cap(dev); mp->quantization = vivid_quantization_cap(dev); memset(mp->reserved, 0, sizeof(mp->reserved)); diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index e0df44151461..3d003fb913ed 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -630,6 +630,7 @@ void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt) mp->field = pix->field; mp->colorspace = pix->colorspace; mp->xfer_func = pix->xfer_func; + /* Also copies hsv_enc */ mp->ycbcr_enc = pix->ycbcr_enc; mp->quantization = pix->quantization; mp->num_planes = 1; @@ -659,6 +660,7 @@ int fmt_sp2mp_func(struct file *file, void *priv, pix->field = mp->field; pix->colorspace = mp->colorspace; pix->xfer_func = mp->xfer_func; + /* Also copies hsv_enc */ pix->ycbcr_enc = mp->ycbcr_enc; pix->quantization = mp->quantization; pix->sizeimage = ppix->sizeimage; diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index dd609eea4753..7ba52ee98371 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -256,6 +256,7 @@ void vivid_update_format_out(struct vivid_dev *dev) } dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT; dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; + dev->hsv_enc_out = V4L2_HSV_ENC_180; dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; dev->compose_out = dev->sink_rect; dev->compose_bounds_out = dev->sink_rect; diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h index 8abed92317e8..13e49d85cae3 100644 --- a/include/media/v4l2-tpg.h +++ b/include/media/v4l2-tpg.h @@ -130,6 +130,7 @@ struct tpg_data { u32 colorspace; u32 xfer_func; u32 ycbcr_enc; + u32 hsv_enc; /* * Stores the actual transfer function, i.e. will never be * V4L2_XFER_FUNC_DEFAULT. @@ -139,6 +140,7 @@ struct tpg_data { * Stores the actual Y'CbCr encoding, i.e. will never be * V4L2_YCBCR_ENC_DEFAULT. */ + u32 real_hsv_enc; u32 real_ycbcr_enc; u32 quantization; /* @@ -341,6 +343,19 @@ static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) return tpg->ycbcr_enc; } +static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc) +{ + if (tpg->hsv_enc == hsv_enc) + return; + tpg->hsv_enc = hsv_enc; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg) +{ + return tpg->hsv_enc; +} + static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) { if (tpg->xfer_func == xfer_func) -- cgit v1.2.3 From bc9b91e6be38b54a7b245969d0a9247791705e6a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 6 Sep 2016 21:04:53 -0300 Subject: [media] v4l: vsp1: Add support for capture and output in HSV formats Support both the HSV24 and HSV32 formats. From a hardware point of view pretend the formats are RGB, the RPF and WPF will just pass the data through without performing any processing. Signed-off-by: Laurent Pinchart Acked-by: Ricardo Ribalda Delgado Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_pipe.c | 8 ++++++++ drivers/media/platform/vsp1/vsp1_rwpf.c | 2 ++ drivers/media/platform/vsp1/vsp1_video.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index 756ca4ea7668..280ba0804699 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c @@ -78,6 +78,14 @@ static const struct vsp1_format_info vsp1_video_formats[] = { VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 32, 0, 0 }, false, false, 1, 1, false }, + { V4L2_PIX_FMT_HSV24, MEDIA_BUS_FMT_AHSV8888_1X32, + VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | + VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, + 1, { 24, 0, 0 }, false, false, 1, 1, false }, + { V4L2_PIX_FMT_HSV32, MEDIA_BUS_FMT_AHSV8888_1X32, + VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | + VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, + 1, { 32, 0, 0 }, false, false, 1, 1, false }, { V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c index 66e4d7ea31d6..04104ef28fb5 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.c +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c @@ -37,6 +37,7 @@ static int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, { static const unsigned int codes[] = { MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AHSV8888_1X32, MEDIA_BUS_FMT_AYUV8_1X32, }; @@ -78,6 +79,7 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, /* Default to YUV if the requested format is not supported. */ if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index d351b9c768d2..41e8b096dab8 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -124,6 +124,11 @@ static int __vsp1_video_try_format(struct vsp1_video *video, pix->pixelformat = info->fourcc; pix->colorspace = V4L2_COLORSPACE_SRGB; pix->field = V4L2_FIELD_NONE; + + if (info->fourcc == V4L2_PIX_FMT_HSV24 || + info->fourcc == V4L2_PIX_FMT_HSV32) + pix->hsv_enc = V4L2_HSV_ENC_256; + memset(pix->reserved, 0, sizeof(pix->reserved)); /* Align the width and height for YUV 4:2:2 and 4:2:0 formats. */ -- cgit v1.2.3 From 0889e4a1bd569a2f1bf431170cec453b3ca4a658 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 22 Oct 2016 20:45:23 -0200 Subject: [media] spca506: rewrite a commented line to avoid wrong parsing Keeping Documentation/media/v4l-drivers/gspca-cardlist.rst in sync with the gspca script requires a parser. Simplify the commented line, to make the parser work better. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/spca506.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/gspca/spca506.c b/drivers/media/usb/gspca/spca506.c index bcd2c04c770e..ee84863d27d4 100644 --- a/drivers/media/usb/gspca/spca506.c +++ b/drivers/media/usb/gspca/spca506.c @@ -581,8 +581,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x06e1, 0xa190)}, -/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 - {USB_DEVICE(0x0733, 0x0430)}, */ +/* {USB_DEVICE(0x0733, 0x0430)}, FIXME: may be IntelPCCameraPro BRIDGE_SPCA505 */ {USB_DEVICE(0x0734, 0x043b)}, {USB_DEVICE(0x99fa, 0x8988)}, {} -- cgit v1.2.3 From b2fdd0ee948f39fb01c53fa15207a8cae71e0a55 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 22 Oct 2016 19:59:57 -0200 Subject: [media] stv06xx: store device name after the USB_DEVICE line That makes easier to parse the names, in order to sync it with gspca-cardlist.rst. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/stv06xx/stv06xx.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 562ddb050cfd..fef7a784b879 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -579,18 +579,12 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, /* -- module initialisation -- */ static const struct usb_device_id device_table[] = { - /* QuickCam Express */ - {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, - /* LEGO cam / QuickCam Web */ - {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, - /* Dexxa WebCam USB */ - {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, - /* QuickCam Messenger */ - {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Communicate */ - {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, + {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* QuickCam Express */ + {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, /* LEGO cam / QuickCam Web */ + {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, /* Dexxa WebCam USB */ + {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, /* QuickCam Messenger */ + {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, /* QuickCam Communicate */ + {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, /* QuickCam Messenger (new) */ {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From 959fe10443aa3b184f9ae1af4abbbf74bdfbf25a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 22 Oct 2016 19:29:26 -0200 Subject: [media] gspca-cardlist.rst: sort entries and adjust table margins Some entries are out of order. While here, clear spaces/tabs. The content remains the same, with the exeption of one duplicated entry from the same driver, where two different brand names share the same entry. The content of such cell was merged, using a comma. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/v4l-drivers/gspca-cardlist.rst | 805 ++++++++++----------- 1 file changed, 402 insertions(+), 403 deletions(-) diff --git a/Documentation/media/v4l-drivers/gspca-cardlist.rst b/Documentation/media/v4l-drivers/gspca-cardlist.rst index 33a8ac7d73ab..76a1c6389b2e 100644 --- a/Documentation/media/v4l-drivers/gspca-cardlist.rst +++ b/Documentation/media/v4l-drivers/gspca-cardlist.rst @@ -6,407 +6,406 @@ The modules for the gspca webcam drivers are: - gspca_main: main driver - gspca\_\ *driver*: subdriver module with *driver* as follows -========= ========= ==================================================================== +========= ========= =================================================================== *driver* vend:prod Device -========= ========= ==================================================================== -spca501 0000:0000 MystFromOri Unknown Camera -spca508 0130:0130 Clone Digital Webcam 11043 -zc3xx 03f0:1b07 HP Premium Starter Cam -m5602 0402:5602 ALi Video Camera Controller -spca501 040a:0002 Kodak DVC-325 -spca500 040a:0300 Kodak EZ200 -zc3xx 041e:041e Creative WebCam Live! -ov519 041e:4003 Video Blaster WebCam Go Plus -spca500 041e:400a Creative PC-CAM 300 -sunplus 041e:400b Creative PC-CAM 600 -sunplus 041e:4012 PC-Cam350 -sunplus 041e:4013 Creative Pccam750 -zc3xx 041e:4017 Creative Webcam Mobile PD1090 -spca508 041e:4018 Creative Webcam Vista (PD1100) -spca561 041e:401a Creative Webcam Vista (PD1100) -zc3xx 041e:401c Creative NX -spca505 041e:401d Creative Webcam NX ULTRA -zc3xx 041e:401e Creative Nx Pro -zc3xx 041e:401f Creative Webcam Notebook PD1171 -pac207 041e:4028 Creative Webcam Vista Plus -zc3xx 041e:4029 Creative WebCam Vista Pro -zc3xx 041e:4034 Creative Instant P0620 -zc3xx 041e:4035 Creative Instant P0620D -zc3xx 041e:4036 Creative Live ! -sq930x 041e:4038 Creative Joy-IT -zc3xx 041e:403a Creative Nx Pro 2 -spca561 041e:403b Creative Webcam Vista (VF0010) -sq930x 041e:403c Creative Live! Ultra -sq930x 041e:403d Creative Live! Ultra for Notebooks -sq930x 041e:4041 Creative Live! Motion -zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) -ov519 041e:4052 Creative Live! VISTA IM -zc3xx 041e:4053 Creative Live!Cam Video IM -vc032x 041e:405b Creative Live! Cam Notebook Ultra (VC0130) -ov519 041e:405f Creative Live! VISTA VF0330 -ov519 041e:4060 Creative Live! VISTA VF0350 -ov519 041e:4061 Creative Live! VISTA VF0400 -ov519 041e:4064 Creative Live! VISTA VF0420 -ov519 041e:4067 Creative Live! Cam Video IM (VF0350) -ov519 041e:4068 Creative Live! VISTA VF0470 -spca561 0458:7004 Genius VideoCAM Express V2 -sn9c2028 0458:7005 Genius Smart 300, version 2 -sunplus 0458:7006 Genius Dsc 1.3 Smart -zc3xx 0458:7007 Genius VideoCam V2 -zc3xx 0458:700c Genius VideoCam V3 -zc3xx 0458:700f Genius VideoCam Web V2 -sonixj 0458:7025 Genius Eye 311Q -sn9c20x 0458:7029 Genius Look 320s -sonixj 0458:702e Genius Slim 310 NB -sn9c20x 0458:7045 Genius Look 1320 V2 -sn9c20x 0458:704a Genius Slim 1320 -sn9c20x 0458:704c Genius i-Look 1321 -sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) -sonixj 045e:00f5 MicroSoft VX3000 -sonixj 045e:00f7 MicroSoft VX1000 -ov519 045e:028c Micro$oft xbox cam -spca508 0461:0815 Micro Innovation IC200 -sunplus 0461:0821 Fujifilm MV-1 -zc3xx 0461:0a00 MicroInnovation WebCam320 -stv06xx 046d:0840 QuickCam Express -stv06xx 046d:0850 LEGO cam / QuickCam Web -stv06xx 046d:0870 Dexxa WebCam USB -spca500 046d:0890 Logitech QuickCam traveler -vc032x 046d:0892 Logitech Orbicam -vc032x 046d:0896 Logitech Orbicam -vc032x 046d:0897 Logitech QuickCam for Dell notebooks -zc3xx 046d:089d Logitech QuickCam E2500 -zc3xx 046d:08a0 Logitech QC IM -zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound -zc3xx 046d:08a2 Labtec Webcam Pro -zc3xx 046d:08a3 Logitech QC Chat -zc3xx 046d:08a6 Logitech QCim -zc3xx 046d:08a7 Logitech QuickCam Image -zc3xx 046d:08a9 Logitech Notebook Deluxe -zc3xx 046d:08aa Labtec Webcam Notebook -zc3xx 046d:08ac Logitech QuickCam Cool -zc3xx 046d:08ad Logitech QCCommunicate STX -zc3xx 046d:08ae Logitech QuickCam for Notebooks -zc3xx 046d:08af Logitech QuickCam Cool -zc3xx 046d:08b9 Logitech QuickCam Express -zc3xx 046d:08d7 Logitech QCam STX -zc3xx 046d:08d9 Logitech QuickCam IM/Connect -zc3xx 046d:08d8 Logitech Notebook Deluxe -zc3xx 046d:08da Logitech QuickCam Messenger -zc3xx 046d:08dd Logitech QuickCam for Notebooks -spca500 046d:0900 Logitech Inc. ClickSmart 310 -spca500 046d:0901 Logitech Inc. ClickSmart 510 -sunplus 046d:0905 Logitech ClickSmart 820 -tv8532 046d:0920 Logitech QuickCam Express -tv8532 046d:0921 Labtec Webcam -spca561 046d:0928 Logitech QC Express Etch2 -spca561 046d:0929 Labtec Webcam Elch2 -spca561 046d:092a Logitech QC for Notebook -spca561 046d:092b Labtec Webcam Plus -spca561 046d:092c Logitech QC chat Elch2 -spca561 046d:092d Logitech QC Elch2 -spca561 046d:092e Logitech QC Elch2 -spca561 046d:092f Logitech QuickCam Express Plus -sunplus 046d:0960 Logitech ClickSmart 420 -nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring) -sunplus 0471:0322 Philips DMVC1300K -zc3xx 0471:0325 Philips SPC 200 NC -zc3xx 0471:0326 Philips SPC 300 NC -sonixj 0471:0327 Philips SPC 600 NC -sonixj 0471:0328 Philips SPC 700 NC -zc3xx 0471:032d Philips SPC 210 NC -zc3xx 0471:032e Philips SPC 315 NC -sonixj 0471:0330 Philips SPC 710 NC -spca501 0497:c001 Smile International -sunplus 04a5:3003 Benq DC 1300 -sunplus 04a5:3008 Benq DC 1500 -sunplus 04a5:300a Benq DC 3410 -spca500 04a5:300c Benq DC 1016 -benq 04a5:3035 Benq DC E300 -finepix 04cb:0104 Fujifilm FinePix 4800 -finepix 04cb:0109 Fujifilm FinePix A202 -finepix 04cb:010b Fujifilm FinePix A203 -finepix 04cb:010f Fujifilm FinePix A204 -finepix 04cb:0111 Fujifilm FinePix A205 -finepix 04cb:0113 Fujifilm FinePix A210 -finepix 04cb:0115 Fujifilm FinePix A303 -finepix 04cb:0117 Fujifilm FinePix A310 -finepix 04cb:0119 Fujifilm FinePix F401 -finepix 04cb:011b Fujifilm FinePix F402 -finepix 04cb:011d Fujifilm FinePix F410 -finepix 04cb:0121 Fujifilm FinePix F601 -finepix 04cb:0123 Fujifilm FinePix F700 -finepix 04cb:0125 Fujifilm FinePix M603 -finepix 04cb:0127 Fujifilm FinePix S300 -finepix 04cb:0129 Fujifilm FinePix S304 -finepix 04cb:012b Fujifilm FinePix S500 -finepix 04cb:012d Fujifilm FinePix S602 -finepix 04cb:012f Fujifilm FinePix S700 -finepix 04cb:0131 Fujifilm FinePix unknown model -finepix 04cb:013b Fujifilm FinePix unknown model -finepix 04cb:013d Fujifilm FinePix unknown model -finepix 04cb:013f Fujifilm FinePix F420 -sunplus 04f1:1001 JVC GC A50 -spca561 04fc:0561 Flexcam 100 -spca1528 04fc:1528 Sunplus MD80 clone -sunplus 04fc:500c Sunplus CA500C -sunplus 04fc:504a Aiptek Mini PenCam 1.3 -sunplus 04fc:504b Maxell MaxPocket LE 1.3 -sunplus 04fc:5330 Digitrex 2110 -sunplus 04fc:5360 Sunplus Generic -spca500 04fc:7333 PalmPixDC85 -sunplus 04fc:ffff Pure DigitalDakota -nw80x 0502:d001 DVC V6 -spca501 0506:00df 3Com HomeConnect Lite -sunplus 052b:1507 Megapixel 5 Pretec DC-1007 -sunplus 052b:1513 Megapix V4 -sunplus 052b:1803 MegaImage VI -nw80x 052b:d001 EZCam Pro p35u -tv8532 0545:808b Veo Stingray -tv8532 0545:8333 Veo Stingray -sunplus 0546:3155 Polaroid PDC3070 -sunplus 0546:3191 Polaroid Ion 80 -sunplus 0546:3273 Polaroid PDC2030 -ov519 054c:0154 Sonny toy4 -ov519 054c:0155 Sonny toy5 -cpia1 0553:0002 CPIA CPiA (version1) based cameras -zc3xx 055f:c005 Mustek Wcam300A -spca500 055f:c200 Mustek Gsmart 300 -sunplus 055f:c211 Kowa Bs888e Microcamera -spca500 055f:c220 Gsmart Mini -sunplus 055f:c230 Mustek Digicam 330K -sunplus 055f:c232 Mustek MDC3500 -sunplus 055f:c360 Mustek DV4000 Mpeg4 -sunplus 055f:c420 Mustek gSmart Mini 2 -sunplus 055f:c430 Mustek Gsmart LCD 2 -sunplus 055f:c440 Mustek DV 3000 -sunplus 055f:c520 Mustek gSmart Mini 3 -sunplus 055f:c530 Mustek Gsmart LCD 3 -sunplus 055f:c540 Gsmart D30 -sunplus 055f:c630 Mustek MDC4000 -sunplus 055f:c650 Mustek MDC5500Z -nw80x 055f:d001 Mustek Wcam 300 mini -zc3xx 055f:d003 Mustek WCam300A -zc3xx 055f:d004 Mustek WCam300 AN -conex 0572:0041 Creative Notebook cx11646 -ov519 05a9:0511 Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera -ov519 05a9:0518 Creative WebCam -ov519 05a9:0519 OV519 Microphone -ov519 05a9:0530 OmniVision -ov534_9 05a9:1550 OmniVision VEHO Filmscanner -ov519 05a9:2800 OmniVision SuperCAM -ov519 05a9:4519 Webcam Classic -ov534_9 05a9:8065 OmniVision test kit ov538+ov9712 -ov519 05a9:8519 OmniVision -ov519 05a9:a511 D-Link USB Digital Video Camera -ov519 05a9:a518 D-Link DSB-C310 Webcam -sunplus 05da:1018 Digital Dream Enigma 1.3 -stk014 05e1:0893 Syntek DV4000 -gl860 05e3:0503 Genesys Logic PC Camera -gl860 05e3:f191 Genesys Logic PC Camera -spca561 060b:a001 Maxell Compact Pc PM3 -zc3xx 0698:2003 CTX M730V built in -topro 06a2:0003 TP6800 PC Camera, CmoX CX0342 webcam -topro 06a2:6810 Creative Qmax -nw80x 06a5:0000 Typhoon Webcam 100 USB -nw80x 06a5:d001 Divio based webcams -nw80x 06a5:d800 Divio Chicony TwinkleCam, Trust SpaceCam -spca500 06bd:0404 Agfa CL20 -spca500 06be:0800 Optimedia -nw80x 06be:d001 EZCam Pro p35u -sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom -spca506 06e1:a190 ADS Instant VCD -ov534 06f8:3002 Hercules Blog Webcam -ov534_9 06f8:3003 Hercules Dualpix HD Weblog -sonixj 06f8:3004 Hercules Classic Silver -sonixj 06f8:3008 Hercules Deluxe Optical Glass -pac7302 06f8:3009 Hercules Classic Link -pac7302 06f8:301b Hercules Link -nw80x 0728:d001 AVerMedia Camguard -spca508 0733:0110 ViewQuest VQ110 -spca501 0733:0401 Intel Create and Share -spca501 0733:0402 ViewQuest M318B -spca505 0733:0430 Intel PC Camera Pro -sunplus 0733:1311 Digital Dream Epsilon 1.3 -sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam -sunplus 0733:2211 Jenoptik jdc 21 LCD -sunplus 0733:2221 Mercury Digital Pro 3.1p -sunplus 0733:3261 Concord 3045 spca536a -sunplus 0733:3281 Cyberpix S550V -spca506 0734:043b 3DeMon USB Capture aka -cpia1 0813:0001 QX3 camera -ov519 0813:0002 Dual Mode USB Camera Plus -spca500 084d:0003 D-Link DSC-350 -spca500 08ca:0103 Aiptek PocketDV -sunplus 08ca:0104 Aiptek PocketDVII 1.3 -sunplus 08ca:0106 Aiptek Pocket DV3100+ -mr97310a 08ca:0110 Trust Spyc@m 100 -mr97310a 08ca:0111 Aiptek PenCam VGA+ -sunplus 08ca:2008 Aiptek Mini PenCam 2 M -sunplus 08ca:2010 Aiptek PocketCam 3M -sunplus 08ca:2016 Aiptek PocketCam 2 Mega -sunplus 08ca:2018 Aiptek Pencam SD 2M -sunplus 08ca:2020 Aiptek Slim 3000F -sunplus 08ca:2022 Aiptek Slim 3200 -sunplus 08ca:2024 Aiptek DV3500 Mpeg4 -sunplus 08ca:2028 Aiptek PocketCam4M -sunplus 08ca:2040 Aiptek PocketDV4100M -sunplus 08ca:2042 Aiptek PocketDV5100 -sunplus 08ca:2050 Medion MD 41437 -sunplus 08ca:2060 Aiptek PocketDV5300 -tv8532 0923:010f ICM532 cams -mars 093a:050f Mars-Semi Pc-Camera -mr97310a 093a:010e All known CIF cams with this ID -mr97310a 093a:010f All known VGA cams with this ID -pac207 093a:2460 Qtec Webcam 100 -pac207 093a:2461 HP Webcam -pac207 093a:2463 Philips SPC 220 NC -pac207 093a:2464 Labtec Webcam 1200 -pac207 093a:2468 Webcam WB-1400T -pac207 093a:2470 Genius GF112 -pac207 093a:2471 Genius VideoCam ge111 -pac207 093a:2472 Genius VideoCam ge110 -pac207 093a:2474 Genius iLook 111 -pac207 093a:2476 Genius e-Messenger 112 -pac7311 093a:2600 PAC7311 Typhoon -pac7311 093a:2601 Philips SPC 610 NC -pac7311 093a:2603 Philips SPC 500 NC -pac7311 093a:2608 Trust WB-3300p -pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 -pac7311 093a:260f SnakeCam -pac7302 093a:2620 Apollo AC-905 -pac7302 093a:2621 PAC731x -pac7302 093a:2622 Genius Eye 312 -pac7302 093a:2624 PAC7302 -pac7302 093a:2625 Genius iSlim 310 -pac7302 093a:2626 Labtec 2200 -pac7302 093a:2627 Genius FaceCam 300 -pac7302 093a:2628 Genius iLook 300 -pac7302 093a:2629 Genious iSlim 300 -pac7302 093a:262a Webcam 300k -pac7302 093a:262c Philips SPC 230 NC -jl2005bcd 0979:0227 Various brands, 19 known cameras supported -jeilinj 0979:0280 Sakar 57379 -jeilinj 0979:0280 Sportscam DV15 -zc3xx 0ac8:0302 Z-star Vimicro zc0302 -vc032x 0ac8:0321 Vimicro generic vc0321 -vc032x 0ac8:0323 Vimicro Vc0323 -vc032x 0ac8:0328 A4Tech PK-130MG -zc3xx 0ac8:301b Z-Star zc301b -zc3xx 0ac8:303b Vimicro 0x303b -zc3xx 0ac8:305b Z-star Vimicro zc0305b -zc3xx 0ac8:307b PC Camera (ZS0211) -vc032x 0ac8:c001 Sony embedded vimicro -vc032x 0ac8:c002 Sony embedded vimicro -vc032x 0ac8:c301 Samsung Q1 Ultra Premium -spca508 0af9:0010 Hama USB Sightcam 100 -spca508 0af9:0011 Hama USB Sightcam 100 -ov519 0b62:0059 iBOT2 Webcam -sonixb 0c45:6001 Genius VideoCAM NB -sonixb 0c45:6005 Microdia Sweex Mini Webcam -sonixb 0c45:6007 Sonix sn9c101 + Tas5110D -sonixb 0c45:6009 spcaCam@120 -sonixb 0c45:600d spcaCam@120 -sonixb 0c45:6011 Microdia PC Camera (SN9C102) -sonixb 0c45:6019 Generic Sonix OV7630 -sonixb 0c45:6024 Generic Sonix Tas5130c -sonixb 0c45:6025 Xcam Shanga -sonixb 0c45:6028 Sonix Btc Pc380 -sonixb 0c45:6029 spcaCam@150 -sonixb 0c45:602c Generic Sonix OV7630 -sonixb 0c45:602d LIC-200 LG -sonixb 0c45:602e Genius VideoCam Messenger -sonixj 0c45:6040 Speed NVC 350K -sonixj 0c45:607c Sonix sn9c102p Hv7131R -sonixj 0c45:60c0 Sangha Sn535 -sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) -sonixj 0c45:60ec SN9C105+MO4000 -sonixj 0c45:60fb Surfer NoName -sonixj 0c45:60fc LG-LIC300 -sonixj 0c45:60fe Microdia Audio -sonixj 0c45:6100 PC Camera (SN9C128) -sonixj 0c45:6102 PC Camera (SN9C128) -sonixj 0c45:610a PC Camera (SN9C128) -sonixj 0c45:610b PC Camera (SN9C128) -sonixj 0c45:610c PC Camera (SN9C128) -sonixj 0c45:610e PC Camera (SN9C128) -sonixj 0c45:6128 Microdia/Sonix SNP325 -sonixj 0c45:612a Avant Camera -sonixj 0c45:612b Speed-Link REFLECT2 -sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix -sonixj 0c45:6130 Sonix Pccam -sonixj 0c45:6138 Sn9c120 Mo4000 -sonixj 0c45:613a Microdia Sonix PC Camera -sonixj 0c45:613b Surfer SN-206 -sonixj 0c45:613c Sonix Pccam168 -sonixj 0c45:6142 Hama PC-Webcam AC-150 -sonixj 0c45:6143 Sonix Pccam168 -sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia -sonixj 0c45:614a Frontech E-Ccam (JIL-2225) -sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001) -sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111) -sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655) -sn9c20x 0c45:624c PC Camera (SN9C201 + MT9M112) -sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968) -sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650) -sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650) -sn9c20x 0c45:6253 PC Camera (SN9C201 + OV9650) -sn9c20x 0c45:6260 PC Camera (SN9C201 + OV7670) -sn9c20x 0c45:6270 PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112) -sn9c20x 0c45:627b PC Camera (SN9C201 + OV7660) -sn9c20x 0c45:627c PC Camera (SN9C201 + HV7131R) -sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650) -sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001) -sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111) -sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655) -sn9c20x 0c45:628c PC Camera (SN9C201 + MT9M112) -sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968) -sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650) -sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670) -sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112) -sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655) -sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) -sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) -sn9c2028 0c45:8001 Wild Planet Digital Spy Camera -sn9c2028 0c45:8003 Sakar #11199, #6637x, #67480 keychain cams -sn9c2028 0c45:8008 Mini-Shotz ms-350 -sn9c2028 0c45:800a Vivitar Vivicam 3350B -sunplus 0d64:0303 Sunplus FashionCam DXG -ov519 0e96:c001 TRUST 380 USB2 SPACEC@M -etoms 102c:6151 Qcam Sangha CIF -etoms 102c:6251 Qcam xxxxxx VGA -ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go -zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 -spca561 10fd:7e50 FlyCam Usb 100 -zc3xx 10fd:8050 Typhoon Webshot II USB 300k -ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) -pac207 145f:013a Trust WB-1300N -sn9c20x 145f:013d Trust WB-3600R -vc032x 15b8:6001 HP 2.0 Megapixel -vc032x 15b8:6002 HP 2.0 Megapixel rz406aa -spca501 1776:501c Arowana 300K CMOS Camera -t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops -vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC -pac207 2001:f115 D-Link DSB-C120 -sq905c 2770:9050 Disney pix micro (CIF) -sq905c 2770:9051 Lego Bionicle -sq905c 2770:9052 Disney pix micro 2 (VGA) -sq905c 2770:905c All 11 known cameras with this ID -sq905 2770:9120 All 24 known cameras with this ID -sq905c 2770:913d All 4 known cameras with this ID -sq930x 2770:930b Sweex Motion Tracking / I-Tec iCam Tracer -sq930x 2770:930c Trust WB-3500T / NSG Robbie 2.0 -spca500 2899:012c Toptro Industrial -ov519 8020:ef04 ov519 -spca508 8086:0110 Intel Easy PC Camera -spca500 8086:0630 Intel Pocket PC Camera -spca506 99fa:8988 Grandtec V.cap -sn9c20x a168:0610 Dino-Lite Digital Microscope (SN9C201 + HV7131R) -sn9c20x a168:0611 Dino-Lite Digital Microscope (SN9C201 + HV7131R) -sn9c20x a168:0613 Dino-Lite Digital Microscope (SN9C201 + HV7131R) -sn9c20x a168:0618 Dino-Lite Digital Microscope (SN9C201 + HV7131R) -sn9c20x a168:0614 Dino-Lite Digital Microscope (SN9C201 + MT9M111) -sn9c20x a168:0615 Dino-Lite Digital Microscope (SN9C201 + MT9M111) -sn9c20x a168:0617 Dino-Lite Digital Microscope (SN9C201 + MT9M111) -spca561 abcd:cdee Petcam -========= ========= ==================================================================== +========= ========= =================================================================== +spca501 0000:0000 MystFromOri Unknown Camera +spca508 0130:0130 Clone Digital Webcam 11043 +zc3xx 03f0:1b07 HP Premium Starter Cam +m5602 0402:5602 ALi Video Camera Controller +spca501 040a:0002 Kodak DVC-325 +spca500 040a:0300 Kodak EZ200 +zc3xx 041e:041e Creative WebCam Live! +ov519 041e:4003 Video Blaster WebCam Go Plus +spca500 041e:400a Creative PC-CAM 300 +sunplus 041e:400b Creative PC-CAM 600 +sunplus 041e:4012 PC-Cam350 +sunplus 041e:4013 Creative Pccam750 +zc3xx 041e:4017 Creative Webcam Mobile PD1090 +spca508 041e:4018 Creative Webcam Vista (PD1100) +spca561 041e:401a Creative Webcam Vista (PD1100) +zc3xx 041e:401c Creative NX +spca505 041e:401d Creative Webcam NX ULTRA +zc3xx 041e:401e Creative Nx Pro +zc3xx 041e:401f Creative Webcam Notebook PD1171 +pac207 041e:4028 Creative Webcam Vista Plus +zc3xx 041e:4029 Creative WebCam Vista Pro +zc3xx 041e:4034 Creative Instant P0620 +zc3xx 041e:4035 Creative Instant P0620D +zc3xx 041e:4036 Creative Live ! +sq930x 041e:4038 Creative Joy-IT +zc3xx 041e:403a Creative Nx Pro 2 +spca561 041e:403b Creative Webcam Vista (VF0010) +sq930x 041e:403c Creative Live! Ultra +sq930x 041e:403d Creative Live! Ultra for Notebooks +sq930x 041e:4041 Creative Live! Motion +zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) +ov519 041e:4052 Creative Live! VISTA IM +zc3xx 041e:4053 Creative Live!Cam Video IM +vc032x 041e:405b Creative Live! Cam Notebook Ultra (VC0130) +ov519 041e:405f Creative Live! VISTA VF0330 +ov519 041e:4060 Creative Live! VISTA VF0350 +ov519 041e:4061 Creative Live! VISTA VF0400 +ov519 041e:4064 Creative Live! VISTA VF0420 +ov519 041e:4067 Creative Live! Cam Video IM (VF0350) +ov519 041e:4068 Creative Live! VISTA VF0470 +spca561 0458:7004 Genius VideoCAM Express V2 +sn9c2028 0458:7005 Genius Smart 300, version 2 +sunplus 0458:7006 Genius Dsc 1.3 Smart +zc3xx 0458:7007 Genius VideoCam V2 +zc3xx 0458:700c Genius VideoCam V3 +zc3xx 0458:700f Genius VideoCam Web V2 +sonixj 0458:7025 Genius Eye 311Q +sn9c20x 0458:7029 Genius Look 320s +sonixj 0458:702e Genius Slim 310 NB +sn9c20x 0458:7045 Genius Look 1320 V2 +sn9c20x 0458:704a Genius Slim 1320 +sn9c20x 0458:704c Genius i-Look 1321 +sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) +sonixj 045e:00f5 MicroSoft VX3000 +sonixj 045e:00f7 MicroSoft VX1000 +ov519 045e:028c Micro$oft xbox cam +spca508 0461:0815 Micro Innovation IC200 +sunplus 0461:0821 Fujifilm MV-1 +zc3xx 0461:0a00 MicroInnovation WebCam320 +stv06xx 046d:0840 QuickCam Express +stv06xx 046d:0850 LEGO cam / QuickCam Web +stv06xx 046d:0870 Dexxa WebCam USB +spca500 046d:0890 Logitech QuickCam traveler +vc032x 046d:0892 Logitech Orbicam +vc032x 046d:0896 Logitech Orbicam +vc032x 046d:0897 Logitech QuickCam for Dell notebooks +zc3xx 046d:089d Logitech QuickCam E2500 +zc3xx 046d:08a0 Logitech QC IM +zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound +zc3xx 046d:08a2 Labtec Webcam Pro +zc3xx 046d:08a3 Logitech QC Chat +zc3xx 046d:08a6 Logitech QCim +zc3xx 046d:08a7 Logitech QuickCam Image +zc3xx 046d:08a9 Logitech Notebook Deluxe +zc3xx 046d:08aa Labtec Webcam Notebook +zc3xx 046d:08ac Logitech QuickCam Cool +zc3xx 046d:08ad Logitech QCCommunicate STX +zc3xx 046d:08ae Logitech QuickCam for Notebooks +zc3xx 046d:08af Logitech QuickCam Cool +zc3xx 046d:08b9 Logitech QuickCam Express +zc3xx 046d:08d7 Logitech QCam STX +zc3xx 046d:08d8 Logitech Notebook Deluxe +zc3xx 046d:08d9 Logitech QuickCam IM/Connect +zc3xx 046d:08da Logitech QuickCam Messenger +zc3xx 046d:08dd Logitech QuickCam for Notebooks +spca500 046d:0900 Logitech Inc. ClickSmart 310 +spca500 046d:0901 Logitech Inc. ClickSmart 510 +sunplus 046d:0905 Logitech ClickSmart 820 +tv8532 046d:0920 Logitech QuickCam Express +tv8532 046d:0921 Labtec Webcam +spca561 046d:0928 Logitech QC Express Etch2 +spca561 046d:0929 Labtec Webcam Elch2 +spca561 046d:092a Logitech QC for Notebook +spca561 046d:092b Labtec Webcam Plus +spca561 046d:092c Logitech QC chat Elch2 +spca561 046d:092d Logitech QC Elch2 +spca561 046d:092e Logitech QC Elch2 +spca561 046d:092f Logitech QuickCam Express Plus +sunplus 046d:0960 Logitech ClickSmart 420 +nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring) +sunplus 0471:0322 Philips DMVC1300K +zc3xx 0471:0325 Philips SPC 200 NC +zc3xx 0471:0326 Philips SPC 300 NC +sonixj 0471:0327 Philips SPC 600 NC +sonixj 0471:0328 Philips SPC 700 NC +zc3xx 0471:032d Philips SPC 210 NC +zc3xx 0471:032e Philips SPC 315 NC +sonixj 0471:0330 Philips SPC 710 NC +spca501 0497:c001 Smile International +sunplus 04a5:3003 Benq DC 1300 +sunplus 04a5:3008 Benq DC 1500 +sunplus 04a5:300a Benq DC 3410 +spca500 04a5:300c Benq DC 1016 +benq 04a5:3035 Benq DC E300 +finepix 04cb:0104 Fujifilm FinePix 4800 +finepix 04cb:0109 Fujifilm FinePix A202 +finepix 04cb:010b Fujifilm FinePix A203 +finepix 04cb:010f Fujifilm FinePix A204 +finepix 04cb:0111 Fujifilm FinePix A205 +finepix 04cb:0113 Fujifilm FinePix A210 +finepix 04cb:0115 Fujifilm FinePix A303 +finepix 04cb:0117 Fujifilm FinePix A310 +finepix 04cb:0119 Fujifilm FinePix F401 +finepix 04cb:011b Fujifilm FinePix F402 +finepix 04cb:011d Fujifilm FinePix F410 +finepix 04cb:0121 Fujifilm FinePix F601 +finepix 04cb:0123 Fujifilm FinePix F700 +finepix 04cb:0125 Fujifilm FinePix M603 +finepix 04cb:0127 Fujifilm FinePix S300 +finepix 04cb:0129 Fujifilm FinePix S304 +finepix 04cb:012b Fujifilm FinePix S500 +finepix 04cb:012d Fujifilm FinePix S602 +finepix 04cb:012f Fujifilm FinePix S700 +finepix 04cb:0131 Fujifilm FinePix unknown model +finepix 04cb:013b Fujifilm FinePix unknown model +finepix 04cb:013d Fujifilm FinePix unknown model +finepix 04cb:013f Fujifilm FinePix F420 +sunplus 04f1:1001 JVC GC A50 +spca561 04fc:0561 Flexcam 100 +spca1528 04fc:1528 Sunplus MD80 clone +sunplus 04fc:500c Sunplus CA500C +sunplus 04fc:504a Aiptek Mini PenCam 1.3 +sunplus 04fc:504b Maxell MaxPocket LE 1.3 +sunplus 04fc:5330 Digitrex 2110 +sunplus 04fc:5360 Sunplus Generic +spca500 04fc:7333 PalmPixDC85 +sunplus 04fc:ffff Pure DigitalDakota +nw80x 0502:d001 DVC V6 +spca501 0506:00df 3Com HomeConnect Lite +sunplus 052b:1507 Megapixel 5 Pretec DC-1007 +sunplus 052b:1513 Megapix V4 +sunplus 052b:1803 MegaImage VI +nw80x 052b:d001 EZCam Pro p35u +tv8532 0545:808b Veo Stingray +tv8532 0545:8333 Veo Stingray +sunplus 0546:3155 Polaroid PDC3070 +sunplus 0546:3191 Polaroid Ion 80 +sunplus 0546:3273 Polaroid PDC2030 +ov519 054c:0154 Sonny toy4 +ov519 054c:0155 Sonny toy5 +cpia1 0553:0002 CPIA CPiA (version1) based cameras +zc3xx 055f:c005 Mustek Wcam300A +spca500 055f:c200 Mustek Gsmart 300 +sunplus 055f:c211 Kowa Bs888e Microcamera +spca500 055f:c220 Gsmart Mini +sunplus 055f:c230 Mustek Digicam 330K +sunplus 055f:c232 Mustek MDC3500 +sunplus 055f:c360 Mustek DV4000 Mpeg4 +sunplus 055f:c420 Mustek gSmart Mini 2 +sunplus 055f:c430 Mustek Gsmart LCD 2 +sunplus 055f:c440 Mustek DV 3000 +sunplus 055f:c520 Mustek gSmart Mini 3 +sunplus 055f:c530 Mustek Gsmart LCD 3 +sunplus 055f:c540 Gsmart D30 +sunplus 055f:c630 Mustek MDC4000 +sunplus 055f:c650 Mustek MDC5500Z +nw80x 055f:d001 Mustek Wcam 300 mini +zc3xx 055f:d003 Mustek WCam300A +zc3xx 055f:d004 Mustek WCam300 AN +conex 0572:0041 Creative Notebook cx11646 +ov519 05a9:0511 Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera +ov519 05a9:0518 Creative WebCam +ov519 05a9:0519 OV519 Microphone +ov519 05a9:0530 OmniVision +ov534_9 05a9:1550 OmniVision VEHO Filmscanner +ov519 05a9:2800 OmniVision SuperCAM +ov519 05a9:4519 Webcam Classic +ov534_9 05a9:8065 OmniVision test kit ov538+ov9712 +ov519 05a9:8519 OmniVision +ov519 05a9:a511 D-Link USB Digital Video Camera +ov519 05a9:a518 D-Link DSB-C310 Webcam +sunplus 05da:1018 Digital Dream Enigma 1.3 +stk014 05e1:0893 Syntek DV4000 +gl860 05e3:0503 Genesys Logic PC Camera +gl860 05e3:f191 Genesys Logic PC Camera +spca561 060b:a001 Maxell Compact Pc PM3 +zc3xx 0698:2003 CTX M730V built in +topro 06a2:0003 TP6800 PC Camera, CmoX CX0342 webcam +topro 06a2:6810 Creative Qmax +nw80x 06a5:0000 Typhoon Webcam 100 USB +nw80x 06a5:d001 Divio based webcams +nw80x 06a5:d800 Divio Chicony TwinkleCam, Trust SpaceCam +spca500 06bd:0404 Agfa CL20 +spca500 06be:0800 Optimedia +nw80x 06be:d001 EZCam Pro p35u +sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom +spca506 06e1:a190 ADS Instant VCD +ov534 06f8:3002 Hercules Blog Webcam +ov534_9 06f8:3003 Hercules Dualpix HD Weblog +sonixj 06f8:3004 Hercules Classic Silver +sonixj 06f8:3008 Hercules Deluxe Optical Glass +pac7302 06f8:3009 Hercules Classic Link +pac7302 06f8:301b Hercules Link +nw80x 0728:d001 AVerMedia Camguard +spca508 0733:0110 ViewQuest VQ110 +spca501 0733:0401 Intel Create and Share +spca501 0733:0402 ViewQuest M318B +spca505 0733:0430 Intel PC Camera Pro +sunplus 0733:1311 Digital Dream Epsilon 1.3 +sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam +sunplus 0733:2211 Jenoptik jdc 21 LCD +sunplus 0733:2221 Mercury Digital Pro 3.1p +sunplus 0733:3261 Concord 3045 spca536a +sunplus 0733:3281 Cyberpix S550V +spca506 0734:043b 3DeMon USB Capture aka +cpia1 0813:0001 QX3 camera +ov519 0813:0002 Dual Mode USB Camera Plus +spca500 084d:0003 D-Link DSC-350 +spca500 08ca:0103 Aiptek PocketDV +sunplus 08ca:0104 Aiptek PocketDVII 1.3 +sunplus 08ca:0106 Aiptek Pocket DV3100+ +mr97310a 08ca:0110 Trust Spyc@m 100 +mr97310a 08ca:0111 Aiptek PenCam VGA+ +sunplus 08ca:2008 Aiptek Mini PenCam 2 M +sunplus 08ca:2010 Aiptek PocketCam 3M +sunplus 08ca:2016 Aiptek PocketCam 2 Mega +sunplus 08ca:2018 Aiptek Pencam SD 2M +sunplus 08ca:2020 Aiptek Slim 3000F +sunplus 08ca:2022 Aiptek Slim 3200 +sunplus 08ca:2024 Aiptek DV3500 Mpeg4 +sunplus 08ca:2028 Aiptek PocketCam4M +sunplus 08ca:2040 Aiptek PocketDV4100M +sunplus 08ca:2042 Aiptek PocketDV5100 +sunplus 08ca:2050 Medion MD 41437 +sunplus 08ca:2060 Aiptek PocketDV5300 +tv8532 0923:010f ICM532 cams +mr97310a 093a:010e All known CIF cams with this ID +mr97310a 093a:010f All known VGA cams with this ID +mars 093a:050f Mars-Semi Pc-Camera +pac207 093a:2460 Qtec Webcam 100 +pac207 093a:2461 HP Webcam +pac207 093a:2463 Philips SPC 220 NC +pac207 093a:2464 Labtec Webcam 1200 +pac207 093a:2468 Webcam WB-1400T +pac207 093a:2470 Genius GF112 +pac207 093a:2471 Genius VideoCam ge111 +pac207 093a:2472 Genius VideoCam ge110 +pac207 093a:2474 Genius iLook 111 +pac207 093a:2476 Genius e-Messenger 112 +pac7311 093a:2600 PAC7311 Typhoon +pac7311 093a:2601 Philips SPC 610 NC +pac7311 093a:2603 Philips SPC 500 NC +pac7311 093a:2608 Trust WB-3300p +pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 +pac7311 093a:260f SnakeCam +pac7302 093a:2620 Apollo AC-905 +pac7302 093a:2621 PAC731x +pac7302 093a:2622 Genius Eye 312 +pac7302 093a:2624 PAC7302 +pac7302 093a:2625 Genius iSlim 310 +pac7302 093a:2626 Labtec 2200 +pac7302 093a:2627 Genius FaceCam 300 +pac7302 093a:2628 Genius iLook 300 +pac7302 093a:2629 Genious iSlim 300 +pac7302 093a:262a Webcam 300k +pac7302 093a:262c Philips SPC 230 NC +jl2005bcd 0979:0227 Various brands, 19 known cameras supported +jeilinj 0979:0280 Sportscam DV15, Sakar 57379 +zc3xx 0ac8:0302 Z-star Vimicro zc0302 +vc032x 0ac8:0321 Vimicro generic vc0321 +vc032x 0ac8:0323 Vimicro Vc0323 +vc032x 0ac8:0328 A4Tech PK-130MG +zc3xx 0ac8:301b Z-Star zc301b +zc3xx 0ac8:303b Vimicro 0x303b +zc3xx 0ac8:305b Z-star Vimicro zc0305b +zc3xx 0ac8:307b PC Camera (ZS0211) +vc032x 0ac8:c001 Sony embedded vimicro +vc032x 0ac8:c002 Sony embedded vimicro +vc032x 0ac8:c301 Samsung Q1 Ultra Premium +spca508 0af9:0010 Hama USB Sightcam 100 +spca508 0af9:0011 Hama USB Sightcam 100 +ov519 0b62:0059 iBOT2 Webcam +sonixb 0c45:6001 Genius VideoCAM NB +sonixb 0c45:6005 Microdia Sweex Mini Webcam +sonixb 0c45:6007 Sonix sn9c101 + Tas5110D +sonixb 0c45:6009 spcaCam@120 +sonixb 0c45:600d spcaCam@120 +sonixb 0c45:6011 Microdia PC Camera (SN9C102) +sonixb 0c45:6019 Generic Sonix OV7630 +sonixb 0c45:6024 Generic Sonix Tas5130c +sonixb 0c45:6025 Xcam Shanga +sonixb 0c45:6028 Sonix Btc Pc380 +sonixb 0c45:6029 spcaCam@150 +sonixb 0c45:602c Generic Sonix OV7630 +sonixb 0c45:602d LIC-200 LG +sonixb 0c45:602e Genius VideoCam Messenger +sonixj 0c45:6040 Speed NVC 350K +sonixj 0c45:607c Sonix sn9c102p Hv7131R +sonixj 0c45:60c0 Sangha Sn535 +sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) +sonixj 0c45:60ec SN9C105+MO4000 +sonixj 0c45:60fb Surfer NoName +sonixj 0c45:60fc LG-LIC300 +sonixj 0c45:60fe Microdia Audio +sonixj 0c45:6100 PC Camera (SN9C128) +sonixj 0c45:6102 PC Camera (SN9C128) +sonixj 0c45:610a PC Camera (SN9C128) +sonixj 0c45:610b PC Camera (SN9C128) +sonixj 0c45:610c PC Camera (SN9C128) +sonixj 0c45:610e PC Camera (SN9C128) +sonixj 0c45:6128 Microdia/Sonix SNP325 +sonixj 0c45:612a Avant Camera +sonixj 0c45:612b Speed-Link REFLECT2 +sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix +sonixj 0c45:6130 Sonix Pccam +sonixj 0c45:6138 Sn9c120 Mo4000 +sonixj 0c45:613a Microdia Sonix PC Camera +sonixj 0c45:613b Surfer SN-206 +sonixj 0c45:613c Sonix Pccam168 +sonixj 0c45:6142 Hama PC-Webcam AC-150 +sonixj 0c45:6143 Sonix Pccam168 +sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia +sonixj 0c45:614a Frontech E-Ccam (JIL-2225) +sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001) +sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111) +sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655) +sn9c20x 0c45:624c PC Camera (SN9C201 + MT9M112) +sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968) +sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650) +sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650) +sn9c20x 0c45:6253 PC Camera (SN9C201 + OV9650) +sn9c20x 0c45:6260 PC Camera (SN9C201 + OV7670) +sn9c20x 0c45:6270 PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112) +sn9c20x 0c45:627b PC Camera (SN9C201 + OV7660) +sn9c20x 0c45:627c PC Camera (SN9C201 + HV7131R) +sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650) +sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001) +sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111) +sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655) +sn9c20x 0c45:628c PC Camera (SN9C201 + MT9M112) +sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968) +sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650) +sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670) +sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112) +sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655) +sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) +sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) +sn9c2028 0c45:8001 Wild Planet Digital Spy Camera +sn9c2028 0c45:8003 Sakar #11199, #6637x, #67480 keychain cams +sn9c2028 0c45:8008 Mini-Shotz ms-350 +sn9c2028 0c45:800a Vivitar Vivicam 3350B +sunplus 0d64:0303 Sunplus FashionCam DXG +ov519 0e96:c001 TRUST 380 USB2 SPACEC@M +etoms 102c:6151 Qcam Sangha CIF +etoms 102c:6251 Qcam xxxxxx VGA +ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go +zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 +spca561 10fd:7e50 FlyCam Usb 100 +zc3xx 10fd:8050 Typhoon Webshot II USB 300k +ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) +pac207 145f:013a Trust WB-1300N +sn9c20x 145f:013d Trust WB-3600R +vc032x 15b8:6001 HP 2.0 Megapixel +vc032x 15b8:6002 HP 2.0 Megapixel rz406aa +spca501 1776:501c Arowana 300K CMOS Camera +t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops +vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC +pac207 2001:f115 D-Link DSB-C120 +sq905c 2770:9050 Disney pix micro (CIF) +sq905c 2770:9051 Lego Bionicle +sq905c 2770:9052 Disney pix micro 2 (VGA) +sq905c 2770:905c All 11 known cameras with this ID +sq905 2770:9120 All 24 known cameras with this ID +sq905c 2770:913d All 4 known cameras with this ID +sq930x 2770:930b Sweex Motion Tracking / I-Tec iCam Tracer +sq930x 2770:930c Trust WB-3500T / NSG Robbie 2.0 +spca500 2899:012c Toptro Industrial +ov519 8020:ef04 ov519 +spca508 8086:0110 Intel Easy PC Camera +spca500 8086:0630 Intel Pocket PC Camera +spca506 99fa:8988 Grandtec V.cap +sn9c20x a168:0610 Dino-Lite Digital Microscope (SN9C201 + HV7131R) +sn9c20x a168:0611 Dino-Lite Digital Microscope (SN9C201 + HV7131R) +sn9c20x a168:0613 Dino-Lite Digital Microscope (SN9C201 + HV7131R) +sn9c20x a168:0614 Dino-Lite Digital Microscope (SN9C201 + MT9M111) +sn9c20x a168:0615 Dino-Lite Digital Microscope (SN9C201 + MT9M111) +sn9c20x a168:0617 Dino-Lite Digital Microscope (SN9C201 + MT9M111) +sn9c20x a168:0618 Dino-Lite Digital Microscope (SN9C201 + HV7131R) +spca561 abcd:cdee Petcam +========= ========= =================================================================== -- cgit v1.2.3 From c3739983d4f32de1a10b1aa7919e2e0c40f0ecbb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 22 Oct 2016 19:47:30 -0200 Subject: [media] gspca-cardlist.rst: update cardlist from drivers USB IDs There are several missing USB IDs that are defined on gspca drivers. Add them. The missing entries were found/created using the following script: Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/v4l-drivers/gspca-cardlist.rst | 44 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Documentation/media/v4l-drivers/gspca-cardlist.rst b/Documentation/media/v4l-drivers/gspca-cardlist.rst index 76a1c6389b2e..474d7418f86a 100644 --- a/Documentation/media/v4l-drivers/gspca-cardlist.rst +++ b/Documentation/media/v4l-drivers/gspca-cardlist.rst @@ -11,12 +11,14 @@ The modules for the gspca webcam drivers are: ========= ========= =================================================================== spca501 0000:0000 MystFromOri Unknown Camera spca508 0130:0130 Clone Digital Webcam 11043 +se401 03e8:0004 Endpoints/AoxSE401 zc3xx 03f0:1b07 HP Premium Starter Cam m5602 0402:5602 ALi Video Camera Controller spca501 040a:0002 Kodak DVC-325 spca500 040a:0300 Kodak EZ200 zc3xx 041e:041e Creative WebCam Live! ov519 041e:4003 Video Blaster WebCam Go Plus +stv0680 041e:4007 spca500 041e:400a Creative PC-CAM 300 sunplus 041e:400b Creative PC-CAM 600 sunplus 041e:4012 PC-Cam350 @@ -28,6 +30,7 @@ zc3xx 041e:401c Creative NX spca505 041e:401d Creative Webcam NX ULTRA zc3xx 041e:401e Creative Nx Pro zc3xx 041e:401f Creative Webcam Notebook PD1171 +zc3xx 041e:4022 pac207 041e:4028 Creative Webcam Vista Plus zc3xx 041e:4029 Creative WebCam Vista Pro zc3xx 041e:4034 Creative Instant P0620 @@ -49,6 +52,7 @@ ov519 041e:4061 Creative Live! VISTA VF0400 ov519 041e:4064 Creative Live! VISTA VF0420 ov519 041e:4067 Creative Live! Cam Video IM (VF0350) ov519 041e:4068 Creative Live! VISTA VF0470 +sn9c2028 0458:7003 GeniusVideocam Live v2 spca561 0458:7004 Genius VideoCAM Express V2 sn9c2028 0458:7005 Genius Smart 300, version 2 sunplus 0458:7006 Genius Dsc 1.3 Smart @@ -65,12 +69,17 @@ sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 ov519 045e:028c Micro$oft xbox cam +kinect 045e:02ae +kinect 045e:02bf spca508 0461:0815 Micro Innovation IC200 sunplus 0461:0821 Fujifilm MV-1 zc3xx 0461:0a00 MicroInnovation WebCam320 -stv06xx 046d:0840 QuickCam Express -stv06xx 046d:0850 LEGO cam / QuickCam Web -stv06xx 046d:0870 Dexxa WebCam USB +stv06xx 046D:08F0 QuickCamMessenger +stv06xx 046D:08F5 QuickCamCommunicate +stv06xx 046D:08F6 QuickCamMessenger (new) +stv06xx 046d:0840 QuickCamExpress +stv06xx 046d:0850 LEGOcam / QuickCam Web +stv06xx 046d:0870 DexxaWebCam USB spca500 046d:0890 Logitech QuickCam traveler vc032x 046d:0892 Logitech Orbicam vc032x 046d:0896 Logitech Orbicam @@ -109,6 +118,7 @@ spca561 046d:092e Logitech QC Elch2 spca561 046d:092f Logitech QuickCam Express Plus sunplus 046d:0960 Logitech ClickSmart 420 nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring) +se401 0471:030b PhilipsPCVC665K sunplus 0471:0322 Philips DMVC1300K zc3xx 0471:0325 Philips SPC 200 NC zc3xx 0471:0326 Philips SPC 300 NC @@ -117,12 +127,17 @@ sonixj 0471:0328 Philips SPC 700 NC zc3xx 0471:032d Philips SPC 210 NC zc3xx 0471:032e Philips SPC 315 NC sonixj 0471:0330 Philips SPC 710 NC +se401 047d:5001 Kensington67014 +se401 047d:5002 Kensington6701(5/7) +se401 047d:5003 Kensington67016 spca501 0497:c001 Smile International sunplus 04a5:3003 Benq DC 1300 sunplus 04a5:3008 Benq DC 1500 sunplus 04a5:300a Benq DC 3410 spca500 04a5:300c Benq DC 1016 benq 04a5:3035 Benq DC E300 +vicam 04c1:009d +konica 04c8:0720 IntelYC 76 finepix 04cb:0104 Fujifilm FinePix 4800 finepix 04cb:0109 Fujifilm FinePix A202 finepix 04cb:010b Fujifilm FinePix A203 @@ -167,9 +182,12 @@ tv8532 0545:8333 Veo Stingray sunplus 0546:3155 Polaroid PDC3070 sunplus 0546:3191 Polaroid Ion 80 sunplus 0546:3273 Polaroid PDC2030 +touptek 0547:6801 TTUCMOS08000KPB, AS MU800 +dtcs033 0547:7303 ov519 054c:0154 Sonny toy4 ov519 054c:0155 Sonny toy5 cpia1 0553:0002 CPIA CPiA (version1) based cameras +stv0680 0553:0202 zc3xx 055f:c005 Mustek Wcam300A spca500 055f:c200 Mustek Gsmart 300 sunplus 055f:c211 Kowa Bs888e Microcamera @@ -204,6 +222,7 @@ sunplus 05da:1018 Digital Dream Enigma 1.3 stk014 05e1:0893 Syntek DV4000 gl860 05e3:0503 Genesys Logic PC Camera gl860 05e3:f191 Genesys Logic PC Camera +vicam 0602:1001 spca561 060b:a001 Maxell Compact Pc PM3 zc3xx 0698:2003 CTX M730V built in topro 06a2:0003 TP6800 PC Camera, CmoX CX0342 webcam @@ -215,6 +234,7 @@ spca500 06bd:0404 Agfa CL20 spca500 06be:0800 Optimedia nw80x 06be:d001 EZCam Pro p35u sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom +sunplus 06d6:0041 spca506 06e1:a190 ADS Instant VCD ov534 06f8:3002 Hercules Blog Webcam ov534_9 06f8:3003 Hercules Dualpix HD Weblog @@ -277,6 +297,7 @@ pac7311 093a:260f SnakeCam pac7302 093a:2620 Apollo AC-905 pac7302 093a:2621 PAC731x pac7302 093a:2622 Genius Eye 312 +pac7302 093a:2623 pac7302 093a:2624 PAC7302 pac7302 093a:2625 Genius iSlim 310 pac7302 093a:2626 Labtec 2200 @@ -286,7 +307,9 @@ pac7302 093a:2629 Genious iSlim 300 pac7302 093a:262a Webcam 300k pac7302 093a:262c Philips SPC 230 NC jl2005bcd 0979:0227 Various brands, 19 known cameras supported +jeilinj 0979:0270 jeilinj 0979:0280 Sportscam DV15, Sakar 57379 +zc3xx 0ac8:0301 zc3xx 0ac8:0302 Z-star Vimicro zc0302 vc032x 0ac8:0321 Vimicro generic vc0321 vc032x 0ac8:0323 Vimicro Vc0323 @@ -310,13 +333,22 @@ sonixb 0c45:6011 Microdia PC Camera (SN9C102) sonixb 0c45:6019 Generic Sonix OV7630 sonixb 0c45:6024 Generic Sonix Tas5130c sonixb 0c45:6025 Xcam Shanga +sonixb 0c45:6027 GeniusEye 310 sonixb 0c45:6028 Sonix Btc Pc380 sonixb 0c45:6029 spcaCam@150 +sonixb 0c45:602a sonixb 0c45:602c Generic Sonix OV7630 sonixb 0c45:602d LIC-200 LG sonixb 0c45:602e Genius VideoCam Messenger sonixj 0c45:6040 Speed NVC 350K sonixj 0c45:607c Sonix sn9c102p Hv7131R +sonixb 0c45:6083 +sonixb 0c45:608c +sonixb 0c45:608f +sonixb 0c45:60a8 +sonixb 0c45:60aa +sonixb 0c45:60af +sonixb 0c45:60b0 sonixj 0c45:60c0 Sangha Sn535 sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) sonixj 0c45:60ec SN9C105+MO4000 @@ -333,11 +365,13 @@ sonixj 0c45:6128 Microdia/Sonix SNP325 sonixj 0c45:612a Avant Camera sonixj 0c45:612b Speed-Link REFLECT2 sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix +sonixj 0c45:612e sonixj 0c45:6130 Sonix Pccam sonixj 0c45:6138 Sn9c120 Mo4000 sonixj 0c45:613a Microdia Sonix PC Camera sonixj 0c45:613b Surfer SN-206 sonixj 0c45:613c Sonix Pccam168 +sonixj 0c45:613e sonixj 0c45:6142 Hama PC-Webcam AC-150 sonixj 0c45:6143 Sonix Pccam168 sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia @@ -377,15 +411,19 @@ etoms 102c:6251 Qcam xxxxxx VGA ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 spca561 10fd:7e50 FlyCam Usb 100 +zc3xx 10fd:804d zc3xx 10fd:8050 Typhoon Webshot II USB 300k ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) pac207 145f:013a Trust WB-1300N +pac7302 145f:013c sn9c20x 145f:013d Trust WB-3600R vc032x 15b8:6001 HP 2.0 Megapixel vc032x 15b8:6002 HP 2.0 Megapixel rz406aa +stk1135 174f:6a31 ASUSlaptop, MT9M112 sensor spca501 1776:501c Arowana 300K CMOS Camera t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC +pac7302 1ae7:2001 SpeedLinkSnappy Mic SL-6825-SBK pac207 2001:f115 D-Link DSB-C120 sq905c 2770:9050 Disney pix micro (CIF) sq905c 2770:9051 Lego Bionicle -- cgit v1.2.3 From 9fd79cf35083e5953c00360c95065939e92f9f1b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 22 Oct 2016 19:51:05 -0200 Subject: [media] gspca-cardlist.rst: update camera names For those cameras that were missing descriptions, update using some web research: https://cateee.net/lkddb/web-lkddb/USB_GSPCA_STV0680.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_ZC3XX.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_KINECT.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_SPCA561.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_VICAM.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_DTCS033.html https://bugs.launchpad.net/ubuntu/+source/linux/+bug/564979 https://cateee.net/lkddb/web-lkddb/USB_GSPCA_PAC7302.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_SONIXB.html https://cateee.net/lkddb/web-lkddb/USB_GSPCA_SONIXJ.html Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/v4l-drivers/gspca-cardlist.rst | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Documentation/media/v4l-drivers/gspca-cardlist.rst b/Documentation/media/v4l-drivers/gspca-cardlist.rst index 474d7418f86a..e18d87e80d78 100644 --- a/Documentation/media/v4l-drivers/gspca-cardlist.rst +++ b/Documentation/media/v4l-drivers/gspca-cardlist.rst @@ -18,7 +18,7 @@ spca501 040a:0002 Kodak DVC-325 spca500 040a:0300 Kodak EZ200 zc3xx 041e:041e Creative WebCam Live! ov519 041e:4003 Video Blaster WebCam Go Plus -stv0680 041e:4007 +stv0680 041e:4007 Go Mini spca500 041e:400a Creative PC-CAM 300 sunplus 041e:400b Creative PC-CAM 600 sunplus 041e:4012 PC-Cam350 @@ -30,7 +30,7 @@ zc3xx 041e:401c Creative NX spca505 041e:401d Creative Webcam NX ULTRA zc3xx 041e:401e Creative Nx Pro zc3xx 041e:401f Creative Webcam Notebook PD1171 -zc3xx 041e:4022 +zc3xx 041e:4022 Webcam NX Pro pac207 041e:4028 Creative Webcam Vista Plus zc3xx 041e:4029 Creative WebCam Vista Pro zc3xx 041e:4034 Creative Instant P0620 @@ -69,9 +69,9 @@ sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 ov519 045e:028c Micro$oft xbox cam -kinect 045e:02ae -kinect 045e:02bf -spca508 0461:0815 Micro Innovation IC200 +kinect 045e:02ae Xbox NUI Camera +kinect 045e:02bf Kinect for Windows NUI Camera +spca561 0461:0815 Micro Innovations IC200 Webcam sunplus 0461:0821 Fujifilm MV-1 zc3xx 0461:0a00 MicroInnovation WebCam320 stv06xx 046D:08F0 QuickCamMessenger @@ -136,7 +136,7 @@ sunplus 04a5:3008 Benq DC 1500 sunplus 04a5:300a Benq DC 3410 spca500 04a5:300c Benq DC 1016 benq 04a5:3035 Benq DC E300 -vicam 04c1:009d +vicam 04c1:009d HomeConnect Webcam [vicam] konica 04c8:0720 IntelYC 76 finepix 04cb:0104 Fujifilm FinePix 4800 finepix 04cb:0109 Fujifilm FinePix A202 @@ -183,11 +183,11 @@ sunplus 0546:3155 Polaroid PDC3070 sunplus 0546:3191 Polaroid Ion 80 sunplus 0546:3273 Polaroid PDC2030 touptek 0547:6801 TTUCMOS08000KPB, AS MU800 -dtcs033 0547:7303 +dtcs033 0547:7303 Anchor Chips, Inc ov519 054c:0154 Sonny toy4 ov519 054c:0155 Sonny toy5 cpia1 0553:0002 CPIA CPiA (version1) based cameras -stv0680 0553:0202 +stv0680 0553:0202 STV0680 Camera zc3xx 055f:c005 Mustek Wcam300A spca500 055f:c200 Mustek Gsmart 300 sunplus 055f:c211 Kowa Bs888e Microcamera @@ -222,7 +222,7 @@ sunplus 05da:1018 Digital Dream Enigma 1.3 stk014 05e1:0893 Syntek DV4000 gl860 05e3:0503 Genesys Logic PC Camera gl860 05e3:f191 Genesys Logic PC Camera -vicam 0602:1001 +vicam 0602:1001 ViCam Webcam spca561 060b:a001 Maxell Compact Pc PM3 zc3xx 0698:2003 CTX M730V built in topro 06a2:0003 TP6800 PC Camera, CmoX CX0342 webcam @@ -234,7 +234,7 @@ spca500 06bd:0404 Agfa CL20 spca500 06be:0800 Optimedia nw80x 06be:d001 EZCam Pro p35u sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom -sunplus 06d6:0041 +sunplus 06d6:0041 Aashima Technology B.V. spca506 06e1:a190 ADS Instant VCD ov534 06f8:3002 Hercules Blog Webcam ov534_9 06f8:3003 Hercules Dualpix HD Weblog @@ -297,7 +297,7 @@ pac7311 093a:260f SnakeCam pac7302 093a:2620 Apollo AC-905 pac7302 093a:2621 PAC731x pac7302 093a:2622 Genius Eye 312 -pac7302 093a:2623 +pac7302 093a:2623 Pixart Imaging, Inc. pac7302 093a:2624 PAC7302 pac7302 093a:2625 Genius iSlim 310 pac7302 093a:2626 Labtec 2200 @@ -307,9 +307,9 @@ pac7302 093a:2629 Genious iSlim 300 pac7302 093a:262a Webcam 300k pac7302 093a:262c Philips SPC 230 NC jl2005bcd 0979:0227 Various brands, 19 known cameras supported -jeilinj 0979:0270 +jeilinj 0979:0270 Sakar 57379 jeilinj 0979:0280 Sportscam DV15, Sakar 57379 -zc3xx 0ac8:0301 +zc3xx 0ac8:0301 Web Camera zc3xx 0ac8:0302 Z-star Vimicro zc0302 vc032x 0ac8:0321 Vimicro generic vc0321 vc032x 0ac8:0323 Vimicro Vc0323 @@ -336,19 +336,19 @@ sonixb 0c45:6025 Xcam Shanga sonixb 0c45:6027 GeniusEye 310 sonixb 0c45:6028 Sonix Btc Pc380 sonixb 0c45:6029 spcaCam@150 -sonixb 0c45:602a +sonixb 0c45:602a Meade ETX-105EC Camera sonixb 0c45:602c Generic Sonix OV7630 sonixb 0c45:602d LIC-200 LG sonixb 0c45:602e Genius VideoCam Messenger sonixj 0c45:6040 Speed NVC 350K sonixj 0c45:607c Sonix sn9c102p Hv7131R -sonixb 0c45:6083 -sonixb 0c45:608c -sonixb 0c45:608f -sonixb 0c45:60a8 -sonixb 0c45:60aa -sonixb 0c45:60af -sonixb 0c45:60b0 +sonixb 0c45:6083 VideoCAM Look +sonixb 0c45:608c VideoCAM Look +sonixb 0c45:608f PC Camera (SN9C103 + OV7630) +sonixb 0c45:60a8 VideoCAM Look +sonixb 0c45:60aa VideoCAM Look +sonixb 0c45:60af VideoCAM Look +sonixb 0c45:60b0 Genius VideoCam Look sonixj 0c45:60c0 Sangha Sn535 sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) sonixj 0c45:60ec SN9C105+MO4000 @@ -365,13 +365,13 @@ sonixj 0c45:6128 Microdia/Sonix SNP325 sonixj 0c45:612a Avant Camera sonixj 0c45:612b Speed-Link REFLECT2 sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix -sonixj 0c45:612e +sonixj 0c45:612e PC Camera (SN9C110) sonixj 0c45:6130 Sonix Pccam sonixj 0c45:6138 Sn9c120 Mo4000 sonixj 0c45:613a Microdia Sonix PC Camera sonixj 0c45:613b Surfer SN-206 sonixj 0c45:613c Sonix Pccam168 -sonixj 0c45:613e +sonixj 0c45:613e PC Camera (SN9C120) sonixj 0c45:6142 Hama PC-Webcam AC-150 sonixj 0c45:6143 Sonix Pccam168 sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia @@ -411,11 +411,11 @@ etoms 102c:6251 Qcam xxxxxx VGA ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 spca561 10fd:7e50 FlyCam Usb 100 -zc3xx 10fd:804d +zc3xx 10fd:804d Typhoon Webshot II Webcam [zc0301] zc3xx 10fd:8050 Typhoon Webshot II USB 300k ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) pac207 145f:013a Trust WB-1300N -pac7302 145f:013c +pac7302 145f:013c Trust sn9c20x 145f:013d Trust WB-3600R vc032x 15b8:6001 HP 2.0 Megapixel vc032x 15b8:6002 HP 2.0 Megapixel rz406aa -- cgit v1.2.3 From 3907fae86ebabd622bd8265285d5b612d5958948 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Oct 2016 08:29:16 -0200 Subject: [media] cardlist: convert them to asciiart tables Instead of using codeblock for the cardlists, use tables, in order to improve their visual when presenting them. Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l-drivers/au0828-cardlist.rst | 18 +- Documentation/media/v4l-drivers/bttv-cardlist.rst | 340 +++++++++--------- .../media/v4l-drivers/cx23885-cardlist.rst | 122 +++---- Documentation/media/v4l-drivers/cx88-cardlist.rst | 188 +++++----- .../media/v4l-drivers/em28xx-cardlist.rst | 206 +++++------ Documentation/media/v4l-drivers/ivtv-cardlist.rst | 61 ++-- .../media/v4l-drivers/saa7134-cardlist.rst | 400 +++++++++++---------- .../media/v4l-drivers/saa7164-cardlist.rst | 36 +- .../media/v4l-drivers/tm6000-cardlist.rst | 39 +- Documentation/media/v4l-drivers/tuner-cardlist.rst | 188 +++++----- .../media/v4l-drivers/usbvision-cardlist.rst | 142 ++++---- 11 files changed, 885 insertions(+), 855 deletions(-) diff --git a/Documentation/media/v4l-drivers/au0828-cardlist.rst b/Documentation/media/v4l-drivers/au0828-cardlist.rst index aed51b4ffb46..82d2567bc7c1 100644 --- a/Documentation/media/v4l-drivers/au0828-cardlist.rst +++ b/Documentation/media/v4l-drivers/au0828-cardlist.rst @@ -1,11 +1,13 @@ AU0828 cards list ================= -.. code-block:: none - - 0 -> Unknown board (au0828) - 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008,2040:7260,2040:7213,2040:7270] - 2 -> Hauppauge HVR850 (au0828) [2040:7240] - 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] - 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] - 5 -> Hauppauge Woodbury (au0828) [05e1:0480,2040:8200] +=========== ========================== ======================================================================================================================= +Card number Card name USB IDs +=========== ========================== ======================================================================================================================= +0 Unknown board +1 Hauppauge HVR950Q 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270 +2 Hauppauge HVR850 2040:7240 +3 DViCO FusionHDTV USB 0fe9:d620 +4 Hauppauge HVR950Q rev xxF8 2040:7201, 2040:7211, 2040:7281 +5 Hauppauge Woodbury 05e1:0480, 2040:8200 +=========== ========================== ======================================================================================================================= diff --git a/Documentation/media/v4l-drivers/bttv-cardlist.rst b/Documentation/media/v4l-drivers/bttv-cardlist.rst index 97a966e7f9c4..28a01cd6cf2e 100644 --- a/Documentation/media/v4l-drivers/bttv-cardlist.rst +++ b/Documentation/media/v4l-drivers/bttv-cardlist.rst @@ -1,172 +1,174 @@ BTTV cards list =============== -.. code-block:: none - - 0 -> *** UNKNOWN/GENERIC *** - 1 -> MIRO PCTV - 2 -> Hauppauge (bt848) - 3 -> STB, Gateway P/N 6000699 (bt848) - 4 -> Intel Create and Share PCI/ Smart Video Recorder III - 5 -> Diamond DTV2000 - 6 -> AVerMedia TVPhone - 7 -> MATRIX-Vision MV-Delta - 8 -> Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 - 9 -> IMS/IXmicro TurboTV - 10 -> Hauppauge (bt878) [0070:13eb,0070:3900,2636:10b4] - 11 -> MIRO PCTV pro - 12 -> ADS Technologies Channel Surfer TV (bt848) - 13 -> AVerMedia TVCapture 98 [1461:0002,1461:0004,1461:0300] - 14 -> Aimslab Video Highway Xtreme (VHX) - 15 -> Zoltrix TV-Max [a1a0:a0fc] - 16 -> Prolink Pixelview PlayTV (bt878) - 17 -> Leadtek WinView 601 - 18 -> AVEC Intercapture - 19 -> Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) - 20 -> CEI Raffles Card - 21 -> Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 - 22 -> Askey CPH050/ Phoebe Tv Master + FM [14ff:3002] - 23 -> Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 [14c7:0101] - 24 -> Askey CPH05X/06X (bt878) [many vendors] [144f:3002,144f:3005,144f:5000,14ff:3000] - 25 -> Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar - 26 -> Hauppauge WinCam newer (bt878) - 27 -> Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 - 28 -> Terratec TerraTV+ Version 1.1 (bt878) [153b:1127,1852:1852] - 29 -> Imagenation PXC200 [1295:200a] - 30 -> Lifeview FlyVideo 98 LR50 [1f7f:1850] - 31 -> Formac iProTV, Formac ProTV I (bt848) - 32 -> Intel Create and Share PCI/ Smart Video Recorder III - 33 -> Terratec TerraTValue Version Bt878 [153b:1117,153b:1118,153b:1119,153b:111a,153b:1134,153b:5018] - 34 -> Leadtek WinFast 2000/ WinFast 2000 XP [107d:6606,107d:6609,6606:217d,f6ff:fff6] - 35 -> Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II [1851:1850,1851:a050] - 36 -> Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner [1852:1852] - 37 -> Prolink PixelView PlayTV pro - 38 -> Askey CPH06X TView99 [144f:3000,144f:a005,a04f:a0fc] - 39 -> Pinnacle PCTV Studio/Rave [11bd:0012,bd11:1200,bd11:ff00,11bd:ff12] - 40 -> STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 [10b4:2636,10b4:2645,121a:3060] - 41 -> AVerMedia TVPhone 98 [1461:0001,1461:0003] - 42 -> ProVideo PV951 [aa0c:146c] - 43 -> Little OnAir TV - 44 -> Sigma TVII-FM - 45 -> MATRIX-Vision MV-Delta 2 - 46 -> Zoltrix Genie TV/FM [15b0:4000,15b0:400a,15b0:400d,15b0:4010,15b0:4016] - 47 -> Terratec TV/Radio+ [153b:1123] - 48 -> Askey CPH03x/ Dynalink Magic TView - 49 -> IODATA GV-BCTV3/PCI [10fc:4020] - 50 -> Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP - 51 -> Eagle Wireless Capricorn2 (bt878A) - 52 -> Pinnacle PCTV Studio Pro - 53 -> Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS - 54 -> Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] - 55 -> Askey CPH031/ BESTBUY Easy TV - 56 -> Lifeview FlyVideo 98FM LR50 [a051:41a0] - 57 -> GrandTec 'Grand Video Capture' (Bt848) [4344:4142] - 58 -> Askey CPH060/ Phoebe TV Master Only (No FM) - 59 -> Askey CPH03x TV Capturer - 60 -> Modular Technology MM100PCTV - 61 -> AG Electronics GMV1 [15cb:0101] - 62 -> Askey CPH061/ BESTBUY Easy TV (bt878) - 63 -> ATI TV-Wonder [1002:0001] - 64 -> ATI TV-Wonder VE [1002:0003] - 65 -> Lifeview FlyVideo 2000S LR90 - 66 -> Terratec TValueRadio [153b:1135,153b:ff3b] - 67 -> IODATA GV-BCTV4/PCI [10fc:4050] - 68 -> 3Dfx VoodooTV FM (Euro) [10b4:2637] - 69 -> Active Imaging AIMMS - 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E) - 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851] - 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011] - 73 -> Sensoray 311/611 [6000:0311,6000:0611] - 74 -> RemoteVision MX (RV605) - 75 -> Powercolor MTV878/ MTV878R/ MTV878F - 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079] - 77 -> GrandTec Multi Capture Card (Bt878) - 78 -> Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF [0a01:17de] - 79 -> DSP Design TCVIDEO - 80 -> Hauppauge WinTV PVR [0070:4500] - 81 -> IODATA GV-BCTV5/PCI [10fc:4070,10fc:d018] - 82 -> Osprey 100/150 (878) [0070:ff00] - 83 -> Osprey 100/150 (848) - 84 -> Osprey 101 (848) - 85 -> Osprey 101/151 - 86 -> Osprey 101/151 w/ svid - 87 -> Osprey 200/201/250/251 - 88 -> Osprey 200/250 [0070:ff01] - 89 -> Osprey 210/220/230 - 90 -> Osprey 500 [0070:ff02] - 91 -> Osprey 540 [0070:ff04] - 92 -> Osprey 2000 [0070:ff03] - 93 -> IDS Eagle - 94 -> Pinnacle PCTV Sat [11bd:001c] - 95 -> Formac ProTV II (bt878) - 96 -> MachTV - 97 -> Euresys Picolo - 98 -> ProVideo PV150 [aa00:1460,aa01:1461,aa02:1462,aa03:1463,aa04:1464,aa05:1465,aa06:1466,aa07:1467] - 99 -> AD-TVK503 - 100 -> Hercules Smart TV Stereo - 101 -> Pace TV & Radio Card - 102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155,0800:a155,0801:a155,0802:a155,0803:a155] - 103 -> Grand X-Guard / Trust 814PCI [0304:0102] - 104 -> Nebula Electronics DigiTV [0071:0101] - 105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433] - 106 -> PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) - 107 -> PHYTEC VD-009-X1 VD-011 Combi (bt878) - 108 -> PHYTEC VD-009 MiniDIN (bt878) - 109 -> PHYTEC VD-009 Combi (bt878) - 110 -> IVC-100 [ff00:a132] - 111 -> IVC-120G [ff00:a182,ff01:a182,ff02:a182,ff03:a182,ff04:a182,ff05:a182,ff06:a182,ff07:a182,ff08:a182,ff09:a182,ff0a:a182,ff0b:a182,ff0c:a182,ff0d:a182,ff0e:a182,ff0f:a182] - 112 -> pcHDTV HD-2000 TV [7063:2000] - 113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00,1822:0026] - 114 -> Winfast VC100 [107d:6607] - 115 -> Teppro TEV-560/InterVision IV-560 - 116 -> SIMUS GVC1100 [aa6a:82b2] - 117 -> NGS NGSTV+ - 118 -> LMLBT4 - 119 -> Tekram M205 PRO - 120 -> Conceptronic CONTVFMi - 121 -> Euresys Picolo Tetra [1805:0105,1805:0106,1805:0107,1805:0108] - 122 -> Spirit TV Tuner - 123 -> AVerMedia AVerTV DVB-T 771 [1461:0771] - 124 -> AverMedia AverTV DVB-T 761 [1461:0761] - 125 -> MATRIX Vision Sigma-SQ - 126 -> MATRIX Vision Sigma-SLC - 127 -> APAC Viewcomp 878(AMAX) - 128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10,18ac:db11] - 129 -> V-Gear MyVCD - 130 -> Super TV Tuner - 131 -> Tibet Systems 'Progress DVR' CS16 - 132 -> Kodicom 4400R (master) - 133 -> Kodicom 4400R (slave) - 134 -> Adlink RTV24 - 135 -> DViCO FusionHDTV 5 Lite [18ac:d500] - 136 -> Acorp Y878F [9511:1540] - 137 -> Conceptronic CTVFMi v2 [036e:109e] - 138 -> Prolink Pixelview PV-BT878P+ (Rev.2E) - 139 -> Prolink PixelView PlayTV MPEG2 PV-M4900 - 140 -> Osprey 440 [0070:ff07] - 141 -> Asound Skyeye PCTV - 142 -> Sabrent TV-FM (bttv version) - 143 -> Hauppauge ImpactVCB (bt878) [0070:13eb] - 144 -> MagicTV - 145 -> SSAI Security Video Interface [4149:5353] - 146 -> SSAI Ultrasound Video Interface [414a:5353] - 147 -> VoodooTV 200 (USA) [121a:3000] - 148 -> DViCO FusionHDTV 2 [dbc0:d200] - 149 -> Typhoon TV-Tuner PCI (50684) - 150 -> Geovision GV-600 [008a:763c] - 151 -> Kozumi KTV-01C - 152 -> Encore ENL TV-FM-2 [1000:1801] - 153 -> PHYTEC VD-012 (bt878) - 154 -> PHYTEC VD-012-X1 (bt878) - 155 -> PHYTEC VD-012-X2 (bt878) - 156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050] - 157 -> Geovision GV-800(S) (master) [800a:763d] - 158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d] - 159 -> ProVideo PV183 [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540] - 160 -> Tongwei Video Technology TD-3116 [f200:3116] - 161 -> Aposonic W-DVR [0279:0228] - 162 -> Adlink MPG24 - 163 -> Bt848 Capture 14MHz - 164 -> CyberVision CV06 (SV) - 165 -> Kworld V-Stream Xpert TV PVR878 - 166 -> PCI-8604PW +=========== ================================================================================= ============================================================================================================================================================================== +Card number Card name PCI IDs +=========== ================================================================================= ============================================================================================================================================================================== +0 *** UNKNOWN/GENERIC *** +1 MIRO PCTV +2 Hauppauge (bt848) +3 STB, Gateway P/N 6000699 (bt848) +4 Intel Create and Share PCI/ Smart Video Recorder III +5 Diamond DTV2000 +6 AVerMedia TVPhone +7 MATRIX-Vision MV-Delta +8 Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 +9 IMS/IXmicro TurboTV +10 Hauppauge (bt878) 0070:13eb, 0070:3900, 2636:10b4 +11 MIRO PCTV pro +12 ADS Technologies Channel Surfer TV (bt848) +13 AVerMedia TVCapture 98 1461:0002, 1461:0004, 1461:0300 +14 Aimslab Video Highway Xtreme (VHX) +15 Zoltrix TV-Max a1a0:a0fc +16 Prolink Pixelview PlayTV (bt878) +17 Leadtek WinView 601 +18 AVEC Intercapture +19 Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) +20 CEI Raffles Card +21 Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 +22 Askey CPH050/ Phoebe Tv Master + FM 14ff:3002 +23 Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 14c7:0101 +24 Askey CPH05X/06X (bt878) [many vendors] 144f:3002, 144f:3005, 144f:5000, 14ff:3000 +25 Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar +26 Hauppauge WinCam newer (bt878) +27 Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 +28 Terratec TerraTV+ Version 1.1 (bt878) 153b:1127, 1852:1852 +29 Imagenation PXC200 1295:200a +30 Lifeview FlyVideo 98 LR50 1f7f:1850 +31 Formac iProTV, Formac ProTV I (bt848) +32 Intel Create and Share PCI/ Smart Video Recorder III +33 Terratec TerraTValue Version Bt878 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018 +34 Leadtek WinFast 2000/ WinFast 2000 XP 107d:6606, 107d:6609, 6606:217d, f6ff:fff6 +35 Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II 1851:1850, 1851:a050 +36 Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner 1852:1852 +37 Prolink PixelView PlayTV pro +38 Askey CPH06X TView99 144f:3000, 144f:a005, a04f:a0fc +39 Pinnacle PCTV Studio/Rave 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12 +40 STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 10b4:2636, 10b4:2645, 121a:3060 +41 AVerMedia TVPhone 98 1461:0001, 1461:0003 +42 ProVideo PV951 aa0c:146c +43 Little OnAir TV +44 Sigma TVII-FM +45 MATRIX-Vision MV-Delta 2 +46 Zoltrix Genie TV/FM 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016 +47 Terratec TV/Radio+ 153b:1123 +48 Askey CPH03x/ Dynalink Magic TView +49 IODATA GV-BCTV3/PCI 10fc:4020 +50 Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP +51 Eagle Wireless Capricorn2 (bt878A) +52 Pinnacle PCTV Studio Pro +53 Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS +54 Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] +55 Askey CPH031/ BESTBUY Easy TV +56 Lifeview FlyVideo 98FM LR50 a051:41a0 +57 GrandTec 'Grand Video Capture' (Bt848) 4344:4142 +58 Askey CPH060/ Phoebe TV Master Only (No FM) +59 Askey CPH03x TV Capturer +60 Modular Technology MM100PCTV +61 AG Electronics GMV1 15cb:0101 +62 Askey CPH061/ BESTBUY Easy TV (bt878) +63 ATI TV-Wonder 1002:0001 +64 ATI TV-Wonder VE 1002:0003 +65 Lifeview FlyVideo 2000S LR90 +66 Terratec TValueRadio 153b:1135, 153b:ff3b +67 IODATA GV-BCTV4/PCI 10fc:4050 +68 3Dfx VoodooTV FM (Euro) 10b4:2637 +69 Active Imaging AIMMS +70 Prolink Pixelview PV-BT878P+ (Rev.4C,8E) +71 Lifeview FlyVideo 98EZ (capture only) LR51 1851:1851 +72 Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) 1554:4011 +73 Sensoray 311/611 6000:0311, 6000:0611 +74 RemoteVision MX (RV605) +75 Powercolor MTV878/ MTV878R/ MTV878F +76 Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) 0e11:0079 +77 GrandTec Multi Capture Card (Bt878) +78 Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF 0a01:17de +79 DSP Design TCVIDEO +80 Hauppauge WinTV PVR 0070:4500 +81 IODATA GV-BCTV5/PCI 10fc:4070, 10fc:d018 +82 Osprey 100/150 (878) 0070:ff00 +83 Osprey 100/150 (848) +84 Osprey 101 (848) +85 Osprey 101/151 +86 Osprey 101/151 w/ svid +87 Osprey 200/201/250/251 +88 Osprey 200/250 0070:ff01 +89 Osprey 210/220/230 +90 Osprey 500 0070:ff02 +91 Osprey 540 0070:ff04 +92 Osprey 2000 0070:ff03 +93 IDS Eagle +94 Pinnacle PCTV Sat 11bd:001c +95 Formac ProTV II (bt878) +96 MachTV +97 Euresys Picolo +98 ProVideo PV150 aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467 +99 AD-TVK503 +100 Hercules Smart TV Stereo +101 Pace TV & Radio Card +102 IVC-200 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155 +103 Grand X-Guard / Trust 814PCI 0304:0102 +104 Nebula Electronics DigiTV 0071:0101 +105 ProVideo PV143 aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433 +106 PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) +107 PHYTEC VD-009-X1 VD-011 Combi (bt878) +108 PHYTEC VD-009 MiniDIN (bt878) +109 PHYTEC VD-009 Combi (bt878) +110 IVC-100 ff00:a132 +111 IVC-120G ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182 +112 pcHDTV HD-2000 TV 7063:2000 +113 Twinhan DST + clones 11bd:0026, 1822:0001, 270f:fc00, 1822:0026 +114 Winfast VC100 107d:6607 +115 Teppro TEV-560/InterVision IV-560 +116 SIMUS GVC1100 aa6a:82b2 +117 NGS NGSTV+ +118 LMLBT4 +119 Tekram M205 PRO +120 Conceptronic CONTVFMi +121 Euresys Picolo Tetra 1805:0105, 1805:0106, 1805:0107, 1805:0108 +122 Spirit TV Tuner +123 AVerMedia AVerTV DVB-T 771 1461:0771 +124 AverMedia AverTV DVB-T 761 1461:0761 +125 MATRIX Vision Sigma-SQ +126 MATRIX Vision Sigma-SLC +127 APAC Viewcomp 878(AMAX) +128 DViCO FusionHDTV DVB-T Lite 18ac:db10, 18ac:db11 +129 V-Gear MyVCD +130 Super TV Tuner +131 Tibet Systems 'Progress DVR' CS16 +132 Kodicom 4400R (master) +133 Kodicom 4400R (slave) +134 Adlink RTV24 +135 DViCO FusionHDTV 5 Lite 18ac:d500 +136 Acorp Y878F 9511:1540 +137 Conceptronic CTVFMi v2 036e:109e +138 Prolink Pixelview PV-BT878P+ (Rev.2E) +139 Prolink PixelView PlayTV MPEG2 PV-M4900 +140 Osprey 440 0070:ff07 +141 Asound Skyeye PCTV +142 Sabrent TV-FM (bttv version) +143 Hauppauge ImpactVCB (bt878) 0070:13eb +144 MagicTV +145 SSAI Security Video Interface 4149:5353 +146 SSAI Ultrasound Video Interface 414a:5353 +147 VoodooTV 200 (USA) 121a:3000 +148 DViCO FusionHDTV 2 dbc0:d200 +149 Typhoon TV-Tuner PCI (50684) +150 Geovision GV-600 008a:763c +151 Kozumi KTV-01C +152 Encore ENL TV-FM-2 1000:1801 +153 PHYTEC VD-012 (bt878) +154 PHYTEC VD-012-X1 (bt878) +155 PHYTEC VD-012-X2 (bt878) +156 IVCE-8784 0000:f050, 0001:f050, 0002:f050, 0003:f050 +157 Geovision GV-800(S) (master) 800a:763d +158 Geovision GV-800(S) (slave) 800b:763d, 800c:763d, 800d:763d +159 ProVideo PV183 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540 +160 Tongwei Video Technology TD-3116 f200:3116 +161 Aposonic W-DVR 0279:0228 +162 Adlink MPG24 +163 Bt848 Capture 14MHz +164 CyberVision CV06 (SV) +165 Kworld V-Stream Xpert TV PVR878 +166 PCI-8604PW +=========== ================================================================================= ============================================================================================================================================================================== diff --git a/Documentation/media/v4l-drivers/cx23885-cardlist.rst b/Documentation/media/v4l-drivers/cx23885-cardlist.rst index f38003255b9a..fd20b50d2c1d 100644 --- a/Documentation/media/v4l-drivers/cx23885-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx23885-cardlist.rst @@ -1,63 +1,65 @@ cx23885 cards list ================== -.. code-block:: none - - 0 -> UNKNOWN/GENERIC [0070:3400] - 1 -> Hauppauge WinTV-HVR1800lp [0070:7600] - 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801,0070:7809] - 3 -> Hauppauge WinTV-HVR1250 [0070:7911] - 4 -> DViCO FusionHDTV5 Express [18ac:d500] - 5 -> Hauppauge WinTV-HVR1500Q [0070:7790,0070:7797] - 6 -> Hauppauge WinTV-HVR1500 [0070:7710,0070:7717] - 7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3] - 8 -> Hauppauge WinTV-HVR1700 [0070:8101] - 9 -> Hauppauge WinTV-HVR1400 [0070:8010] - 10 -> DViCO FusionHDTV7 Dual Express [18ac:d618] - 11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78] - 12 -> Leadtek Winfast PxDVR3200 H [107d:6681] - 13 -> Compro VideoMate E650F [185b:e800] - 14 -> TurboSight TBS 6920 [6920:8888] - 15 -> TeVii S470 [d470:9022] - 16 -> DVBWorld DVB-S2 2005 [0001:2005] - 17 -> NetUP Dual DVB-S2 CI [1b55:2a2c] - 18 -> Hauppauge WinTV-HVR1270 [0070:2211] - 19 -> Hauppauge WinTV-HVR1275 [0070:2215,0070:221d,0070:22f2] - 20 -> Hauppauge WinTV-HVR1255 [0070:2251,0070:22f1] - 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295,0070:2299,0070:229d,0070:22f0,0070:22f3,0070:22f4,0070:22f5] - 22 -> Mygica X8506 DMB-TH [14f1:8651] - 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657] - 24 -> Hauppauge WinTV-HVR1850 [0070:8541] - 25 -> Compro VideoMate E800 [1858:e800] - 26 -> Hauppauge WinTV-HVR1290 [0070:8551] - 27 -> Mygica X8558 PRO DMB-TH [14f1:8578] - 28 -> LEADTEK WinFast PxTV1200 [107d:6f22] - 29 -> GoTView X5 3D Hybrid [5654:2390] - 30 -> NetUP Dual DVB-T/C-CI RF [1b55:e2e4] - 31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39] - 32 -> MPX-885 - 33 -> Mygica X8502/X8507 ISDB-T [14f1:8502] - 34 -> TerraTec Cinergy T PCIe Dual [153b:117e] - 35 -> TeVii S471 [d471:9022] - 36 -> Hauppauge WinTV-HVR1255 [0070:2259] - 37 -> Prof Revolution DVB-S2 8000 [8000:3034] - 38 -> Hauppauge WinTV-HVR4400/HVR5500 [0070:c108,0070:c138,0070:c1f8] - 39 -> AVerTV Hybrid Express Slim HC81R [1461:d939] - 40 -> TurboSight TBS 6981 [6981:8888] - 41 -> TurboSight TBS 6980 [6980:8888] - 42 -> Leadtek Winfast PxPVR2200 [107d:6f21] - 43 -> Hauppauge ImpactVCB-e [0070:7133] - 44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98] - 45 -> DVBSky T9580 [4254:9580] - 46 -> DVBSky T980C [4254:980c] - 47 -> DVBSky S950C [4254:950c] - 48 -> Technotrend TT-budget CT2-4500 CI [13c2:3013] - 49 -> DVBSky S950 [4254:0950] - 50 -> DVBSky S952 [4254:0952] - 51 -> DVBSky T982 [4254:0982] - 52 -> Hauppauge WinTV-HVR5525 [0070:f038] - 53 -> Hauppauge WinTV Starburst [0070:c12a] - 54 -> ViewCast 260e [1576:0260] - 55 -> ViewCast 460e [1576:0460] - 56 -> Hauppauge WinTV-QuadHD-DVB [0070:6a28,0070:6b28] - 57 -> Hauppauge WinTV-QuadHD-ATSC [0070:6a18,0070:6b18] +=========== ==================================== ====================================================================================== +Card number Card name PCI IDs +=========== ==================================== ====================================================================================== +0 UNKNOWN/GENERIC 0070:3400 +1 Hauppauge WinTV-HVR1800lp 0070:7600 +2 Hauppauge WinTV-HVR1800 0070:7800, 0070:7801, 0070:7809 +3 Hauppauge WinTV-HVR1250 0070:7911 +4 DViCO FusionHDTV5 Express 18ac:d500 +5 Hauppauge WinTV-HVR1500Q 0070:7790, 0070:7797 +6 Hauppauge WinTV-HVR1500 0070:7710, 0070:7717 +7 Hauppauge WinTV-HVR1200 0070:71d1, 0070:71d3 +8 Hauppauge WinTV-HVR1700 0070:8101 +9 Hauppauge WinTV-HVR1400 0070:8010 +10 DViCO FusionHDTV7 Dual Express 18ac:d618 +11 DViCO FusionHDTV DVB-T Dual Express 18ac:db78 +12 Leadtek Winfast PxDVR3200 H 107d:6681 +13 Compro VideoMate E650F 185b:e800 +14 TurboSight TBS 6920 6920:8888 +15 TeVii S470 d470:9022 +16 DVBWorld DVB-S2 2005 0001:2005 +17 NetUP Dual DVB-S2 CI 1b55:2a2c +18 Hauppauge WinTV-HVR1270 0070:2211 +19 Hauppauge WinTV-HVR1275 0070:2215, 0070:221d, 0070:22f2 +20 Hauppauge WinTV-HVR1255 0070:2251, 0070:22f1 +21 Hauppauge WinTV-HVR1210 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5 +22 Mygica X8506 DMB-TH 14f1:8651 +23 Magic-Pro ProHDTV Extreme 2 14f1:8657 +24 Hauppauge WinTV-HVR1850 0070:8541 +25 Compro VideoMate E800 1858:e800 +26 Hauppauge WinTV-HVR1290 0070:8551 +27 Mygica X8558 PRO DMB-TH 14f1:8578 +28 LEADTEK WinFast PxTV1200 107d:6f22 +29 GoTView X5 3D Hybrid 5654:2390 +30 NetUP Dual DVB-T/C-CI RF 1b55:e2e4 +31 Leadtek Winfast PxDVR3200 H XC4000 107d:6f39 +32 MPX-885 +33 Mygica X8502/X8507 ISDB-T 14f1:8502 +34 TerraTec Cinergy T PCIe Dual 153b:117e +35 TeVii S471 d471:9022 +36 Hauppauge WinTV-HVR1255 0070:2259 +37 Prof Revolution DVB-S2 8000 8000:3034 +38 Hauppauge WinTV-HVR4400/HVR5500 0070:c108, 0070:c138, 0070:c1f8 +39 AVerTV Hybrid Express Slim HC81R 1461:d939 +40 TurboSight TBS 6981 6981:8888 +41 TurboSight TBS 6980 6980:8888 +42 Leadtek Winfast PxPVR2200 107d:6f21 +43 Hauppauge ImpactVCB-e 0070:7133 +44 DViCO FusionHDTV DVB-T Dual Express2 18ac:db98 +45 DVBSky T9580 4254:9580 +46 DVBSky T980C 4254:980c +47 DVBSky S950C 4254:950c +48 Technotrend TT-budget CT2-4500 CI 13c2:3013 +49 DVBSky S950 4254:0950 +50 DVBSky S952 4254:0952 +51 DVBSky T982 4254:0982 +52 Hauppauge WinTV-HVR5525 0070:f038 +53 Hauppauge WinTV Starburst 0070:c12a +54 ViewCast 260e 1576:0260 +55 ViewCast 460e 1576:0460 +56 Hauppauge WinTV-QuadHD-DVB 0070:6a28, 0070:6b28 +57 Hauppauge WinTV-QuadHD-ATSC 0070:6a18, 0070:6b18 +=========== ==================================== ====================================================================================== diff --git a/Documentation/media/v4l-drivers/cx88-cardlist.rst b/Documentation/media/v4l-drivers/cx88-cardlist.rst index 01128341e1ea..8cc1cea17035 100644 --- a/Documentation/media/v4l-drivers/cx88-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx88-cardlist.rst @@ -1,96 +1,98 @@ CX88 cards list =============== -.. code-block:: none - - 0 -> UNKNOWN/GENERIC - 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401] - 2 -> GDI Black Gold [14c7:0106,14c7:0107] - 3 -> PixelView [1554:4811] - 4 -> ATI TV Wonder Pro [1002:00f8,1002:00f9] - 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613] - 6 -> AverTV Studio 303 (M126) [1461:000b] - 7 -> MSI TV-@nywhere Master [1462:8606] - 8 -> Leadtek Winfast DV2000 [107d:6620,107d:6621] - 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632,107d:6630,107d:6638,107d:6631,107d:6637,107d:663d] - 10 -> IODATA GV-VCP3/PCI [10fc:d003] - 11 -> Prolink PlayTV PVR - 12 -> ASUS PVR-416 [1043:4823,1461:c111] - 13 -> MSI TV-@nywhere - 14 -> KWorld/VStream XPert DVB-T [17de:08a6] - 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] - 16 -> KWorld LTV883RF - 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810,18ac:d800] - 18 -> Hauppauge Nova-T DVB-T [0070:9002,0070:9001,0070:9000] - 19 -> Conexant DVB-T reference design [14f1:0187] - 20 -> Provideo PV259 [1540:2580] - 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10,18ac:db11] - 22 -> pcHDTV HD3000 HDTV [7063:3000] - 23 -> digitalnow DNTV Live! DVB-T [17de:a8a6] - 24 -> Hauppauge WinTV 28xxx (Roslyn) models [0070:2801] - 25 -> Digital-Logic MICROSPACE Entertainment Center (MEC) [14f1:0342] - 26 -> IODATA GV/BCTV7E [10fc:d035] - 27 -> PixelView PlayTV Ultra Pro (Stereo) - 28 -> DViCO FusionHDTV 3 Gold-T [18ac:d820] - 29 -> ADS Tech Instant TV DVB-T PCI [1421:0334] - 30 -> TerraTec Cinergy 1400 DVB-T [153b:1166] - 31 -> DViCO FusionHDTV 5 Gold [18ac:d500] - 32 -> AverMedia UltraTV Media Center PCI 550 [1461:8011] - 33 -> Kworld V-Stream Xpert DVD - 34 -> ATI HDTV Wonder [1002:a101] - 35 -> WinFast DTV1000-T [107d:665f] - 36 -> AVerTV 303 (M126) [1461:000a] - 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202] - 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200] - 39 -> KWorld DVB-S 100 [17de:08b2,1421:0341] - 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] - 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] - 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019] - 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1,12ab:2300] - 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] - 45 -> KWorld HardwareMpegTV XPert [17de:0840,1421:0305] - 46 -> DViCO FusionHDTV DVB-T Hybrid [18ac:db40,18ac:db44] - 47 -> pcHDTV HD5500 HDTV [7063:5500] - 48 -> Kworld MCE 200 Deluxe [17de:0841] - 49 -> PixelView PlayTV P7000 [1554:4813] - 50 -> NPG Tech Real TV FM Top 10 [14f1:0842] - 51 -> WinFast DTV2000 H [107d:665e] - 52 -> Geniatech DVB-S [14f1:0084] - 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404,0070:1400,0070:1401,0070:1402] - 54 -> Norwood Micro TV Tuner - 55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980] - 56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602] - 57 -> ADS Tech Instant Video PCI [1421:0390] - 58 -> Pinnacle PCTV HD 800i [11bd:0051] - 59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530] - 60 -> Pinnacle Hybrid PCTV [12ab:1788] - 61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618,107d:6619] - 62 -> PowerColor RA330 [14f1:ea3d] - 63 -> Geniatech X8000-MT DVBT [14f1:8852] - 64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30] - 65 -> DViCO FusionHDTV 7 Gold [18ac:d610] - 66 -> Prolink Pixelview MPEG 8000GT [1554:4935] - 67 -> Kworld PlusTV HD PCI 120 (ATSC 120) [17de:08c1] - 68 -> Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid [0070:6900,0070:6904,0070:6902] - 69 -> Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 [0070:6905,0070:6906] - 70 -> TeVii S460 DVB-S/S2 [d460:9022] - 71 -> Omicom SS4 DVB-S/S2 PCI [A044:2011] - 72 -> TBS 8920 DVB-S/S2 [8920:8888] - 73 -> TeVii S420 DVB-S [d420:9022] - 74 -> Prolink Pixelview Global Extreme [1554:4976] - 75 -> PROF 7300 DVB-S/S2 [B033:3033] - 76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200] - 77 -> TBS 8910 DVB-S [8910:8888] - 78 -> Prof 6200 DVB-S [b022:3022] - 79 -> Terratec Cinergy HT PCI MKII [153b:1177] - 80 -> Hauppauge WinTV-IR Only [0070:9290] - 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654] - 82 -> WinFast DTV2000 H rev. J [107d:6f2b] - 83 -> Prof 7301 DVB-S/S2 [b034:3034] - 84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd] - 85 -> Twinhan VP-1027 DVB-S [1822:0023] - 86 -> TeVii S464 DVB-S/S2 [d464:9022] - 87 -> Leadtek WinFast DTV2000 H PLUS [107d:6f42] - 88 -> Leadtek WinFast DTV1800 H (XC4000) [107d:6f38] - 89 -> Leadtek TV2000 XP Global (SC4100) [107d:6f36] - 90 -> Leadtek TV2000 XP Global (XC4100) [107d:6f43] +=========== =================================================== ====================================================================================== +Card number Card name PCI IDs +=========== =================================================== ====================================================================================== +0 UNKNOWN/GENERIC +1 Hauppauge WinTV 34xxx models 0070:3400, 0070:3401 +2 GDI Black Gold 14c7:0106, 14c7:0107 +3 PixelView 1554:4811 +4 ATI TV Wonder Pro 1002:00f8, 1002:00f9 +5 Leadtek Winfast 2000XP Expert 107d:6611, 107d:6613 +6 AverTV Studio 303 (M126) 1461:000b +7 MSI TV-@nywhere Master 1462:8606 +8 Leadtek Winfast DV2000 107d:6620, 107d:6621 +9 Leadtek PVR 2000 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d +10 IODATA GV-VCP3/PCI 10fc:d003 +11 Prolink PlayTV PVR +12 ASUS PVR-416 1043:4823, 1461:c111 +13 MSI TV-@nywhere +14 KWorld/VStream XPert DVB-T 17de:08a6 +15 DViCO FusionHDTV DVB-T1 18ac:db00 +16 KWorld LTV883RF +17 DViCO FusionHDTV 3 Gold-Q 18ac:d810, 18ac:d800 +18 Hauppauge Nova-T DVB-T 0070:9002, 0070:9001, 0070:9000 +19 Conexant DVB-T reference design 14f1:0187 +20 Provideo PV259 1540:2580 +21 DViCO FusionHDTV DVB-T Plus 18ac:db10, 18ac:db11 +22 pcHDTV HD3000 HDTV 7063:3000 +23 digitalnow DNTV Live! DVB-T 17de:a8a6 +24 Hauppauge WinTV 28xxx (Roslyn) models 0070:2801 +25 Digital-Logic MICROSPACE Entertainment Center (MEC) 14f1:0342 +26 IODATA GV/BCTV7E 10fc:d035 +27 PixelView PlayTV Ultra Pro (Stereo) +28 DViCO FusionHDTV 3 Gold-T 18ac:d820 +29 ADS Tech Instant TV DVB-T PCI 1421:0334 +30 TerraTec Cinergy 1400 DVB-T 153b:1166 +31 DViCO FusionHDTV 5 Gold 18ac:d500 +32 AverMedia UltraTV Media Center PCI 550 1461:8011 +33 Kworld V-Stream Xpert DVD +34 ATI HDTV Wonder 1002:a101 +35 WinFast DTV1000-T 107d:665f +36 AVerTV 303 (M126) 1461:000a +37 Hauppauge Nova-S-Plus DVB-S 0070:9201, 0070:9202 +38 Hauppauge Nova-SE2 DVB-S 0070:9200 +39 KWorld DVB-S 100 17de:08b2, 1421:0341 +40 Hauppauge WinTV-HVR1100 DVB-T/Hybrid 0070:9400, 0070:9402 +41 Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) 0070:9800, 0070:9802 +42 digitalnow DNTV Live! DVB-T Pro 1822:0025, 1822:0019 +43 KWorld/VStream XPert DVB-T with cx22702 17de:08a1, 12ab:2300 +44 DViCO FusionHDTV DVB-T Dual Digital 18ac:db50, 18ac:db54 +45 KWorld HardwareMpegTV XPert 17de:0840, 1421:0305 +46 DViCO FusionHDTV DVB-T Hybrid 18ac:db40, 18ac:db44 +47 pcHDTV HD5500 HDTV 7063:5500 +48 Kworld MCE 200 Deluxe 17de:0841 +49 PixelView PlayTV P7000 1554:4813 +50 NPG Tech Real TV FM Top 10 14f1:0842 +51 WinFast DTV2000 H 107d:665e +52 Geniatech DVB-S 14f1:0084 +53 Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T 0070:1404, 0070:1400, 0070:1401, 0070:1402 +54 Norwood Micro TV Tuner +55 Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM c180:c980 +56 Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder 0070:9600, 0070:9601, 0070:9602 +57 ADS Tech Instant Video PCI 1421:0390 +58 Pinnacle PCTV HD 800i 11bd:0051 +59 DViCO FusionHDTV 5 PCI nano 18ac:d530 +60 Pinnacle Hybrid PCTV 12ab:1788 +61 Leadtek TV2000 XP Global 107d:6f18, 107d:6618, 107d:6619 +62 PowerColor RA330 14f1:ea3d +63 Geniatech X8000-MT DVBT 14f1:8852 +64 DViCO FusionHDTV DVB-T PRO 18ac:db30 +65 DViCO FusionHDTV 7 Gold 18ac:d610 +66 Prolink Pixelview MPEG 8000GT 1554:4935 +67 Kworld PlusTV HD PCI 120 (ATSC 120) 17de:08c1 +68 Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid 0070:6900, 0070:6904, 0070:6902 +69 Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 0070:6905, 0070:6906 +70 TeVii S460 DVB-S/S2 d460:9022 +71 Omicom SS4 DVB-S/S2 PCI A044:2011 +72 TBS 8920 DVB-S/S2 8920:8888 +73 TeVii S420 DVB-S d420:9022 +74 Prolink Pixelview Global Extreme 1554:4976 +75 PROF 7300 DVB-S/S2 B033:3033 +76 SATTRADE ST4200 DVB-S/S2 b200:4200 +77 TBS 8910 DVB-S 8910:8888 +78 Prof 6200 DVB-S b022:3022 +79 Terratec Cinergy HT PCI MKII 153b:1177 +80 Hauppauge WinTV-IR Only 0070:9290 +81 Leadtek WinFast DTV1800 Hybrid 107d:6654 +82 WinFast DTV2000 H rev. J 107d:6f2b +83 Prof 7301 DVB-S/S2 b034:3034 +84 Samsung SMT 7020 DVB-S 18ac:dc00, 18ac:dccd +85 Twinhan VP-1027 DVB-S 1822:0023 +86 TeVii S464 DVB-S/S2 d464:9022 +87 Leadtek WinFast DTV2000 H PLUS 107d:6f42 +88 Leadtek WinFast DTV1800 H (XC4000) 107d:6f38 +89 Leadtek TV2000 XP Global (SC4100) 107d:6f36 +90 Leadtek TV2000 XP Global (XC4100) 107d:6f43 +=========== =================================================== ====================================================================================== diff --git a/Documentation/media/v4l-drivers/em28xx-cardlist.rst b/Documentation/media/v4l-drivers/em28xx-cardlist.rst index e72f2e5c0898..76b1d301754c 100644 --- a/Documentation/media/v4l-drivers/em28xx-cardlist.rst +++ b/Documentation/media/v4l-drivers/em28xx-cardlist.rst @@ -1,105 +1,107 @@ EM28xx cards list ================= -.. code-block:: none - - 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868,eb1a:2875] - 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] - 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] - 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] - 5 -> MSI VOX USB 2.0 (em2820/em2840) - 6 -> Terratec Cinergy 200 USB (em2800) - 7 -> Leadtek Winfast USB II (em2800) [0413:6023] - 8 -> Kworld USB2800 (em2800) - 9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a,093b:a003] - 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] - 11 -> Terratec Hybrid XS (em2880) - 12 -> Kworld PVR TV 2800 RF (em2820/em2840) - 13 -> Terratec Prodigy XS (em2880) - 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) - 15 -> V-Gear PocketTV (em2800) - 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b] - 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] - 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] - 19 -> EM2860/SAA711X Reference Design (em2860) - 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] - 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] - 22 -> EM2710/EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751] - 23 -> Huaqi DLCW-130 (em2750) - 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] - 25 -> Gadmei UTV310 (em2820/em2840) - 26 -> Hercules Smart TV USB 2.0 (em2820/em2840) - 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840) - 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840) - 29 -> EM2860/TVP5150 Reference Design (em2860) - 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) - 31 -> Usbgear VD204v9 (em2821) - 32 -> Supercomp USB 2.0 TV (em2821) - 33 -> Elgato Video Capture (em2860) [0fd9:0033] - 34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f] - 35 -> Typhoon DVD Maker (em2860) - 36 -> NetGMBH Cam (em2860) - 37 -> Gadmei UTV330 (em2860) [eb1a:50a6] - 38 -> Yakumo MovieMixer (em2861) - 39 -> KWorld PVRTV 300U (em2861) [eb1a:e300] - 40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005] - 41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350] - 42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357,eb1a:e359] - 43 -> Terratec Cinergy T XS (em2870) - 44 -> Terratec Cinergy T XS (MT2060) (em2870) [0ccd:0043] - 45 -> Pinnacle PCTV DVB-T (em2870) - 46 -> Compro, VideoMate U3 (em2870) [185b:2870] - 47 -> KWorld DVB-T 305U (em2880) [eb1a:e305] - 48 -> KWorld DVB-T 310U (em2880) - 49 -> MSI DigiVox A/D (em2880) [eb1a:e310] - 50 -> MSI DigiVox A/D II (em2880) [eb1a:e320] - 51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c] - 52 -> DNT DA2 Hybrid (em2881) - 53 -> Pinnacle Hybrid Pro (em2881) - 54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323] - 55 -> Terratec Cinnergy Hybrid T USB XS (em2882) (em2882) [0ccd:005e,0ccd:0042] - 56 -> Pinnacle Hybrid Pro (330e) (em2882) [2304:0226] - 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] - 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] - 59 -> Pinnacle PCTV HD Mini (em2874) [2304:023f] - 60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f] - 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840) - 62 -> Gadmei TVR200 (em2820/em2840) - 63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] - 64 -> Easy Cap Capture DC-60 (em2860) [1b80:e309] - 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] - 66 -> Empire dual TV (em2880) - 67 -> Terratec Grabby (em2860) [0ccd:0096,0ccd:10AF] - 68 -> Terratec AV350 (em2860) [0ccd:0084] - 69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313] - 70 -> Evga inDtube (em2882) - 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840) - 72 -> Gadmei UTV330+ (em2861) - 73 -> Reddo DVB-C USB TV Box (em2870) - 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800) - 75 -> Dikom DK300 (em2882) - 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] - 77 -> EM2874 Leadership ISDBT (em2874) - 78 -> PCTV nanoStick T2 290e (em28174) [2013:024f] - 79 -> Terratec Cinergy H5 (em2884) [eb1a:2885,0ccd:10a2,0ccd:10ad,0ccd:10b6] - 80 -> PCTV DVB-S2 Stick (460e) (em28174) [2013:024c] - 81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605] - 82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2] - 83 -> Honestech Vidbox NW03 (em2860) [eb1a:5006] - 84 -> MaxMedia UB425-TC (em2874) [1b80:e425] - 85 -> PCTV QuatroStick (510e) (em2884) [2304:0242] - 86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251] - 87 -> Terratec Cinergy HTC USB XS (em2884) [0ccd:008e,0ccd:00ac] - 88 -> C3 Tech Digital Duo HDTV/SDTV USB (em2884) [1b80:e755] - 89 -> Delock 61959 (em2874) [1b80:e1cc] - 90 -> KWorld USB ATSC TV Stick UB435-Q V2 (em2874) [1b80:e346] - 91 -> SpeedLink Vicious And Devine Laplace webcam (em2765) [1ae7:9003,1ae7:9004] - 92 -> PCTV DVB-S2 Stick (461e) (em28178) [2013:0258] - 93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c] - 94 -> PCTV tripleStick (292e) (em28178) [2013:025f,2040:0264] - 95 -> Leadtek VC100 (em2861) [0413:6f07] - 96 -> Terratec Cinergy T2 Stick HD (em28178) [eb1a:8179] - 97 -> Elgato EyeTV Hybrid 2008 INT (em2884) [0fd9:0018] - 98 -> PLEX PX-BCUD (em28178) [3275:0085] - 99 -> Hauppauge WinTV-dualHD DVB (em28174) [2040:0265] +=========== ==================================================================== ================ ================================================================================================================================== +Card number Card name Empia Chip USB IDs +=========== ==================================================================== ================ ================================================================================================================================== +0 Unknown EM2800 video grabber em2800 eb1a:2800 +1 Unknown EM2750/28xx video grabber em2820 or em2840 eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875 +2 Terratec Cinergy 250 USB em2820 or em2840 0ccd:0036 +3 Pinnacle PCTV USB 2 em2820 or em2840 2304:0208 +4 Hauppauge WinTV USB 2 em2820 or em2840 2040:4200, 2040:4201 +5 MSI VOX USB 2.0 em2820 or em2840 +6 Terratec Cinergy 200 USB em2800 +7 Leadtek Winfast USB II em2800 0413:6023 +8 Kworld USB2800 em2800 +9 Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker em2820 or em2840 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003 +10 Hauppauge WinTV HVR 900 em2880 2040:6500 +11 Terratec Hybrid XS em2880 +12 Kworld PVR TV 2800 RF em2820 or em2840 +13 Terratec Prodigy XS em2880 +14 SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 em2820 or em2840 +15 V-Gear PocketTV em2800 +16 Hauppauge WinTV HVR 950 em2883 2040:6513, 2040:6517, 2040:651b +17 Pinnacle PCTV HD Pro Stick em2880 2304:0227 +18 Hauppauge WinTV HVR 900 (R2) em2880 2040:6502 +19 EM2860/SAA711X Reference Design em2860 +20 AMD ATI TV Wonder HD 600 em2880 0438:b002 +21 eMPIA Technology, Inc. GrabBeeX+ Video Encoder em2800 eb1a:2801 +22 EM2710/EM2750/EM2751 webcam grabber em2750 eb1a:2750, eb1a:2751 +23 Huaqi DLCW-130 em2750 +24 D-Link DUB-T210 TV Tuner em2820 or em2840 2001:f112 +25 Gadmei UTV310 em2820 or em2840 +26 Hercules Smart TV USB 2.0 em2820 or em2840 +27 Pinnacle PCTV USB 2 (Philips FM1216ME) em2820 or em2840 +28 Leadtek Winfast USB II Deluxe em2820 or em2840 +29 EM2860/TVP5150 Reference Design em2860 +30 Videology 20K14XUSB USB2.0 em2820 or em2840 +31 Usbgear VD204v9 em2821 +32 Supercomp USB 2.0 TV em2821 +33 Elgato Video Capture em2860 0fd9:0033 +34 Terratec Cinergy A Hybrid XS em2860 0ccd:004f +35 Typhoon DVD Maker em2860 +36 NetGMBH Cam em2860 +37 Gadmei UTV330 em2860 eb1a:50a6 +38 Yakumo MovieMixer em2861 +39 KWorld PVRTV 300U em2861 eb1a:e300 +40 Plextor ConvertX PX-TV100U em2861 093b:a005 +41 Kworld 350 U DVB-T em2870 eb1a:e350 +42 Kworld 355 U DVB-T em2870 eb1a:e355, eb1a:e357, eb1a:e359 +43 Terratec Cinergy T XS em2870 +44 Terratec Cinergy T XS (MT2060) em2870 0ccd:0043 +45 Pinnacle PCTV DVB-T em2870 +46 Compro, VideoMate U3 em2870 185b:2870 +47 KWorld DVB-T 305U em2880 eb1a:e305 +48 KWorld DVB-T 310U em2880 +49 MSI DigiVox A/D em2880 eb1a:e310 +50 MSI DigiVox A/D II em2880 eb1a:e320 +51 Terratec Hybrid XS Secam em2880 0ccd:004c +52 DNT DA2 Hybrid em2881 +53 Pinnacle Hybrid Pro em2881 +54 Kworld VS-DVB-T 323UR em2882 eb1a:e323 +55 Terratec Cinnergy Hybrid T USB XS (em2882) em2882 0ccd:005e, 0ccd:0042 +56 Pinnacle Hybrid Pro (330e) em2882 2304:0226 +57 Kworld PlusTV HD Hybrid 330 em2883 eb1a:a316 +58 Compro VideoMate ForYou/Stereo em2820 or em2840 185b:2041 +59 Pinnacle PCTV HD Mini em2874 2304:023f +60 Hauppauge WinTV HVR 850 em2883 2040:651f +61 Pixelview PlayTV Box 4 USB 2.0 em2820 or em2840 +62 Gadmei TVR200 em2820 or em2840 +63 Kaiomy TVnPC U2 em2860 eb1a:e303 +64 Easy Cap Capture DC-60 em2860 1b80:e309 +65 IO-DATA GV-MVP/SZ em2820 or em2840 04bb:0515 +66 Empire dual TV em2880 +67 Terratec Grabby em2860 0ccd:0096, 0ccd:10AF +68 Terratec AV350 em2860 0ccd:0084 +69 KWorld ATSC 315U HDTV TV Box em2882 eb1a:a313 +70 Evga inDtube em2882 +71 Silvercrest Webcam 1.3mpix em2820 or em2840 +72 Gadmei UTV330+ em2861 +73 Reddo DVB-C USB TV Box em2870 +74 Actionmaster/LinXcel/Digitus VC211A em2800 +75 Dikom DK300 em2882 +76 KWorld PlusTV 340U or UB435-Q (ATSC) em2870 1b80:a340 +77 EM2874 Leadership ISDBT em2874 +78 PCTV nanoStick T2 290e em28174 2013:024f +79 Terratec Cinergy H5 em2884 eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6 +80 PCTV DVB-S2 Stick (460e) em28174 2013:024c +81 Hauppauge WinTV HVR 930C em2884 2040:1605 +82 Terratec Cinergy HTC Stick em2884 0ccd:00b2 +83 Honestech Vidbox NW03 em2860 eb1a:5006 +84 MaxMedia UB425-TC em2874 1b80:e425 +85 PCTV QuatroStick (510e) em2884 2304:0242 +86 PCTV QuatroStick nano (520e) em2884 2013:0251 +87 Terratec Cinergy HTC USB XS em2884 0ccd:008e, 0ccd:00ac +88 C3 Tech Digital Duo HDTV/SDTV USB em2884 1b80:e755 +89 Delock 61959 em2874 1b80:e1cc +90 KWorld USB ATSC TV Stick UB435-Q V2 em2874 1b80:e346 +91 SpeedLink Vicious And Devine Laplace webcam em2765 1ae7:9003, 1ae7:9004 +92 PCTV DVB-S2 Stick (461e) em28178 2013:0258 +93 KWorld USB ATSC TV Stick UB435-Q V3 em2874 1b80:e34c +94 PCTV tripleStick (292e) em28178 2013:025f, 2040:0264 +95 Leadtek VC100 em2861 0413:6f07 +96 Terratec Cinergy T2 Stick HD em28178 eb1a:8179 +97 Elgato EyeTV Hybrid 2008 INT em2884 0fd9:0018 +98 PLEX PX-BCUD em28178 3275:0085 +99 Hauppauge WinTV-dualHD DVB em28174 2040:0265 +=========== ==================================================================== ================ ================================================================================================================================== diff --git a/Documentation/media/v4l-drivers/ivtv-cardlist.rst b/Documentation/media/v4l-drivers/ivtv-cardlist.rst index cd7e79d2963e..754ffa820b4c 100644 --- a/Documentation/media/v4l-drivers/ivtv-cardlist.rst +++ b/Documentation/media/v4l-drivers/ivtv-cardlist.rst @@ -1,29 +1,38 @@ IVTV cards list =============== -.. code-block:: none - - 1 -> Hauppauge WinTV PVR-250 - 2 -> Hauppauge WinTV PVR-350 - 3 -> Hauppauge WinTV PVR-150 or PVR-500 - 4 -> AVerMedia M179 [1461:a3ce,1461:a3cf] - 5 -> Yuan MPG600/Kuroutoshikou iTVC16-STVLP [12ab:fff3,12ab:ffff] - 6 -> Yuan MPG160/Kuroutoshikou iTVC15-STVLP [12ab:0000,10fc:40a0] - 7 -> Yuan PG600/DiamondMM PVR-550 [ff92:0070,ffab:0600] - 8 -> Adaptec AVC-2410 [9005:0093] - 9 -> Adaptec AVC-2010 [9005:0092] - 10 -> NAGASE TRANSGEAR 5000TV [1461:bfff] - 11 -> AOpen VA2000MAX-STN6 [0000:ff5f] - 12 -> YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP [12ab:0600,fbab:0600,1154:0523] - 13 -> I/O Data GV-MVP/RX [10fc:d01e,10fc:d038,10fc:d039] - 14 -> I/O Data GV-MVP/RX2E [10fc:d025] - 15 -> GOTVIEW PCI DVD (partial support only) [12ab:0600] - 16 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600] - 17 -> Yuan MPC622 [ff01:d998] - 18 -> Digital Cowboy DCT-MTVP1 [1461:bfff] - 19 -> Yuan PG600V2/GotView PCI DVD Lite [ffab:0600,ffad:0600] - 20 -> Club3D ZAP-TV1x01 [ffab:0600] - 21 -> AverTV MCE 116 Plus [1461:c439] - 22 -> ASUS Falcon2 [1043:4b66,1043:462e,1043:4b2e] - 23 -> AverMedia PVR-150 Plus [1461:c035] - 24 -> AverMedia EZMaker PCI Deluxe [1461:c03f] +=========== ============================================================= ==================================================== +Card number Card name PCI IDs +=========== ============================================================= ==================================================== +0 Hauppauge WinTV PVR-250 IVTV16 104d:813d +1 Hauppauge WinTV PVR-350 IVTV16 104d:813d +2 Hauppauge WinTV PVR-150 IVTV16 104d:813d +3 AVerMedia M179 IVTV15 1461:a3cf, IVTV15 1461:a3ce +4 Yuan MPG600, Kuroutoshikou ITVC16-STVLP IVTV16 12ab:fff3, IVTV16 12ab:ffff +5 YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI IVTV15 10fc:40a0 +6 Yuan PG600, Diamond PVR-550 IVTV16 ff92:0070, IVTV16 ffab:0600 +7 Adaptec VideOh! AVC-2410 IVTV16 9005:0093 +8 Adaptec VideOh! AVC-2010 IVTV16 9005:0092 +9 Nagase Transgear 5000TV IVTV16 1461:bfff +10 AOpen VA2000MAX-SNT6 IVTV16 0000:ff5f +11 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523 +12 I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039 +13 I/O Data GV-MVP/RX2E IVTV16 10fc:d025 +14 GotView PCI DVD IVTV16 12ab:0600 +15 GotView PCI DVD2 Deluxe IVTV16 ffac:0600 +16 Yuan MPC622 IVTV16 ff01:d998 +17 Digital Cowboy DCT-MTVP1 IVTV16 1461:bfff +18 Yuan PG600-2, GotView PCI DVD Lite IVTV16 ffab:0600, IVTV16 ffad:0600 +19 Club3D ZAP-TV1x01 IVTV16 ffab:0600 +20 AVerTV MCE 116 Plus IVTV16 1461:c439 +21 ASUS Falcon2 IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e +22 AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner IVTV16 1461:c034, IVTV16 1461:c035 +23 AVerMedia EZMaker PCI Deluxe IVTV16 1461:c03f +24 AVerMedia M104 IVTV16 1461:c136 +25 Buffalo PC-MV5L/PCI IVTV16 1154:052b +26 AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner IVTV16 1461:c019, IVTV16 1461:c01b +27 Sony VAIO Giga Pocket (ENX Kikyou) IVTV16 104d:813d +28 Hauppauge WinTV PVR-350 (V1) IVTV16 104d:813d +29 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR) IVTV16 104d:813d +30 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS) IVTV16 104d:813d +=========== ============================================================= ==================================================== diff --git a/Documentation/media/v4l-drivers/saa7134-cardlist.rst b/Documentation/media/v4l-drivers/saa7134-cardlist.rst index 22c1510d9fa6..a5efa8f4b8e4 100644 --- a/Documentation/media/v4l-drivers/saa7134-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7134-cardlist.rst @@ -1,202 +1,204 @@ SAA7134 cards list ================== -.. code-block:: none - - 0 -> UNKNOWN/GENERIC - 1 -> Proteus Pro [philips reference design] [1131:2001,1131:2001] - 2 -> LifeView FlyVIDEO3000 [5168:0138,4e42:0138] - 3 -> LifeView/Typhoon FlyVIDEO2000 [5168:0138,4e42:0138] - 4 -> EMPRESS [1131:6752] - 5 -> SKNet Monster TV [1131:4e85] - 6 -> Tevion MD 9717 - 7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01] - 8 -> Terratec Cinergy 400 TV [153b:1142] - 9 -> Medion 5044 - 10 -> Kworld/KuroutoShikou SAA7130-TVPCI - 11 -> Terratec Cinergy 600 TV [153b:1143] - 12 -> Medion 7134 [16be:0003,16be:5000] - 13 -> Typhoon TV+Radio 90031 - 14 -> ELSA EX-VISION 300TV [1048:226b] - 15 -> ELSA EX-VISION 500TV [1048:226a] - 16 -> ASUS TV-FM 7134 [1043:4842,1043:4830,1043:4840] - 17 -> AOPEN VA1000 POWER [1131:7133] - 18 -> BMK MPEX No Tuner - 19 -> Compro VideoMate TV [185b:c100] - 20 -> Matrox CronosPlus [102B:48d0] - 21 -> 10MOONS PCI TV CAPTURE CARD [1131:2001] - 22 -> AverMedia M156 / Medion 2819 [1461:a70b] - 23 -> BMK MPEX Tuner - 24 -> KNC One TV-Station DVR [1894:a006] - 25 -> ASUS TV-FM 7133 [1043:4843] - 26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b] - 27 -> Manli MuchTV M-TV002 - 28 -> Manli MuchTV M-TV001 - 29 -> Nagase Sangyo TransGear 3000TV [1461:050c] - 30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4] - 31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5] - 32 -> AVACS SmartTV - 33 -> AVerMedia DVD EZMaker [1461:10ff] - 34 -> Noval Prime TV 7133 - 35 -> AverMedia AverTV Studio 305 [1461:2115] - 36 -> UPMOST PURPLE TV [12ab:0800] - 37 -> Items MuchTV Plus / IT-005 - 38 -> Terratec Cinergy 200 TV [153b:1152] - 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212,5169:1502] - 40 -> Compro VideoMate TV PVR/FM [185b:c100] - 41 -> Compro VideoMate TV Gold+ [185b:c100] - 42 -> Sabrent SBT-TVFM (saa7130) - 43 -> :Zolid Xpert TV7134 - 44 -> Empire PCI TV-Radio LE - 45 -> Avermedia AVerTV Studio 307 [1461:9715] - 46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee] - 47 -> Terratec Cinergy 400 mobile [153b:1162] - 48 -> Terratec Cinergy 600 TV MK3 [153b:1158] - 49 -> Compro VideoMate Gold+ Pal [185b:c200] - 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d] - 51 -> ProVideo PV952 [1540:9524] - 52 -> AverMedia AverTV/305 [1461:2108] - 53 -> ASUS TV-FM 7135 [1043:4845] - 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,5168:5214,1489:0214,5168:0304] - 55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306] - 56 -> Avermedia AVerTV 307 [1461:a70a] - 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] - 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] - 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 - 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489:0502] - 61 -> Philips TOUGH DVB-T reference design [1131:2004] - 62 -> Compro VideoMate TV Gold+II - 63 -> Kworld Xpert TV PVR7134 - 64 -> FlyTV mini Asus Digimatrix [1043:0210] - 65 -> V-Stream Studio TV Terminator - 66 -> Yuan TUN-900 (saa7135) - 67 -> Beholder BeholdTV 409 FM [0000:4091] - 68 -> GoTView 7135 PCI [5456:7135] - 69 -> Philips EUROPA V3 reference design [1131:2004] - 70 -> Compro Videomate DVB-T300 [185b:c900] - 71 -> Compro Videomate DVB-T200 [185b:c901] - 72 -> RTD Embedded Technologies VFG7350 [1435:7350] - 73 -> RTD Embedded Technologies VFG7330 [1435:7330] - 74 -> LifeView FlyTV Platinum Mini2 [14c0:1212] - 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044] - 76 -> SKNet MonsterTV Mobile [1131:4ee9] - 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e] - 78 -> ASUSTeK P7131 Dual [1043:4862] - 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) - 80 -> ASUS Digimatrix TV [1043:0210] - 81 -> Philips Tiger reference design [1131:2018] - 82 -> MSI TV@Anywhere plus [1462:6231,1462:8624] - 83 -> Terratec Cinergy 250 PCI TV [153b:1160] - 84 -> LifeView FlyDVB Trio [5168:0319] - 85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05] - 86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301] - 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] - 88 -> Tevion/KWorld DVB-T 220RF [17de:7201] - 89 -> ELSA EX-VISION 700TV [1048:226c] - 90 -> Kworld ATSC110/115 [17de:7350,17de:7352] - 91 -> AVerMedia A169 B [1461:7360] - 92 -> AVerMedia A169 B1 [1461:6360] - 93 -> Medion 7134 Bridge #2 [16be:0005] - 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502] - 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] - 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d] - 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] - 98 -> Proteus Pro 2309 [0919:2003] - 99 -> AVerMedia TV Hybrid A16AR [1461:2c00] - 100 -> Asus Europa2 OEM [1043:4860] - 101 -> Pinnacle PCTV 310i [11bd:002f] - 102 -> Avermedia AVerTV Studio 507 [1461:9715] - 103 -> Compro Videomate DVB-T200A - 104 -> Hauppauge WinTV-HVR1110 DVB-T/Hybrid [0070:6700,0070:6701,0070:6702,0070:6703,0070:6704,0070:6705] - 105 -> Terratec Cinergy HT PCMCIA [153b:1172] - 106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344] - 107 -> Encore ENLTV-FM [1131:230f] - 108 -> Terratec Cinergy HT PCI [153b:1175] - 109 -> Philips Tiger - S Reference design - 110 -> Avermedia M102 [1461:f31e] - 111 -> ASUS P7131 4871 [1043:4871] - 112 -> ASUSTeK P7131 Hybrid [1043:4876] - 113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6] - 114 -> KWorld DVB-T 210 [17de:7250] - 115 -> Sabrent PCMCIA TV-PCB05 [0919:2003] - 116 -> 10MOONS TM300 TV Card [1131:2304] - 117 -> Avermedia Super 007 [1461:f01d] - 118 -> Beholder BeholdTV 401 [0000:4016] - 119 -> Beholder BeholdTV 403 [0000:4036] - 120 -> Beholder BeholdTV 403 FM [0000:4037] - 121 -> Beholder BeholdTV 405 [0000:4050] - 122 -> Beholder BeholdTV 405 FM [0000:4051] - 123 -> Beholder BeholdTV 407 [0000:4070] - 124 -> Beholder BeholdTV 407 FM [0000:4071] - 125 -> Beholder BeholdTV 409 [0000:4090] - 126 -> Beholder BeholdTV 505 FM [5ace:5050] - 127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090] - 128 -> Beholder BeholdTV Columbus TV/FM [0000:5201] - 129 -> Beholder BeholdTV 607 FM [5ace:6070] - 130 -> Beholder BeholdTV M6 [5ace:6190] - 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] - 132 -> Genius TVGO AM11MCE - 133 -> NXP Snake DVB-S reference design - 134 -> Medion/Creatix CTX953 Hybrid [16be:0010] - 135 -> MSI TV@nywhere A/D v1.1 [1462:8625] - 136 -> AVerMedia Cardbus TV/Radio (E506R) [1461:f436] - 137 -> AVerMedia Hybrid TV/Radio (A16D) [1461:f936] - 138 -> Avermedia M115 [1461:a836] - 139 -> Compro VideoMate T750 [185b:c900] - 140 -> Avermedia DVB-S Pro A700 [1461:a7a1] - 141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2] - 142 -> Beholder BeholdTV H6 [5ace:6290] - 143 -> Beholder BeholdTV M63 [5ace:6191] - 144 -> Beholder BeholdTV M6 Extra [5ace:6193] - 145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636,1461:f736] - 146 -> ASUSTeK P7131 Analog - 147 -> Asus Tiger 3in1 [1043:4878] - 148 -> Encore ENLTV-FM v5.3 [1a7f:2008] - 149 -> Avermedia PCI pure analog (M135A) [1461:f11d] - 150 -> Zogis Real Angel 220 - 151 -> ADS Tech Instant HDTV [1421:0380] - 152 -> Asus Tiger Rev:1.00 [1043:4857] - 153 -> Kworld Plus TV Analog Lite PCI [17de:7128] - 154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d] - 155 -> Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid [0070:6706,0070:6708] - 156 -> Hauppauge WinTV-HVR1120 DVB-T/Hybrid [0070:6707,0070:6709,0070:670a] - 157 -> Avermedia AVerTV Studio 507UA [1461:a11b] - 158 -> AVerMedia Cardbus TV/Radio (E501R) [1461:b7e9] - 159 -> Beholder BeholdTV 505 RDS [0000:505B] - 160 -> Beholder BeholdTV 507 RDS [0000:5071] - 161 -> Beholder BeholdTV 507 RDS [0000:507B] - 162 -> Beholder BeholdTV 607 FM [5ace:6071] - 163 -> Beholder BeholdTV 609 FM [5ace:6090] - 164 -> Beholder BeholdTV 609 FM [5ace:6091] - 165 -> Beholder BeholdTV 607 RDS [5ace:6072] - 166 -> Beholder BeholdTV 607 RDS [5ace:6073] - 167 -> Beholder BeholdTV 609 RDS [5ace:6092] - 168 -> Beholder BeholdTV 609 RDS [5ace:6093] - 169 -> Compro VideoMate S350/S300 [185b:c900] - 170 -> AverMedia AverTV Studio 505 [1461:a115] - 171 -> Beholder BeholdTV X7 [5ace:7595] - 172 -> RoverMedia TV Link Pro FM [19d1:0138] - 173 -> Zolid Hybrid TV Tuner PCI [1131:2004] - 174 -> Asus Europa Hybrid OEM [1043:4847] - 175 -> Leadtek Winfast DTV1000S [107d:6655] - 176 -> Beholder BeholdTV 505 RDS [0000:5051] - 177 -> Hawell HW-404M7 - 178 -> Beholder BeholdTV H7 [5ace:7190] - 179 -> Beholder BeholdTV A7 [5ace:7090] - 180 -> Avermedia PCI M733A [1461:4155,1461:4255] - 181 -> TechoTrend TT-budget T-3000 [13c2:2804] - 182 -> Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid [17de:b136] - 183 -> Compro VideoMate Vista M1F [185b:c900] - 184 -> Encore ENLTV-FM 3 [1a7f:2108] - 185 -> MagicPro ProHDTV Pro2 DMB-TH/Hybrid [17de:d136] - 186 -> Beholder BeholdTV 501 [5ace:5010] - 187 -> Beholder BeholdTV 503 FM [5ace:5030] - 188 -> Sensoray 811/911 [6000:0811,6000:0911] - 189 -> Kworld PC150-U [17de:a134] - 190 -> Asus My Cinema PS3-100 [1043:48cd] - 191 -> Hawell HW-9004V1 - 192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055] - 193 -> WIS Voyager or compatible [1905:7007] - 194 -> AverMedia AverTV/505 [1461:a10a] - 195 -> Leadtek Winfast TV2100 FM [107d:6f3a] - 196 -> SnaZio* TVPVR PRO [1779:13cf] +=========== ======================================================= ================================================================ +Card number Card name PCI IDs +=========== ======================================================= ================================================================ +0 UNKNOWN/GENERIC +1 Proteus Pro [philips reference design] 1131:2001, 1131:2001 +2 LifeView FlyVIDEO3000 5168:0138, 4e42:0138 +3 LifeView/Typhoon FlyVIDEO2000 5168:0138, 4e42:0138 +4 EMPRESS 1131:6752 +5 SKNet Monster TV 1131:4e85 +6 Tevion MD 9717 +7 KNC One TV-Station RDS / Typhoon TV Tuner RDS 1131:fe01, 1894:fe01 +8 Terratec Cinergy 400 TV 153b:1142 +9 Medion 5044 +10 Kworld/KuroutoShikou SAA7130-TVPCI +11 Terratec Cinergy 600 TV 153b:1143 +12 Medion 7134 16be:0003, 16be:5000 +13 Typhoon TV+Radio 90031 +14 ELSA EX-VISION 300TV 1048:226b +15 ELSA EX-VISION 500TV 1048:226a +16 ASUS TV-FM 7134 1043:4842, 1043:4830, 1043:4840 +17 AOPEN VA1000 POWER 1131:7133 +18 BMK MPEX No Tuner +19 Compro VideoMate TV 185b:c100 +20 Matrox CronosPlus 102B:48d0 +21 10MOONS PCI TV CAPTURE CARD 1131:2001 +22 AverMedia M156 / Medion 2819 1461:a70b +23 BMK MPEX Tuner +24 KNC One TV-Station DVR 1894:a006 +25 ASUS TV-FM 7133 1043:4843 +26 Pinnacle PCTV Stereo (saa7134) 11bd:002b +27 Manli MuchTV M-TV002 +28 Manli MuchTV M-TV001 +29 Nagase Sangyo TransGear 3000TV 1461:050c +30 Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) 1019:4cb4 +31 Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) 1019:4cb5 +32 AVACS SmartTV +33 AVerMedia DVD EZMaker 1461:10ff +34 Noval Prime TV 7133 +35 AverMedia AverTV Studio 305 1461:2115 +36 UPMOST PURPLE TV 12ab:0800 +37 Items MuchTV Plus / IT-005 +38 Terratec Cinergy 200 TV 153b:1152 +39 LifeView FlyTV Platinum Mini 5168:0212, 4e42:0212, 5169:1502 +40 Compro VideoMate TV PVR/FM 185b:c100 +41 Compro VideoMate TV Gold+ 185b:c100 +42 Sabrent SBT-TVFM (saa7130) +43 :Zolid Xpert TV7134 +44 Empire PCI TV-Radio LE +45 Avermedia AVerTV Studio 307 1461:9715 +46 AVerMedia Cardbus TV/Radio (E500) 1461:d6ee +47 Terratec Cinergy 400 mobile 153b:1162 +48 Terratec Cinergy 600 TV MK3 153b:1158 +49 Compro VideoMate Gold+ Pal 185b:c200 +50 Pinnacle PCTV 300i DVB-T + PAL 11bd:002d +51 ProVideo PV952 1540:9524 +52 AverMedia AverTV/305 1461:2108 +53 ASUS TV-FM 7135 1043:4845 +54 LifeView FlyTV Platinum FM / Gold 5168:0214, 5168:5214, 1489:0214, 5168:0304 +55 LifeView FlyDVB-T DUO / MSI TV@nywhere Duo 5168:0306, 4E42:0306 +56 Avermedia AVerTV 307 1461:a70a +57 Avermedia AVerTV GO 007 FM 1461:f31f +58 ADS Tech Instant TV (saa7135) 1421:0350, 1421:0351, 1421:0370, 1421:1370 +59 Kworld/Tevion V-Stream Xpert TV PVR7134 +60 LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus 5168:0502, 4e42:0502, 1489:0502 +61 Philips TOUGH DVB-T reference design 1131:2004 +62 Compro VideoMate TV Gold+II +63 Kworld Xpert TV PVR7134 +64 FlyTV mini Asus Digimatrix 1043:0210 +65 V-Stream Studio TV Terminator +66 Yuan TUN-900 (saa7135) +67 Beholder BeholdTV 409 FM 0000:4091 +68 GoTView 7135 PCI 5456:7135 +69 Philips EUROPA V3 reference design 1131:2004 +70 Compro Videomate DVB-T300 185b:c900 +71 Compro Videomate DVB-T200 185b:c901 +72 RTD Embedded Technologies VFG7350 1435:7350 +73 RTD Embedded Technologies VFG7330 1435:7330 +74 LifeView FlyTV Platinum Mini2 14c0:1212 +75 AVerMedia AVerTVHD MCE A180 1461:1044 +76 SKNet MonsterTV Mobile 1131:4ee9 +77 Pinnacle PCTV 40i/50i/110i (saa7133) 11bd:002e +78 ASUSTeK P7131 Dual 1043:4862 +79 Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) +80 ASUS Digimatrix TV 1043:0210 +81 Philips Tiger reference design 1131:2018 +82 MSI TV@Anywhere plus 1462:6231, 1462:8624 +83 Terratec Cinergy 250 PCI TV 153b:1160 +84 LifeView FlyDVB Trio 5168:0319 +85 AverTV DVB-T 777 1461:2c05, 1461:2c05 +86 LifeView FlyDVB-T / Genius VideoWonder DVB-T 5168:0301, 1489:0301 +87 ADS Instant TV Duo Cardbus PTV331 0331:1421 +88 Tevion/KWorld DVB-T 220RF 17de:7201 +89 ELSA EX-VISION 700TV 1048:226c +90 Kworld ATSC110/115 17de:7350, 17de:7352 +91 AVerMedia A169 B 1461:7360 +92 AVerMedia A169 B1 1461:6360 +93 Medion 7134 Bridge #2 16be:0005 +94 LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB 5168:3306, 5168:3502, 5168:3307, 4e42:3502 +95 LifeView FlyVIDEO3000 (NTSC) 5169:0138 +96 Medion Md8800 Quadro 16be:0007, 16be:0008, 16be:000d +97 LifeView FlyDVB-S /Acorp TV134DS 5168:0300, 4e42:0300 +98 Proteus Pro 2309 0919:2003 +99 AVerMedia TV Hybrid A16AR 1461:2c00 +100 Asus Europa2 OEM 1043:4860 +101 Pinnacle PCTV 310i 11bd:002f +102 Avermedia AVerTV Studio 507 1461:9715 +103 Compro Videomate DVB-T200A +104 Hauppauge WinTV-HVR1110 DVB-T/Hybrid 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705 +105 Terratec Cinergy HT PCMCIA 153b:1172 +106 Encore ENLTV 1131:2342, 1131:2341, 3016:2344 +107 Encore ENLTV-FM 1131:230f +108 Terratec Cinergy HT PCI 153b:1175 +109 Philips Tiger - S Reference design +110 Avermedia M102 1461:f31e +111 ASUS P7131 4871 1043:4871 +112 ASUSTeK P7131 Hybrid 1043:4876 +113 Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) 1019:4cb6 +114 KWorld DVB-T 210 17de:7250 +115 Sabrent PCMCIA TV-PCB05 0919:2003 +116 10MOONS TM300 TV Card 1131:2304 +117 Avermedia Super 007 1461:f01d +118 Beholder BeholdTV 401 0000:4016 +119 Beholder BeholdTV 403 0000:4036 +120 Beholder BeholdTV 403 FM 0000:4037 +121 Beholder BeholdTV 405 0000:4050 +122 Beholder BeholdTV 405 FM 0000:4051 +123 Beholder BeholdTV 407 0000:4070 +124 Beholder BeholdTV 407 FM 0000:4071 +125 Beholder BeholdTV 409 0000:4090 +126 Beholder BeholdTV 505 FM 5ace:5050 +127 Beholder BeholdTV 507 FM / BeholdTV 509 FM 5ace:5070, 5ace:5090 +128 Beholder BeholdTV Columbus TV/FM 0000:5201 +129 Beholder BeholdTV 607 FM 5ace:6070 +130 Beholder BeholdTV M6 5ace:6190 +131 Twinhan Hybrid DTV-DVB 3056 PCI 1822:0022 +132 Genius TVGO AM11MCE +133 NXP Snake DVB-S reference design +134 Medion/Creatix CTX953 Hybrid 16be:0010 +135 MSI TV@nywhere A/D v1.1 1462:8625 +136 AVerMedia Cardbus TV/Radio (E506R) 1461:f436 +137 AVerMedia Hybrid TV/Radio (A16D) 1461:f936 +138 Avermedia M115 1461:a836 +139 Compro VideoMate T750 185b:c900 +140 Avermedia DVB-S Pro A700 1461:a7a1 +141 Avermedia DVB-S Hybrid+FM A700 1461:a7a2 +142 Beholder BeholdTV H6 5ace:6290 +143 Beholder BeholdTV M63 5ace:6191 +144 Beholder BeholdTV M6 Extra 5ace:6193 +145 AVerMedia MiniPCI DVB-T Hybrid M103 1461:f636, 1461:f736 +146 ASUSTeK P7131 Analog +147 Asus Tiger 3in1 1043:4878 +148 Encore ENLTV-FM v5.3 1a7f:2008 +149 Avermedia PCI pure analog (M135A) 1461:f11d +150 Zogis Real Angel 220 +151 ADS Tech Instant HDTV 1421:0380 +152 Asus Tiger Rev:1.00 1043:4857 +153 Kworld Plus TV Analog Lite PCI 17de:7128 +154 Avermedia AVerTV GO 007 FM Plus 1461:f31d +155 Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid 0070:6706, 0070:6708 +156 Hauppauge WinTV-HVR1120 DVB-T/Hybrid 0070:6707, 0070:6709, 0070:670a +157 Avermedia AVerTV Studio 507UA 1461:a11b +158 AVerMedia Cardbus TV/Radio (E501R) 1461:b7e9 +159 Beholder BeholdTV 505 RDS 0000:505B +160 Beholder BeholdTV 507 RDS 0000:5071 +161 Beholder BeholdTV 507 RDS 0000:507B +162 Beholder BeholdTV 607 FM 5ace:6071 +163 Beholder BeholdTV 609 FM 5ace:6090 +164 Beholder BeholdTV 609 FM 5ace:6091 +165 Beholder BeholdTV 607 RDS 5ace:6072 +166 Beholder BeholdTV 607 RDS 5ace:6073 +167 Beholder BeholdTV 609 RDS 5ace:6092 +168 Beholder BeholdTV 609 RDS 5ace:6093 +169 Compro VideoMate S350/S300 185b:c900 +170 AverMedia AverTV Studio 505 1461:a115 +171 Beholder BeholdTV X7 5ace:7595 +172 RoverMedia TV Link Pro FM 19d1:0138 +173 Zolid Hybrid TV Tuner PCI 1131:2004 +174 Asus Europa Hybrid OEM 1043:4847 +175 Leadtek Winfast DTV1000S 107d:6655 +176 Beholder BeholdTV 505 RDS 0000:5051 +177 Hawell HW-404M7 +178 Beholder BeholdTV H7 5ace:7190 +179 Beholder BeholdTV A7 5ace:7090 +180 Avermedia PCI M733A 1461:4155, 1461:4255 +181 TechoTrend TT-budget T-3000 13c2:2804 +182 Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid 17de:b136 +183 Compro VideoMate Vista M1F 185b:c900 +184 Encore ENLTV-FM 3 1a7f:2108 +185 MagicPro ProHDTV Pro2 DMB-TH/Hybrid 17de:d136 +186 Beholder BeholdTV 501 5ace:5010 +187 Beholder BeholdTV 503 FM 5ace:5030 +188 Sensoray 811/911 6000:0811, 6000:0911 +189 Kworld PC150-U 17de:a134 +190 Asus My Cinema PS3-100 1043:48cd +191 Hawell HW-9004V1 +192 AverMedia AverTV Satellite Hybrid+FM A706 1461:2055 +193 WIS Voyager or compatible 1905:7007 +194 AverMedia AverTV/505 1461:a10a +195 Leadtek Winfast TV2100 FM 107d:6f3a +196 SnaZio* TVPVR PRO 1779:13cf +=========== ======================================================= ================================================================ diff --git a/Documentation/media/v4l-drivers/saa7164-cardlist.rst b/Documentation/media/v4l-drivers/saa7164-cardlist.rst index b937836cd54c..7d17d38df3bc 100644 --- a/Documentation/media/v4l-drivers/saa7164-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7164-cardlist.rst @@ -1,19 +1,21 @@ -SAA7134 cards list +SAA7164 cards list ================== -.. code-block:: none - - 0 -> Unknown - 1 -> Generic Rev2 - 2 -> Generic Rev3 - 3 -> Hauppauge WinTV-HVR2250 [0070:8880,0070:8810] - 4 -> Hauppauge WinTV-HVR2200 [0070:8980] - 5 -> Hauppauge WinTV-HVR2200 [0070:8900] - 6 -> Hauppauge WinTV-HVR2200 [0070:8901] - 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851] - 8 -> Hauppauge WinTV-HVR2250 [0070:88A1] - 9 -> Hauppauge WinTV-HVR2200 [0070:8940] - 10 -> Hauppauge WinTV-HVR2200 [0070:8953] - 11 -> Hauppauge WinTV-HVR2255(proto) - 12 -> Hauppauge WinTV-HVR2255 [0070:f111] - 13 -> Hauppauge WinTV-HVR2205 [0070:f123,0070:f120] +=========== ==================================== ==================== +Card number Card name PCI IDs +=========== ==================================== ==================== +0 Unknown +1 Generic Rev2 +2 Generic Rev3 +3 Hauppauge WinTV-HVR2250 0070:8880, 0070:8810 +4 Hauppauge WinTV-HVR2200 0070:8980 +5 Hauppauge WinTV-HVR2200 0070:8900 +6 Hauppauge WinTV-HVR2200 0070:8901 +7 Hauppauge WinTV-HVR2250 0070:8891, 0070:8851 +8 Hauppauge WinTV-HVR2250 0070:88A1 +9 Hauppauge WinTV-HVR2200 0070:8940 +10 Hauppauge WinTV-HVR2200 0070:8953 +11 Hauppauge WinTV-HVR2255(proto) 0070:f111 +12 Hauppauge WinTV-HVR2255 0070:f111 +13 Hauppauge WinTV-HVR2205 0070:f123, 0070:f120 +=========== ==================================== ==================== diff --git a/Documentation/media/v4l-drivers/tm6000-cardlist.rst b/Documentation/media/v4l-drivers/tm6000-cardlist.rst index 2fbd3886b5f0..ae2952683ccf 100644 --- a/Documentation/media/v4l-drivers/tm6000-cardlist.rst +++ b/Documentation/media/v4l-drivers/tm6000-cardlist.rst @@ -1,21 +1,24 @@ TM6000 cards list ================= -.. code-block:: none - - 1 -> Generic tm5600 board (tm5600) [6000:0001] - 2 -> Generic tm6000 board (tm6000) [6000:0001] - 3 -> Generic tm6010 board (tm6010) [6000:0002] - 4 -> 10Moons UT821 (tm5600) [6000:0001] - 5 -> 10Moons UT330 (tm5600) - 6 -> ADSTech Dual TV (tm6000) [06e1:f332] - 7 -> FreeCom and similar (tm6000) [14aa:0620] - 8 -> ADSTech Mini Dual TV (tm6000) [06e1:b339] - 9 -> Hauppauge WinTV HVR-900H/USB2 Stick (tm6010) [2040:6600,2040:6601,2040:6610,2040:6611] - 10 -> Beholder Wander (tm6010) [6000:dec0] - 11 -> Beholder Voyager (tm6010) [6000:dec1] - 12 -> TerraTec Cinergy Hybrid XE/Cinergy Hybrid Stick (tm6010) [0ccd:0086,0ccd:00a5] - 13 -> TwinHan TU501 (tm6010) [13d3:3240,13d3:3241,13d3:3243,13d3:3264] - 14 -> Beholder Wander Lite (tm6010) [6000:dec2] - 15 -> Beholder Voyager Lite (tm6010) [6000:dec3] - +=========== ================================================= ========================================== +Card number Card name USB IDs +=========== ================================================= ========================================== +0 Unknown tm6000 video grabber +1 Generic tm5600 board 6000:0001 +2 Generic tm6000 board +3 Generic tm6010 board 6000:0002 +4 10Moons UT 821 +5 10Moons UT 330 +6 ADSTECH Dual TV USB 06e1:f332 +7 Freecom Hybrid Stick / Moka DVB-T Receiver Dual 14aa:0620 +8 ADSTECH Mini Dual TV USB 06e1:b339 +9 Hauppauge WinTV HVR-900H / WinTV USB2-Stick 2040:6600, 2040:6601, 2040:6610, 2040:6611 +10 Beholder Wander DVB-T/TV/FM USB2.0 6000:dec0 +11 Beholder Voyager TV/FM USB2.0 6000:dec1 +12 Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick 0ccd:0086, 0ccd:00A5 +13 Twinhan TU501(704D1) 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264 +14 Beholder Wander Lite DVB-T/TV/FM USB2.0 6000:dec2 +15 Beholder Voyager Lite TV/FM USB2.0 6000:dec3 +16 Terratec Grabster AV 150/250 MX 0ccd:0079 +=========== ================================================= ========================================== diff --git a/Documentation/media/v4l-drivers/tuner-cardlist.rst b/Documentation/media/v4l-drivers/tuner-cardlist.rst index 2f1e1029c04e..276dd90e0c59 100644 --- a/Documentation/media/v4l-drivers/tuner-cardlist.rst +++ b/Documentation/media/v4l-drivers/tuner-cardlist.rst @@ -1,96 +1,98 @@ Tuner cards list ================ -.. code-block:: none - - tuner=0 - Temic PAL (4002 FH5) - tuner=1 - Philips PAL_I (FI1246 and compatibles) - tuner=2 - Philips NTSC (FI1236,FM1236 and compatibles) - tuner=3 - Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF) - tuner=4 - NoTuner - tuner=5 - Philips PAL_BG (FI1216 and compatibles) - tuner=6 - Temic NTSC (4032 FY5) - tuner=7 - Temic PAL_I (4062 FY5) - tuner=8 - Temic NTSC (4036 FY5) - tuner=9 - Alps HSBH1 - tuner=10 - Alps TSBE1 - tuner=11 - Alps TSBB5 - tuner=12 - Alps TSBE5 - tuner=13 - Alps TSBC5 - tuner=14 - Temic PAL_BG (4006FH5) - tuner=15 - Alps TSCH6 - tuner=16 - Temic PAL_DK (4016 FY5) - tuner=17 - Philips NTSC_M (MK2) - tuner=18 - Temic PAL_I (4066 FY5) - tuner=19 - Temic PAL* auto (4006 FN5) - tuner=20 - Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5) - tuner=21 - Temic NTSC (4039 FR5) - tuner=22 - Temic PAL/SECAM multi (4046 FM5) - tuner=23 - Philips PAL_DK (FI1256 and compatibles) - tuner=24 - Philips PAL/SECAM multi (FQ1216ME) - tuner=25 - LG PAL_I+FM (TAPC-I001D) - tuner=26 - LG PAL_I (TAPC-I701D) - tuner=27 - LG NTSC+FM (TPI8NSR01F) - tuner=28 - LG PAL_BG+FM (TPI8PSB01D) - tuner=29 - LG PAL_BG (TPI8PSB11D) - tuner=30 - Temic PAL* auto + FM (4009 FN5) - tuner=31 - SHARP NTSC_JP (2U5JF5540) - tuner=32 - Samsung PAL TCPM9091PD27 - tuner=33 - MT20xx universal - tuner=34 - Temic PAL_BG (4106 FH5) - tuner=35 - Temic PAL_DK/SECAM_L (4012 FY5) - tuner=36 - Temic NTSC (4136 FY5) - tuner=37 - LG PAL (newer TAPC series) - tuner=38 - Philips PAL/SECAM multi (FM1216ME MK3) - tuner=39 - LG NTSC (newer TAPC series) - tuner=40 - HITACHI V7-J180AT - tuner=41 - Philips PAL_MK (FI1216 MK) - tuner=42 - Philips FCV1236D ATSC/NTSC dual in - tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F) - tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant) - tuner=45 - Microtune 4049 FM5 - tuner=46 - Panasonic VP27s/ENGE4324D - tuner=47 - LG NTSC (TAPE series) - tuner=48 - Tenna TNF 8831 BGFF) - tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in - tuner=50 - TCL 2002N - tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3) - tuner=52 - Thomson DTT 7610 (ATSC/NTSC) - tuner=53 - Philips FQ1286 - tuner=54 - Philips/NXP TDA 8290/8295 + 8275/8275A/18271 - tuner=55 - TCL 2002MB - tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) - tuner=57 - Philips FQ1236A MK4 - tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF - tuner=59 - Ymec TVision TVF-5533MF - tuner=60 - Thomson DTT 761X (ATSC/NTSC) - tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF - tuner=62 - Philips TEA5767HN FM Radio - tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner - tuner=64 - LG TDVS-H06xF - tuner=65 - Ymec TVF66T5-B/DFF - tuner=66 - LG TALN series - tuner=67 - Philips TD1316 Hybrid Tuner - tuner=68 - Philips TUV1236D ATSC/NTSC dual in - tuner=69 - Tena TNF 5335 and similar models - tuner=70 - Samsung TCPN 2121P30A - tuner=71 - Xceive xc2028/xc3028 tuner - tuner=72 - Thomson FE6600 - tuner=73 - Samsung TCPG 6121P30A - tuner=75 - Philips TEA5761 FM Radio - tuner=76 - Xceive 5000 tuner - tuner=77 - TCL tuner MF02GIP-5N-E - tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner - tuner=79 - Philips PAL/SECAM multi (FM1216 MK5) - tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough - tuner=81 - Partsnic (Daewoo) PTI-5NF05 - tuner=82 - Philips CU1216L - tuner=83 - NXP TDA18271 - tuner=84 - Sony BTF-Pxn01Z - tuner=85 - Philips FQ1236 MK5 - tuner=86 - Tena TNF5337 MFD - tuner=87 - Xceive 4000 tuner - tuner=88 - Xceive 5000C tuner - tuner=89 - Sony BTF-PG472Z PAL/SECAM - tuner=90 - Sony BTF-PK467Z NTSC-M-JP - tuner=91 - Sony BTF-PB463Z NTSC-M +============ ===================================================== +Tuner number Card name +============ ===================================================== +0 Temic PAL (4002 FH5) +1 Philips PAL_I (FI1246 and compatibles) +2 Philips NTSC (FI1236,FM1236 and compatibles) +3 Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF) +4 NoTuner +5 Philips PAL_BG (FI1216 and compatibles) +6 Temic NTSC (4032 FY5) +7 Temic PAL_I (4062 FY5) +8 Temic NTSC (4036 FY5) +9 Alps HSBH1 +10 Alps TSBE1 +11 Alps TSBB5 +12 Alps TSBE5 +13 Alps TSBC5 +14 Temic PAL_BG (4006FH5) +15 Alps TSCH6 +16 Temic PAL_DK (4016 FY5) +17 Philips NTSC_M (MK2) +18 Temic PAL_I (4066 FY5) +19 Temic PAL* auto (4006 FN5) +20 Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5) +21 Temic NTSC (4039 FR5) +22 Temic PAL/SECAM multi (4046 FM5) +23 Philips PAL_DK (FI1256 and compatibles) +24 Philips PAL/SECAM multi (FQ1216ME) +25 LG PAL_I+FM (TAPC-I001D) +26 LG PAL_I (TAPC-I701D) +27 LG NTSC+FM (TPI8NSR01F) +28 LG PAL_BG+FM (TPI8PSB01D) +29 LG PAL_BG (TPI8PSB11D) +30 Temic PAL* auto + FM (4009 FN5) +31 SHARP NTSC_JP (2U5JF5540) +32 Samsung PAL TCPM9091PD27 +33 MT20xx universal +34 Temic PAL_BG (4106 FH5) +35 Temic PAL_DK/SECAM_L (4012 FY5) +36 Temic NTSC (4136 FY5) +37 LG PAL (newer TAPC series) +38 Philips PAL/SECAM multi (FM1216ME MK3) +39 LG NTSC (newer TAPC series) +40 HITACHI V7-J180AT +41 Philips PAL_MK (FI1216 MK) +42 Philips FCV1236D ATSC/NTSC dual in +43 Philips NTSC MK3 (FM1236MK3 or FM1236/F) +44 Philips 4 in 1 (ATI TV Wonder Pro/Conexant) +45 Microtune 4049 FM5 +46 Panasonic VP27s/ENGE4324D +47 LG NTSC (TAPE series) +48 Tenna TNF 8831 BGFF) +49 Microtune 4042 FI5 ATSC/NTSC dual in +50 TCL 2002N +51 Philips PAL/SECAM_D (FM 1256 I-H3) +52 Thomson DTT 7610 (ATSC/NTSC) +53 Philips FQ1286 +54 Philips/NXP TDA 8290/8295 + 8275/8275A/18271 +55 TCL 2002MB +56 Philips PAL/SECAM multi (FQ1216AME MK4) +57 Philips FQ1236A MK4 +58 Ymec TVision TVF-8531MF/8831MF/8731MF +59 Ymec TVision TVF-5533MF +60 Thomson DTT 761X (ATSC/NTSC) +61 Tena TNF9533-D/IF/TNF9533-B/DF +62 Philips TEA5767HN FM Radio +63 Philips FMD1216ME MK3 Hybrid Tuner +64 LG TDVS-H06xF +65 Ymec TVF66T5-B/DFF +66 LG TALN series +67 Philips TD1316 Hybrid Tuner +68 Philips TUV1236D ATSC/NTSC dual in +69 Tena TNF 5335 and similar models +70 Samsung TCPN 2121P30A +71 Xceive xc2028/xc3028 tuner +72 Thomson FE6600 +73 Samsung TCPG 6121P30A +75 Philips TEA5761 FM Radio +76 Xceive 5000 tuner +77 TCL tuner MF02GIP-5N-E +78 Philips FMD1216MEX MK3 Hybrid Tuner +79 Philips PAL/SECAM multi (FM1216 MK5) +80 Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough +81 Partsnic (Daewoo) PTI-5NF05 +82 Philips CU1216L +83 NXP TDA18271 +84 Sony BTF-Pxn01Z +85 Philips FQ1236 MK5 +86 Tena TNF5337 MFD +87 Xceive 4000 tuner +88 Xceive 5000C tuner +89 Sony BTF-PG472Z PAL/SECAM +90 Sony BTF-PK467Z NTSC-M-JP +91 Sony BTF-PB463Z NTSC-M +============ ===================================================== diff --git a/Documentation/media/v4l-drivers/usbvision-cardlist.rst b/Documentation/media/v4l-drivers/usbvision-cardlist.rst index 3d8be9cb1b5a..44d53dff0984 100644 --- a/Documentation/media/v4l-drivers/usbvision-cardlist.rst +++ b/Documentation/media/v4l-drivers/usbvision-cardlist.rst @@ -1,72 +1,74 @@ -Usbvision cards list +USBvision cards list ==================== -.. code-block:: none - - 0 -> Xanboo [0a6f:0400] - 1 -> Belkin USB VideoBus II Adapter [050d:0106] - 2 -> Belkin Components USB VideoBus [050d:0207] - 3 -> Belkin USB VideoBus II [050d:0208] - 4 -> echoFX InterView Lite [0571:0002] - 5 -> USBGear USBG-V1 resp. HAMA USB [0573:0003] - 6 -> D-Link V100 [0573:0400] - 7 -> X10 USB Camera [0573:2000] - 8 -> Hauppauge WinTV USB Live (PAL B/G) [0573:2d00] - 9 -> Hauppauge WinTV USB Live Pro (NTSC M/N) [0573:2d01] - 10 -> Zoran Co. PMD (Nogatech) AV-grabber Manhattan [0573:2101] - 11 -> Nogatech USB-TV (NTSC) FM [0573:4100] - 12 -> PNY USB-TV (NTSC) FM [0573:4110] - 13 -> PixelView PlayTv-USB PRO (PAL) FM [0573:4450] - 14 -> ZTV ZT-721 2.4GHz USB A/V Receiver [0573:4550] - 15 -> Hauppauge WinTV USB (NTSC M/N) [0573:4d00] - 16 -> Hauppauge WinTV USB (PAL B/G) [0573:4d01] - 17 -> Hauppauge WinTV USB (PAL I) [0573:4d02] - 18 -> Hauppauge WinTV USB (PAL/SECAM L) [0573:4d03] - 19 -> Hauppauge WinTV USB (PAL D/K) [0573:4d04] - 20 -> Hauppauge WinTV USB (NTSC FM) [0573:4d10] - 21 -> Hauppauge WinTV USB (PAL B/G FM) [0573:4d11] - 22 -> Hauppauge WinTV USB (PAL I FM) [0573:4d12] - 23 -> Hauppauge WinTV USB (PAL D/K FM) [0573:4d14] - 24 -> Hauppauge WinTV USB Pro (NTSC M/N) [0573:4d2a] - 25 -> Hauppauge WinTV USB Pro (NTSC M/N) V2 [0573:4d2b] - 26 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) [0573:4d2c] - 27 -> Hauppauge WinTV USB Pro (NTSC M/N) V3 [0573:4d20] - 28 -> Hauppauge WinTV USB Pro (PAL B/G) [0573:4d21] - 29 -> Hauppauge WinTV USB Pro (PAL I) [0573:4d22] - 30 -> Hauppauge WinTV USB Pro (PAL/SECAM L) [0573:4d23] - 31 -> Hauppauge WinTV USB Pro (PAL D/K) [0573:4d24] - 32 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) [0573:4d25] - 33 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 [0573:4d26] - 34 -> Hauppauge WinTV USB Pro (PAL B/G) V2 [0573:4d27] - 35 -> Hauppauge WinTV USB Pro (PAL B/G,D/K) [0573:4d28] - 36 -> Hauppauge WinTV USB Pro (PAL I,D/K) [0573:4d29] - 37 -> Hauppauge WinTV USB Pro (NTSC M/N FM) [0573:4d30] - 38 -> Hauppauge WinTV USB Pro (PAL B/G FM) [0573:4d31] - 39 -> Hauppauge WinTV USB Pro (PAL I FM) [0573:4d32] - 40 -> Hauppauge WinTV USB Pro (PAL D/K FM) [0573:4d34] - 41 -> Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) [0573:4d35] - 42 -> Hauppauge WinTV USB Pro (Temic PAL B/G FM) [0573:4d36] - 43 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) [0573:4d37] - 44 -> Hauppauge WinTV USB Pro (NTSC M/N FM) V2 [0573:4d38] - 45 -> Camtel Technology USB TV Genie Pro FM Model TVB330 [0768:0006] - 46 -> Digital Video Creator I [07d0:0001] - 47 -> Global Village GV-007 (NTSC) [07d0:0002] - 48 -> Dazzle Fusion Model DVC-50 Rev 1 (NTSC) [07d0:0003] - 49 -> Dazzle Fusion Model DVC-80 Rev 1 (PAL) [07d0:0004] - 50 -> Dazzle Fusion Model DVC-90 Rev 1 (SECAM) [07d0:0005] - 51 -> Eskape Labs MyTV2Go [07f8:9104] - 52 -> Pinnacle Studio PCTV USB (PAL) [2304:010d] - 53 -> Pinnacle Studio PCTV USB (SECAM) [2304:0109] - 54 -> Pinnacle Studio PCTV USB (PAL) FM [2304:0110] - 55 -> Miro PCTV USB [2304:0111] - 56 -> Pinnacle Studio PCTV USB (NTSC) FM [2304:0112] - 57 -> Pinnacle Studio PCTV USB (PAL) FM V2 [2304:0210] - 58 -> Pinnacle Studio PCTV USB (NTSC) FM V2 [2304:0212] - 59 -> Pinnacle Studio PCTV USB (PAL) FM V3 [2304:0214] - 60 -> Pinnacle Studio Linx Video input cable (NTSC) [2304:0300] - 61 -> Pinnacle Studio Linx Video input cable (PAL) [2304:0301] - 62 -> Pinnacle PCTV Bungee USB (PAL) FM [2304:0419] - 63 -> Hauppauge WinTv-USB [2400:4200] - 64 -> Pinnacle Studio PCTV USB (NTSC) FM V3 [2304:0113] - 65 -> Nogatech USB MicroCam NTSC (NV3000N) [0573:3000] - 66 -> Nogatech USB MicroCam PAL (NV3001P) [0573:3001] +=========== ======================================================== ========= +Card number Card name USB IDs +=========== ======================================================== ========= +0 Xanboo 0a6f:0400 +1 Belkin USB VideoBus II Adapter 050d:0106 +2 Belkin Components USB VideoBus 050d:0207 +3 Belkin USB VideoBus II 050d:0208 +4 echoFX InterView Lite 0571:0002 +5 USBGear USBG-V1 resp. HAMA USB 0573:0003 +6 D-Link V100 0573:0400 +7 X10 USB Camera 0573:2000 +8 Hauppauge WinTV USB Live (PAL B/G) 0573:2d00 +9 Hauppauge WinTV USB Live Pro (NTSC M/N) 0573:2d01 +10 Zoran Co. PMD (Nogatech) AV-grabber Manhattan 0573:2101 +11 Nogatech USB-TV (NTSC) FM 0573:4100 +12 PNY USB-TV (NTSC) FM 0573:4110 +13 PixelView PlayTv-USB PRO (PAL) FM 0573:4450 +14 ZTV ZT-721 2.4GHz USB A/V Receiver 0573:4550 +15 Hauppauge WinTV USB (NTSC M/N) 0573:4d00 +16 Hauppauge WinTV USB (PAL B/G) 0573:4d01 +17 Hauppauge WinTV USB (PAL I) 0573:4d02 +18 Hauppauge WinTV USB (PAL/SECAM L) 0573:4d03 +19 Hauppauge WinTV USB (PAL D/K) 0573:4d04 +20 Hauppauge WinTV USB (NTSC FM) 0573:4d10 +21 Hauppauge WinTV USB (PAL B/G FM) 0573:4d11 +22 Hauppauge WinTV USB (PAL I FM) 0573:4d12 +23 Hauppauge WinTV USB (PAL D/K FM) 0573:4d14 +24 Hauppauge WinTV USB Pro (NTSC M/N) 0573:4d2a +25 Hauppauge WinTV USB Pro (NTSC M/N) V2 0573:4d2b +26 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) 0573:4d2c +27 Hauppauge WinTV USB Pro (NTSC M/N) V3 0573:4d20 +28 Hauppauge WinTV USB Pro (PAL B/G) 0573:4d21 +29 Hauppauge WinTV USB Pro (PAL I) 0573:4d22 +30 Hauppauge WinTV USB Pro (PAL/SECAM L) 0573:4d23 +31 Hauppauge WinTV USB Pro (PAL D/K) 0573:4d24 +32 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) 0573:4d25 +33 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 0573:4d26 +34 Hauppauge WinTV USB Pro (PAL B/G) V2 0573:4d27 +35 Hauppauge WinTV USB Pro (PAL B/G,D/K) 0573:4d28 +36 Hauppauge WinTV USB Pro (PAL I,D/K) 0573:4d29 +37 Hauppauge WinTV USB Pro (NTSC M/N FM) 0573:4d30 +38 Hauppauge WinTV USB Pro (PAL B/G FM) 0573:4d31 +39 Hauppauge WinTV USB Pro (PAL I FM) 0573:4d32 +40 Hauppauge WinTV USB Pro (PAL D/K FM) 0573:4d34 +41 Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) 0573:4d35 +42 Hauppauge WinTV USB Pro (Temic PAL B/G FM) 0573:4d36 +43 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) 0573:4d37 +44 Hauppauge WinTV USB Pro (NTSC M/N FM) V2 0573:4d38 +45 Camtel Technology USB TV Genie Pro FM Model TVB330 0768:0006 +46 Digital Video Creator I 07d0:0001 +47 Global Village GV-007 (NTSC) 07d0:0002 +48 Dazzle Fusion Model DVC-50 Rev 1 (NTSC) 07d0:0003 +49 Dazzle Fusion Model DVC-80 Rev 1 (PAL) 07d0:0004 +50 Dazzle Fusion Model DVC-90 Rev 1 (SECAM) 07d0:0005 +51 Eskape Labs MyTV2Go 07f8:9104 +52 Pinnacle Studio PCTV USB (PAL) 2304:010d +53 Pinnacle Studio PCTV USB (SECAM) 2304:0109 +54 Pinnacle Studio PCTV USB (PAL) FM 2304:0110 +55 Miro PCTV USB 2304:0111 +56 Pinnacle Studio PCTV USB (NTSC) FM 2304:0112 +57 Pinnacle Studio PCTV USB (PAL) FM V2 2304:0210 +58 Pinnacle Studio PCTV USB (NTSC) FM V2 2304:0212 +59 Pinnacle Studio PCTV USB (PAL) FM V3 2304:0214 +60 Pinnacle Studio Linx Video input cable (NTSC) 2304:0300 +61 Pinnacle Studio Linx Video input cable (PAL) 2304:0301 +62 Pinnacle PCTV Bungee USB (PAL) FM 2304:0419 +63 Hauppauge WinTv-USB 2400:4200 +64 Pinnacle Studio PCTV USB (NTSC) FM V3 2304:0113 +65 Nogatech USB MicroCam NTSC (NV3000N) 0573:3000 +66 Nogatech USB MicroCam PAL (NV3001P) 0573:3001 +=========== ======================================================== ========= -- cgit v1.2.3 From e950267ab802c8558f1100eafd4087fd039ad634 Mon Sep 17 00:00:00 2001 From: Henrik Ingo Date: Sun, 29 May 2016 17:58:00 -0300 Subject: [media] uvcvideo: uvc_scan_fallback() for webcams with broken chain Some devices have invalid baSourceID references, causing uvc_scan_chain() to fail, but if we just take the entities we can find and put them together in the most sensible chain we can think of, turns out they do work anyway. Note: This heuristic assumes there is a single chain. At the time of writing, devices known to have such a broken chain are - Acer Integrated Camera (5986:055a) - Realtek rtl157a7 (0bda:57a7) Signed-off-by: Henrik Ingo Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 118 +++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 9c4b56b4a9c6..87b2fc3b0ac2 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain) return buffer; } +static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) +{ + struct uvc_video_chain *chain; + + chain = kzalloc(sizeof(*chain), GFP_KERNEL); + if (chain == NULL) + return NULL; + + INIT_LIST_HEAD(&chain->entities); + mutex_init(&chain->ctrl_mutex); + chain->dev = dev; + v4l2_prio_init(&chain->prio); + + return chain; +} + +/* + * Fallback heuristic for devices that don't connect units and terminals in a + * valid chain. + * + * Some devices have invalid baSourceID references, causing uvc_scan_chain() + * to fail, but if we just take the entities we can find and put them together + * in the most sensible chain we can think of, turns out they do work anyway. + * Note: This heuristic assumes there is a single chain. + * + * At the time of writing, devices known to have such a broken chain are + * - Acer Integrated Camera (5986:055a) + * - Realtek rtl157a7 (0bda:57a7) + */ +static int uvc_scan_fallback(struct uvc_device *dev) +{ + struct uvc_video_chain *chain; + struct uvc_entity *iterm = NULL; + struct uvc_entity *oterm = NULL; + struct uvc_entity *entity; + struct uvc_entity *prev; + + /* + * Start by locating the input and output terminals. We only support + * devices with exactly one of each for now. + */ + list_for_each_entry(entity, &dev->entities, list) { + if (UVC_ENTITY_IS_ITERM(entity)) { + if (iterm) + return -EINVAL; + iterm = entity; + } + + if (UVC_ENTITY_IS_OTERM(entity)) { + if (oterm) + return -EINVAL; + oterm = entity; + } + } + + if (iterm == NULL || oterm == NULL) + return -EINVAL; + + /* Allocate the chain and fill it. */ + chain = uvc_alloc_chain(dev); + if (chain == NULL) + return -ENOMEM; + + if (uvc_scan_chain_entity(chain, oterm) < 0) + goto error; + + prev = oterm; + + /* + * Add all Processing and Extension Units with two pads. The order + * doesn't matter much, use reverse list traversal to connect units in + * UVC descriptor order as we build the chain from output to input. This + * leads to units appearing in the order meant by the manufacturer for + * the cameras known to require this heuristic. + */ + list_for_each_entry_reverse(entity, &dev->entities, list) { + if (entity->type != UVC_VC_PROCESSING_UNIT && + entity->type != UVC_VC_EXTENSION_UNIT) + continue; + + if (entity->num_pads != 2) + continue; + + if (uvc_scan_chain_entity(chain, entity) < 0) + goto error; + + prev->baSourceID[0] = entity->id; + prev = entity; + } + + if (uvc_scan_chain_entity(chain, iterm) < 0) + goto error; + + prev->baSourceID[0] = iterm->id; + + list_add_tail(&chain->list, &dev->chains); + + uvc_trace(UVC_TRACE_PROBE, + "Found a video chain by fallback heuristic (%s).\n", + uvc_print_chain(chain)); + + return 0; + +error: + kfree(chain); + return -EINVAL; +} + /* * Scan the device for video chains and register video devices. * @@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev) if (term->chain.next || term->chain.prev) continue; - chain = kzalloc(sizeof(*chain), GFP_KERNEL); + chain = uvc_alloc_chain(dev); if (chain == NULL) return -ENOMEM; - INIT_LIST_HEAD(&chain->entities); - mutex_init(&chain->ctrl_mutex); - chain->dev = dev; - v4l2_prio_init(&chain->prio); - term->flags |= UVC_ENTITY_FLAG_DEFAULT; if (uvc_scan_chain(chain, term) < 0) { @@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev) list_add_tail(&chain->list, &dev->chains); } + if (list_empty(&dev->chains)) + uvc_scan_fallback(dev); + if (list_empty(&dev->chains)) { uvc_printk(KERN_INFO, "No valid video chain found.\n"); return -1; -- cgit v1.2.3 From 37e785682746b53017c7b6e533c3ac2c85bb4ac8 Mon Sep 17 00:00:00 2001 From: CIJOML CIJOMLovic Date: Mon, 1 Aug 2016 18:55:52 -0300 Subject: [media] Add support for EVOLVEO XtraTV stick Add a new USB ID for EVOLVEO XtraTV stick. [mchehab@s-opensource.org: fix patch and make checkpatch happy] Cc: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb-usb-ids.h | 1 + drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index a7a4674ccc40..5938ea4abc69 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h @@ -411,4 +411,5 @@ #define USB_PID_SVEON_STV27 0xd3af #define USB_PID_TURBOX_DTT_2000 0xd3a4 #define USB_PID_WINTV_SOLOHD 0x0264 +#define USB_PID_EVOLVEO_XTRATV_STICK 0xa115 #endif diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 8961dd732522..c673726d9b70 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -2095,6 +2095,8 @@ static const struct usb_device_id af9035_id_table[] = { &af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) }, { DVB_USB_DEVICE(USB_VID_AVERMEDIA, 0x0337, &af9035_props, "AVerMedia HD Volar (A867)", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_EVOLVEO_XTRATV_STICK, + &af9035_props, "EVOLVEO XtraTV stick", NULL) }, /* IT9135 devices */ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135, -- cgit v1.2.3 From c0b34ab141505087d7d66f447d77e6023f34501e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 3 Sep 2016 14:04:17 -0300 Subject: [media] cx24120: do not allow an invalid delivery system types cx24120_set_frontend currently allows invalid delivery system types other than SYS_DVBS2 and SYS_DVBS. Fix this by returning -EINVAL for invalid values. Signed-off-by: Colin Ian King Acked-by: Jemma Denson --- drivers/media/dvb-frontends/cx24120.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 066ee387bf25..3112a3206d46 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1154,8 +1154,7 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) dev_dbg(&state->i2c->dev, "delivery system(%d) not supported\n", c->delivery_system); - ret = -EINVAL; - break; + return -EINVAL; } state->dnxt.delsys = c->delivery_system; -- cgit v1.2.3 From 06c24f6779ea863a9410c872c577d8ae986a4b60 Mon Sep 17 00:00:00 2001 From: Baoyou Xie Date: Tue, 6 Sep 2016 04:50:56 -0300 Subject: [media] coda: add missing header dependencies We get 1 warning when building kernel with W=1: drivers/media/platform/coda/coda-h264.c:22:5: warning: no previous prototype for 'coda_h264_padding' [-Wmissing-prototypes] In fact, this function is declared in coda.h, so this patch add missing header dependencies. Signed-off-by: Baoyou Xie Acked-by: Arnd Bergmann Acked-by: Philipp Zabel --- drivers/media/platform/coda/coda-h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/coda/coda-h264.c b/drivers/media/platform/coda/coda-h264.c index 456773af1f1d..09dfcca7cc50 100644 --- a/drivers/media/platform/coda/coda-h264.c +++ b/drivers/media/platform/coda/coda-h264.c @@ -13,6 +13,7 @@ #include #include +#include static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 }; -- cgit v1.2.3 From 69117994aa7d9dba8ea3bcdde7676b123d975877 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 6 Sep 2016 09:44:09 -0300 Subject: [media] variable name is never null, so remove null check The variable name is always assigned to a literal string in the proceeding switch statement, so it is never null and hence the null check is redundant. Remove null the check. Signed-off-by: Colin Ian King --- drivers/media/usb/pvrusb2/pvrusb2-sysfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c index 06fe63ced58c..d977976b8d91 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c @@ -116,7 +116,6 @@ static ssize_t show_type(struct device *class_dev, } pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s", cip->chptr, cip->ctl_id, name); - if (!name) return -EINVAL; return scnprintf(buf, PAGE_SIZE, "%s\n", name); } -- cgit v1.2.3 From 82b65714a6f5f5124d7cc5a2162272a8576df80f Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Fri, 9 Sep 2016 16:24:54 -0300 Subject: [media] dvb-usb-dvbsky: Add support for TechnoTrend S2-4650 CI TechnoTrend TT-connect S2-4650 CI seems to be a variation of the DVBSky S960CI device. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb-usb-ids.h | 1 + drivers/media/usb/dvb-usb-v2/dvbsky.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index 5938ea4abc69..779f4224b63e 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h @@ -262,6 +262,7 @@ #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012 #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2 0x3015 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014 +#define USB_PID_TECHNOTREND_CONNECT_S2_4650_CI 0x3017 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 02dbc6c45423..0636eac37bbb 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -851,6 +851,10 @@ static const struct usb_device_id dvbsky_id_table[] = { USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2, &dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI v1.1", RC_MAP_TT_1500) }, + { DVB_USB_DEVICE(USB_VID_TECHNOTREND, + USB_PID_TECHNOTREND_CONNECT_S2_4650_CI, + &dvbsky_s960c_props, "TechnoTrend TT-connect S2-4650 CI", + RC_MAP_TT_1500) }, { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_3, &dvbsky_t680c_props, "Terratec H7 Rev.4", -- cgit v1.2.3 From 19157003abe4d9ca4706fca8ff8306946f7942c6 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sat, 10 Sep 2016 13:49:01 -0300 Subject: [media] mb86a20s: always initialize a return value In mb86a20s_read_status_and_stats(), when mb86a20s_read_status() fails, the function returns the value in variable rc without initializing it first. Fix this by propagating the error code from variable status_nr. This bug has been found using clang and -Wsometimes-uninitialized warning flag. Signed-off-by: Nicolas Iooss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index fe79358b035e..27f425137ce6 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -1967,6 +1967,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, if (status_nr < 0) { dev_err(&state->i2c->dev, "%s: Can't read frontend lock status\n", __func__); + rc = status_nr; goto error; } -- cgit v1.2.3 From 7ec03e60ef81c19b5d3a46dd070ee966774b860f Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sat, 10 Sep 2016 13:59:49 -0300 Subject: [media] ite-cir: initialize use_demodulator before using it Function ite_set_carrier_params() uses variable use_demodulator after having initialized it to false in some if branches, but this variable is never set to true otherwise. This bug has been found using clang -Wsometimes-uninitialized warning flag. Fixes: 620a32bba4a2 ("[media] rc: New rc-based ite-cir driver for several ITE CIRs") Signed-off-by: Nicolas Iooss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ite-cir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index c5e8e3885766..367b28bed627 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -261,6 +261,8 @@ static void ite_set_carrier_params(struct ite_dev *dev) if (allowance > ITE_RXDCR_MAX) allowance = ITE_RXDCR_MAX; + + use_demodulator = true; } } -- cgit v1.2.3 From 1a33ac00c5ebc4b2e2efb5bc0252c6ba7dc8ff0f Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Wed, 14 Sep 2016 17:03:13 -0300 Subject: [media] media: i2c: tvp514x: Reported mbus format should be MEDIA_BUS_FMT_UYVY8_2X8 The advertised V4L2 pixel format and Media Bus code don't match. The current media bud code advertised is MEDIA_BUS_FMT_YUYV8_2X8 which does not reflect what the encoder actually outputs. This encoder generate MEDIA_BUS_FMT_UYVY8_2X8 so advertise as such. Signed-off-by: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp514x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index d5c9347f4c6d..0c62899c3667 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -894,7 +894,7 @@ static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, if (index != 0) return -EINVAL; - code->code = MEDIA_BUS_FMT_YUYV8_2X8; + code->code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -922,7 +922,7 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, return 0; } - format->format.code = MEDIA_BUS_FMT_YUYV8_2X8; + format->format.code = MEDIA_BUS_FMT_UYVY8_2X8; format->format.width = tvp514x_std_list[decoder->current_std].width; format->format.height = tvp514x_std_list[decoder->current_std].height; format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -946,7 +946,7 @@ static int tvp514x_set_pad_format(struct v4l2_subdev *sd, struct tvp514x_decoder *decoder = to_decoder(sd); if (fmt->format.field != V4L2_FIELD_INTERLACED || - fmt->format.code != MEDIA_BUS_FMT_YUYV8_2X8 || + fmt->format.code != MEDIA_BUS_FMT_UYVY8_2X8 || fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M || fmt->format.width != tvp514x_std_list[decoder->current_std].width || fmt->format.height != tvp514x_std_list[decoder->current_std].height) -- cgit v1.2.3 From f59d4418c420ac3d6bb896228317168f790f489b Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 22 Sep 2016 10:18:59 -0300 Subject: [media] media: adv7604: fix bindings inconsistency for default-input The text states that default-input is an endpoint property, but in the example it is a device property. The default input is a property of the chip, not of a particular port, so the example makes more sense. Signed-off-by: Ulrich Hecht Reviewed-by: Laurent Pinchart Acked-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/i2c/adv7604.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index 8337f75c75da..9cbd92eb5d05 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt @@ -34,6 +34,7 @@ The digital output port node must contain at least one endpoint. Optional Properties: - reset-gpios: Reference to the GPIO connected to the device's reset pin. + - default-input: Select which input is selected after reset. Optional Endpoint Properties: @@ -47,8 +48,6 @@ Optional Endpoint Properties: If none of hsync-active, vsync-active and pclk-sample is specified the endpoint will use embedded BT.656 synchronization. - - default-input: Select which input is selected after reset. - Example: hdmi_receiver@4c { -- cgit v1.2.3 From c57a68a152dc7e2d0631acb9d3c00d1c33ddecfb Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 22 Sep 2016 10:19:00 -0300 Subject: [media] media: adv7604: automatic "default-input" selection Documentation states that the "default-input" property should reside directly in the node of the device. This adjusts the parsing to make the implementation consistent with the documentation. Based on patch by William Towle . Signed-off-by: Ulrich Hecht Signed-off-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 4003831de712..fa7046ef09b2 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3074,13 +3074,13 @@ static int adv76xx_parse_dt(struct adv76xx_state *state) return ret; } - if (!of_property_read_u32(endpoint, "default-input", &v)) + of_node_put(endpoint); + + if (!of_property_read_u32(np, "default-input", &v)) state->pdata.default_input = v; else state->pdata.default_input = -1; - of_node_put(endpoint); - flags = bus_cfg.bus.parallel.flags; if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) -- cgit v1.2.3 From 1ff52fa0f19c407e0e091bf0c8e169ee017ef725 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 16 Sep 2016 07:16:30 -0300 Subject: [media] ad5820: Fix sparse warning Use a type with explicit endianness in machine to big endian conversion. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ad5820.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c index beab2f381b81..a9026a91855e 100644 --- a/drivers/media/i2c/ad5820.c +++ b/drivers/media/i2c/ad5820.c @@ -65,16 +65,17 @@ static int ad5820_write(struct ad5820_device *coil, u16 data) { struct i2c_client *client = v4l2_get_subdevdata(&coil->subdev); struct i2c_msg msg; + __be16 be_data; int r; if (!client->adapter) return -ENODEV; - data = cpu_to_be16(data); + be_data = cpu_to_be16(data); msg.addr = client->addr; msg.flags = 0; msg.len = 2; - msg.buf = (u8 *)&data; + msg.buf = (u8 *)&be_data; r = i2c_transfer(client->adapter, &msg, 1); if (r < 0) { -- cgit v1.2.3 From 7c073fffb763dceb38737c32408750b3809773f9 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 16 Sep 2016 08:18:21 -0300 Subject: [media] imon: use complete() instead of complete_all() There is only one waiter for the completion, therefore there is no need to use complete_all(). Let's make that clear by using complete() instead of complete_all(). While we are at it, we do a small optimization with the reinitialization of the completion before we use it. The usage pattern of the completion is: waiter context waker context send_packet() init_completion() usb_submit_urb() wait_for_completion_interruptible() usb_tx_callback() complete() imon_disonnect() complete() Signed-off-by: Daniel Wagner Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index bd807fa4cb9f..0785a24af8fc 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -607,7 +607,7 @@ static int send_packet(struct imon_context *ictx) ictx->tx_urb->actual_length = 0; } - init_completion(&ictx->tx.finished); + reinit_completion(&ictx->tx.finished); ictx->tx.busy = true; smp_rmb(); /* ensure later readers know we're busy */ @@ -2216,6 +2216,8 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, ictx->tx_urb = tx_urb; ictx->rf_device = false; + init_completion(&ictx->tx.finished); + ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); @@ -2491,7 +2493,7 @@ static void imon_disconnect(struct usb_interface *interface) /* Abort ongoing write */ if (ictx->tx.busy) { usb_kill_urb(ictx->tx_urb); - complete_all(&ictx->tx.finished); + complete(&ictx->tx.finished); } if (ifnum == 0) { -- cgit v1.2.3 From 9b26336356603d457a53255adc7a4fdad31c5ede Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 16 Sep 2016 08:18:22 -0300 Subject: [media] lirc_imon: use complete() instead complete_all() There is only one waiter for the completion, therefore there is no need to use complete_all(). Let's make that clear by using complete() instead of complete_all(). While we are at it, we do a small optimization with the reinitialization of the completion before we use it. The usage pattern of the completion is: waiter context waker context send_packet() reinit_completion() usb_sumbit_urb() wait_for_completion_interruptible() usb_tx_callback() complete() imon_disconnect() complete() Signed-off-by: Daniel Wagner Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_imon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 198a8057f2f1..00e00b0be275 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -334,7 +334,7 @@ static int send_packet(struct imon_context *context) context->tx_urb->actual_length = 0; - init_completion(&context->tx.finished); + reinit_completion(&context->tx.finished); atomic_set(&context->tx.busy, 1); retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); @@ -497,6 +497,8 @@ static int ir_open(void *data) context->rx.initial_space = 1; context->rx.prev_bit = 0; + init_completion(&context->tx.finished); + context->ir_isopen = 1; dev_info(context->driver->dev, "IR port opened\n"); @@ -930,7 +932,7 @@ static void imon_disconnect(struct usb_interface *interface) /* Abort ongoing write */ if (atomic_read(&context->tx.busy)) { usb_kill_urb(context->tx_urb); - complete_all(&context->tx.finished); + complete(&context->tx.finished); } context->dev_present = 0; -- cgit v1.2.3 From ff681022c6639c194fbb6893c50ace9e52a44788 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 19 Sep 2016 09:46:30 -0300 Subject: [media] platform: pxa_camera: add VIDEO_V4L2 dependency Moving the pxa_camera driver from soc_camera lots the implied VIDEO_V4L2 Kconfig dependency, and building the driver without V4L2 results in a kernel that cannot link: drivers/media/platform/pxa_camera.o: In function `pxa_camera_remove': pxa_camera.c:(.text.pxa_camera_remove+0x10): undefined reference to `v4l2_clk_unregister' pxa_camera.c:(.text.pxa_camera_remove+0x18): undefined reference to `v4l2_device_unregister' drivers/media/platform/pxa_camera.o: In function `pxa_camera_probe': pxa_camera.c:(.text.pxa_camera_probe+0x458): undefined reference to `v4l2_of_parse_endpoint' drivers/media/v4l2-core/videobuf2-core.o: In function `__enqueue_in_driver': drivers/media/v4l2-core/videobuf2-core.o: In function `vb2_core_streamon': videobuf2-core.c:(.text.vb2_core_streamon+0x1b4): undefined reference to `v4l_vb2q_enable_media_source' drivers/media/v4l2-core/videobuf2-v4l2.o: In function `vb2_ioctl_reqbufs': videobuf2-v4l2.c:(.text.vb2_ioctl_reqbufs+0xc): undefined reference to `video_devdata' This adds back an explicit dependency. Fixes: 3050b9985024 ("[media] media: platform: pxa_camera: move pxa_camera out of soc_camera") Signed-off-by: Arnd Bergmann Acked-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 8d00a3fdcf96..754edbf1a326 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -93,7 +93,7 @@ config VIDEO_OMAP3_DEBUG config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" - depends on VIDEO_DEV && HAS_DMA + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA depends on PXA27x || COMPILE_TEST select VIDEOBUF2_DMA_SG select SG_SPLIT -- cgit v1.2.3 From b7491e7e902a488503982c9be098cac578a94bdc Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2016 10:09:23 -0300 Subject: [media] gs1662: remove .owner field for driver Remove .owner field if calls are used which set it automatically. Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Wei Yongjun Signed-off-by: Mauro Carvalho Chehab --- drivers/media/spi/gs1662.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/spi/gs1662.c b/drivers/media/spi/gs1662.c index d76f36233f43..057530bf8528 100644 --- a/drivers/media/spi/gs1662.c +++ b/drivers/media/spi/gs1662.c @@ -463,7 +463,6 @@ static int gs_remove(struct spi_device *spi) static struct spi_driver gs_driver = { .driver = { .name = "gs1662", - .owner = THIS_MODULE, }, .probe = gs_probe, -- cgit v1.2.3 From df94121f02ecce435d6b5277071eb94b764caa89 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2016 10:09:39 -0300 Subject: [media] gs1662: drop kfree for memory allocated with devm_kzalloc It's not necessary to free memory allocated with devm_kzalloc and using kfree leads to a double free. Fixes: 7aae6e2df127 ("[media] Add GS1662 driver, a video serializer") Signed-off-by: Wei Yongjun Signed-off-by: Mauro Carvalho Chehab --- drivers/media/spi/gs1662.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/spi/gs1662.c b/drivers/media/spi/gs1662.c index 057530bf8528..330dcb2b2e44 100644 --- a/drivers/media/spi/gs1662.c +++ b/drivers/media/spi/gs1662.c @@ -453,10 +453,9 @@ static int gs_probe(struct spi_device *spi) static int gs_remove(struct spi_device *spi) { struct v4l2_subdev *sd = spi_get_drvdata(spi); - struct gs *gs = to_gs(sd); v4l2_device_unregister_subdev(sd); - kfree(gs); + return 0; } -- cgit v1.2.3 From 017f4fb7f2eaa191072e7c0bd1153a879b3e207e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2016 12:09:38 -0300 Subject: [media] bdisp: fix error return code in bdisp_probe() Fix to return error code -EINVAL from the platform_get_resource() error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Reviewed-by: Fabien Dessenne Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 45f82b5ddd77..823608112d89 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1337,6 +1337,7 @@ static int bdisp_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to get IRQ resource\n"); + ret = -EINVAL; goto err_clk; } -- cgit v1.2.3 From e546b1ef22850d53a9e21c4d0bcf9a6057cd9293 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 21 Sep 2016 12:12:58 -0300 Subject: [media] cx88: fix error return code in cx8802_dvb_probe() Fix to return error code -ENODEV from the error handling case instead of 0(err maybe overwrited to 0 in the for loop), as done elsewhere in this function. [mchehab@s-opensource.com: remove a now uneeded set for err = -ENODEV] Signed-off-by: Wei Yongjun Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index fe5fd2a4650b..157bc14874eb 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -1769,7 +1769,6 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) if (err) goto fail_core; - err = -ENODEV; for (i = 1; i <= core->board.num_frontends; i++) { struct vb2_queue *q; @@ -1777,6 +1776,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) if (fe == NULL) { printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); + err = -ENODEV; goto fail_probe; } q = &fe->dvb.dvbq; -- cgit v1.2.3 From 6dfcd296576a14bc52d0453e4ba7ed09323a26dc Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Wed, 21 Sep 2016 21:04:20 -0300 Subject: [media] tw5864: crop picture width to 704 Previously, width of 720 was used, but it gives 16-pixel wide black bar at right side of encoded picture. Signed-off-by: Andrey Utkin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/tw5864/tw5864-reg.h | 8 ++++++++ drivers/media/pci/tw5864/tw5864-video.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/tw5864/tw5864-reg.h b/drivers/media/pci/tw5864/tw5864-reg.h index 92a1b077ef8a..30ac14210e91 100644 --- a/drivers/media/pci/tw5864/tw5864-reg.h +++ b/drivers/media/pci/tw5864/tw5864-reg.h @@ -1879,6 +1879,14 @@ #define TW5864_INDIR_IN_PIC_HEIGHT(channel) (0x201 + 4 * channel) #define TW5864_INDIR_OUT_PIC_WIDTH(channel) (0x202 + 4 * channel) #define TW5864_INDIR_OUT_PIC_HEIGHT(channel) (0x203 + 4 * channel) + +/* Some registers skipped */ + +#define TW5864_INDIR_CROP_ETC 0x260 +/* Define controls in register TW5864_INDIR_CROP_ETC */ +/* Enable cropping from 720 to 704 */ +#define TW5864_INDIR_CROP_ETC_CROP_EN 0x4 + /* * Interrupt status register from the front-end. Write "1" to each bit to clear * the interrupt diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c index 652a059b2e0a..9421216bb942 100644 --- a/drivers/media/pci/tw5864/tw5864-video.c +++ b/drivers/media/pci/tw5864/tw5864-video.c @@ -330,6 +330,15 @@ static int tw5864_enable_input(struct tw5864_input *input) tw_indir_writeb(TW5864_INDIR_OUT_PIC_WIDTH(nr), input->width / 4); tw_indir_writeb(TW5864_INDIR_OUT_PIC_HEIGHT(nr), input->height / 4); + /* + * Crop width from 720 to 704. + * Above register settings need value 720 involved. + */ + input->width = 704; + tw_indir_writeb(TW5864_INDIR_CROP_ETC, + tw_indir_readb(TW5864_INDIR_CROP_ETC) | + TW5864_INDIR_CROP_ETC_CROP_EN); + tw_writel(TW5864_DSP_PIC_MAX_MB, ((input->width / 16) << 8) | (input->height / 16)); @@ -532,7 +541,7 @@ static int tw5864_fmt_vid_cap(struct file *file, void *priv, { struct tw5864_input *input = video_drvdata(file); - f->fmt.pix.width = 720; + f->fmt.pix.width = 704; switch (input->std) { default: WARN_ON_ONCE(1); @@ -738,7 +747,7 @@ static int tw5864_enum_framesizes(struct file *file, void *priv, return -EINVAL; fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = 720; + fsize->discrete.width = 704; fsize->discrete.height = input->std == STD_NTSC ? 480 : 576; return 0; -- cgit v1.2.3 From c771f42fed7f21f510793302687884b424cd9f54 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Fri, 23 Sep 2016 15:41:39 -0300 Subject: [media] media: platform: pxa_camera: add missing sensor power on During sensors binding, there is a window where the sensor is switched off, while there is a call it to set a new format, which can end up in an access to the sensor, especially an I2C based sensor. Remove this window by activating the sensor. Signed-off-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/pxa_camera.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index bcdac4932fb1..929006f65cc7 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2125,17 +2125,22 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, pix->bytesperline, pix->height); pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc; v4l2_fill_mbus_format(mf, pix, pcdev->current_fmt->code); - err = sensor_call(pcdev, pad, set_fmt, NULL, &format); + + err = sensor_call(pcdev, core, s_power, 1); if (err) goto out; + err = sensor_call(pcdev, pad, set_fmt, NULL, &format); + if (err) + goto out_sensor_poweroff; + v4l2_fill_pix_format(pix, mf); pr_info("%s(): colorspace=0x%x pixfmt=0x%x\n", __func__, pix->colorspace, pix->pixelformat); err = pxa_camera_init_videobuf2(pcdev); if (err) - goto out; + goto out_sensor_poweroff; err = video_register_device(&pcdev->vdev, VFL_TYPE_GRABBER, -1); if (err) { @@ -2146,6 +2151,9 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, "PXA Camera driver attached to camera %s\n", subdev->name); } + +out_sensor_poweroff: + err = sensor_call(pcdev, core, s_power, 0); out: mutex_unlock(&pcdev->mlock); return err; -- cgit v1.2.3 From 8a5d2acee6fa9ec5997335cc3ebdd47c7524d6d2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 23 Sep 2016 18:19:01 -0300 Subject: [media] VPU: mediatek: Fix return value in case of error If 'dma_alloc_coherent()' returns NULL, 'vpu_alloc_ext_mem()' will return 0 which means success. Return -ENOMEM instead. Signed-off-by: Christophe JAILLET Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index c3643d929167..463b69c934be 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -689,7 +689,7 @@ static int vpu_alloc_ext_mem(struct mtk_vpu *vpu, u32 fw_type) GFP_KERNEL); if (!vpu->extmem[fw_type].va) { dev_err(dev, "Failed to allocate the extended program memory\n"); - return PTR_ERR(vpu->extmem[fw_type].va); + return -ENOMEM; } /* Disable extend0. Enable extend1 */ -- cgit v1.2.3 From 37e90a220abc4c5dee1fc42382cbca595a0e95bd Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 27 Sep 2016 16:48:47 -0300 Subject: [media] rc: ir-raw: change type of available_protocols to atomic64_t Changing available_protocols to atomic64_t allows to get rid of the mutex protecting access to the variable. This helps to simplify the code. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-ir-raw.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 205ecc602e34..1c42a9f2f290 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -26,8 +26,7 @@ static LIST_HEAD(ir_raw_client_list); /* Used to handle IR raw handler extensions */ static DEFINE_MUTEX(ir_raw_handler_lock); static LIST_HEAD(ir_raw_handler_list); -static DEFINE_MUTEX(available_protocols_lock); -static u64 available_protocols; +static atomic64_t available_protocols = ATOMIC64_INIT(0); static int ir_raw_event_thread(void *data) { @@ -234,11 +233,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_handle); u64 ir_raw_get_allowed_protocols(void) { - u64 protocols; - mutex_lock(&available_protocols_lock); - protocols = available_protocols; - mutex_unlock(&available_protocols_lock); - return protocols; + return atomic64_read(&available_protocols); } static int change_protocol(struct rc_dev *dev, u64 *rc_type) @@ -331,9 +326,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) if (ir_raw_handler->raw_register) list_for_each_entry(raw, &ir_raw_client_list, list) ir_raw_handler->raw_register(raw->dev); - mutex_lock(&available_protocols_lock); - available_protocols |= ir_raw_handler->protocols; - mutex_unlock(&available_protocols_lock); + atomic64_or(ir_raw_handler->protocols, &available_protocols); mutex_unlock(&ir_raw_handler_lock); return 0; @@ -352,9 +345,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) if (ir_raw_handler->raw_unregister) ir_raw_handler->raw_unregister(raw->dev); } - mutex_lock(&available_protocols_lock); - available_protocols &= ~protocols; - mutex_unlock(&available_protocols_lock); + atomic64_andnot(protocols, &available_protocols); mutex_unlock(&ir_raw_handler_lock); } EXPORT_SYMBOL(ir_raw_handler_unregister); -- cgit v1.2.3 From fa8bbe0a8567bf4eb87e82739465360a6797c91b Mon Sep 17 00:00:00 2001 From: Songjun Wu Date: Wed, 28 Sep 2016 02:28:57 -0300 Subject: [media] atmel-isc: start dma in some scenario If a new vb buf is added to vb queue, the queue is empty and steaming, dma should be started. Signed-off-by: Songjun Wu Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index ccfe13b7d3f8..8e25d3f56438 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -617,7 +617,13 @@ static void isc_buffer_queue(struct vb2_buffer *vb) unsigned long flags; spin_lock_irqsave(&isc->dma_queue_lock, flags); - list_add_tail(&buf->list, &isc->dma_queue); + if (!isc->cur_frm && list_empty(&isc->dma_queue) && + vb2_is_streaming(vb->vb2_queue)) { + isc->cur_frm = buf; + isc_start_dma(isc->regmap, isc->cur_frm, + isc->current_fmt->reg_dctrl_dview); + } else + list_add_tail(&buf->list, &isc->dma_queue); spin_unlock_irqrestore(&isc->dma_queue_lock, flags); } -- cgit v1.2.3 From 8f3408d5a14f3a50253d9e8fd4c443af4af8fa3f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 28 Sep 2016 12:13:13 -0300 Subject: [media] stih-cec: remove unused including Remove including that don't need it. Signed-off-by: Wei Yongjun Acked-by: Benjamin Gaignard Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/st-cec/stih-cec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c index 214344866a6b..b0aee1d4d5d0 100644 --- a/drivers/staging/media/st-cec/stih-cec.c +++ b/drivers/staging/media/st-cec/stih-cec.c @@ -16,7 +16,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From ddbf7d5a698c4d8553ad2f77cb281d7b37898d34 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Fri, 30 Sep 2016 17:42:07 -0300 Subject: [media] rc: core: add managed versions of rc_allocate_device and rc_register_device Introduce managed versions of both functions. They allows to simplify the error path in the probe function of rc drivers, and usually also to simplify the remove function. New element managed_alloc in struct rc_dev is needed to correctly handle mixed use, e.g. managed version of rc_register_device and normal version of rc_allocate_device. In addition devm_rc_allocate_device sets rc->dev.parent as having a reference to the parent device might be useful for future extensions. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 58 +++++++++++++++++++++++++++++++++++++++++++++- include/media/rc-core.h | 18 ++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b241e5f569ef..5087e76dfb03 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1402,6 +1402,34 @@ void rc_free_device(struct rc_dev *dev) } EXPORT_SYMBOL_GPL(rc_free_device); +static void devm_rc_alloc_release(struct device *dev, void *res) +{ + rc_free_device(*(struct rc_dev **)res); +} + +struct rc_dev *devm_rc_allocate_device(struct device *dev) +{ + struct rc_dev **dr, *rc; + + dr = devres_alloc(devm_rc_alloc_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return NULL; + + rc = rc_allocate_device(); + if (!rc) { + devres_free(dr); + return NULL; + } + + rc->dev.parent = dev; + rc->managed_alloc = true; + *dr = rc; + devres_add(dev, dr); + + return rc; +} +EXPORT_SYMBOL_GPL(devm_rc_allocate_device); + int rc_register_device(struct rc_dev *dev) { static bool raw_init = false; /* raw decoders loaded? */ @@ -1530,6 +1558,33 @@ out_unlock: } EXPORT_SYMBOL_GPL(rc_register_device); +static void devm_rc_release(struct device *dev, void *res) +{ + rc_unregister_device(*(struct rc_dev **)res); +} + +int devm_rc_register_device(struct device *parent, struct rc_dev *dev) +{ + struct rc_dev **dr; + int ret; + + dr = devres_alloc(devm_rc_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + ret = rc_register_device(dev); + if (ret) { + devres_free(dr); + return ret; + } + + *dr = dev; + devres_add(parent, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_rc_register_device); + void rc_unregister_device(struct rc_dev *dev) { if (!dev) @@ -1551,7 +1606,8 @@ void rc_unregister_device(struct rc_dev *dev) ida_simple_remove(&rc_ida, dev->minor); - rc_free_device(dev); + if (!dev->managed_alloc) + rc_free_device(dev); } EXPORT_SYMBOL_GPL(rc_unregister_device); diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 40188d362486..55281b92105a 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -68,6 +68,7 @@ enum rc_filter_type { * struct rc_dev - represents a remote control device * @dev: driver model's view of this device * @initialized: 1 if the device init has completed, 0 otherwise + * @managed_alloc: devm_rc_allocate_device was used to create rc_dev * @sysfs_groups: sysfs attribute groups * @input_name: name of the input child device * @input_phys: physical path to the input child device @@ -131,6 +132,7 @@ enum rc_filter_type { struct rc_dev { struct device dev; atomic_t initialized; + bool managed_alloc; const struct attribute_group *sysfs_groups[5]; const char *input_name; const char *input_phys; @@ -202,6 +204,14 @@ struct rc_dev { */ struct rc_dev *rc_allocate_device(void); +/** + * devm_rc_allocate_device - Managed RC device allocation + * + * @dev: pointer to struct device + * returns a pointer to struct rc_dev. + */ +struct rc_dev *devm_rc_allocate_device(struct device *dev); + /** * rc_free_device - Frees a RC device * @@ -216,6 +226,14 @@ void rc_free_device(struct rc_dev *dev); */ int rc_register_device(struct rc_dev *dev); +/** + * devm_rc_register_device - Manageded registering of a RC device + * + * @parent: pointer to struct device. + * @dev: pointer to struct rc_dev. + */ +int devm_rc_register_device(struct device *parent, struct rc_dev *dev); + /** * rc_unregister_device - Unregisters a RC device * -- cgit v1.2.3 From b6f3ece3873323a3d4dd56d71231d5f758265463 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Fri, 30 Sep 2016 17:42:17 -0300 Subject: [media] rc: nuvoton: use managed versions of rc_allocate_device and rc_register_device Simplify the remove function and the error path in the probe function by using the managed versions of rc_allocate_device and rc_register_device. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 50 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 04fedaa75612..3df3bd9aab7e 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1002,40 +1002,40 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) { struct nvt_dev *nvt; struct rc_dev *rdev; - int ret = -ENOMEM; + int ret; nvt = devm_kzalloc(&pdev->dev, sizeof(struct nvt_dev), GFP_KERNEL); if (!nvt) - return ret; + return -ENOMEM; /* input device for IR remote (and tx) */ - rdev = rc_allocate_device(); + rdev = devm_rc_allocate_device(&pdev->dev); if (!rdev) - goto exit_free_dev_rdev; + return -ENOMEM; - ret = -ENODEV; /* activate pnp device */ - if (pnp_activate_dev(pdev) < 0) { + ret = pnp_activate_dev(pdev); + if (ret) { dev_err(&pdev->dev, "Could not activate PNP device!\n"); - goto exit_free_dev_rdev; + return ret; } /* validate pnp resources */ if (!pnp_port_valid(pdev, 0) || pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) { dev_err(&pdev->dev, "IR PNP Port not valid!\n"); - goto exit_free_dev_rdev; + return -EINVAL; } if (!pnp_irq_valid(pdev, 0)) { dev_err(&pdev->dev, "PNP IRQ not valid!\n"); - goto exit_free_dev_rdev; + return -EINVAL; } if (!pnp_port_valid(pdev, 1) || pnp_port_len(pdev, 1) < CIR_IOREG_LENGTH) { dev_err(&pdev->dev, "Wake PNP Port not valid!\n"); - goto exit_free_dev_rdev; + return -EINVAL; } nvt->cir_addr = pnp_port_start(pdev, 0); @@ -1056,7 +1056,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) ret = nvt_hw_detect(nvt); if (ret) - goto exit_free_dev_rdev; + return ret; /* Initialize CIR & CIR Wake Logical Devices */ nvt_efm_enable(nvt); @@ -1099,27 +1099,27 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) #endif nvt->rdev = rdev; - ret = rc_register_device(rdev); + ret = devm_rc_register_device(&pdev->dev, rdev); if (ret) - goto exit_free_dev_rdev; + return ret; - ret = -EBUSY; /* now claim resources */ if (!devm_request_region(&pdev->dev, nvt->cir_addr, CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto exit_unregister_device; + return -EBUSY; - if (devm_request_irq(&pdev->dev, nvt->cir_irq, nvt_cir_isr, - IRQF_SHARED, NVT_DRIVER_NAME, (void *)nvt)) - goto exit_unregister_device; + ret = devm_request_irq(&pdev->dev, nvt->cir_irq, nvt_cir_isr, + IRQF_SHARED, NVT_DRIVER_NAME, nvt); + if (ret) + return ret; if (!devm_request_region(&pdev->dev, nvt->cir_wake_addr, CIR_IOREG_LENGTH, NVT_DRIVER_NAME "-wake")) - goto exit_unregister_device; + return -EBUSY; ret = device_create_file(&rdev->dev, &dev_attr_wakeup_data); if (ret) - goto exit_unregister_device; + return ret; device_init_wakeup(&pdev->dev, true); @@ -1130,14 +1130,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) } return 0; - -exit_unregister_device: - rc_unregister_device(rdev); - rdev = NULL; -exit_free_dev_rdev: - rc_free_device(rdev); - - return ret; } static void nvt_remove(struct pnp_dev *pdev) @@ -1150,8 +1142,6 @@ static void nvt_remove(struct pnp_dev *pdev) /* enable CIR Wake (for IR power-on) */ nvt_enable_wake(nvt); - - rc_unregister_device(nvt->rdev); } static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) -- cgit v1.2.3 From e128c9acdd4bffb3e962d8b8c78614971b12abe1 Mon Sep 17 00:00:00 2001 From: Wayne Porter Date: Sat, 1 Oct 2016 21:06:27 -0300 Subject: [media] bcm2048: Remove FSF mailing address FSF address changes, checkpatch recommends removing it Signed-off-by: Wayne Porter Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.h b/drivers/staging/media/bcm2048/radio-bcm2048.h index 4c90a32db795..4d950c1e2e8b 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.h +++ b/drivers/staging/media/bcm2048/radio-bcm2048.h @@ -14,11 +14,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA */ #ifndef BCM2048_H -- cgit v1.2.3 From 69fd825c17a9f0e2ad939ee701c64242d181cdb9 Mon Sep 17 00:00:00 2001 From: Enrico Mioso Date: Tue, 4 Oct 2016 08:13:27 -0300 Subject: [media] Add Cinergy S2 rev.4 support This patch derives from previous one(s) by CrazyCat. I used the commit adding rev.3 to mainline Linux kernel as an example, so credits go to its author(s). The hardware seems to scan and tune OK. Signed-off-by: Enrico Mioso Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 38794ab8874e..6ca502d834b4 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1641,6 +1641,7 @@ enum dw2102_table_entry { TEVII_S632, TERRATEC_CINERGY_S2_R2, TERRATEC_CINERGY_S2_R3, + TERRATEC_CINERGY_S2_R4, GOTVIEW_SAT_HD, GENIATECH_T220, TECHNOTREND_S2_4600, @@ -1670,6 +1671,7 @@ static struct usb_device_id dw2102_table[] = { [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R2)}, [TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R3)}, + [TERRATEC_CINERGY_S2_R4] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4)}, [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND, -- cgit v1.2.3 From c762ff1f7e3b09293c22ce62135ef550c1b3327c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 4 Oct 2016 12:41:37 -0300 Subject: [media] coda: fix the error path in coda_probe() In the case of coda_firmware_request() failure, we should release the prevously acquired resources. Signed-off-by: Fabio Estevam Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index c39718a63e5e..9e6bdafa16f5 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2295,8 +2295,13 @@ static int coda_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - return coda_firmware_request(dev); + ret = coda_firmware_request(dev); + if (ret) + goto err_alloc_workqueue; + return 0; +err_alloc_workqueue: + destroy_workqueue(dev->workqueue); err_v4l2_register: v4l2_device_unregister(&dev->v4l2_dev); return ret; -- cgit v1.2.3 From 079933dbcb02132cc48ba052882fe0a9e3b0b762 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 5 Oct 2016 04:13:10 -0300 Subject: [media] v4l: flash led class: Fix of_node release in probe() error path The sub-device's OF node was used (of_node_get()) if it was set, but device's OF node was always put. Fix this. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-flash-led-class.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index ae7544d5469a..6b31c0aad84a 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -638,7 +638,7 @@ struct v4l2_flash *v4l2_flash_init( v4l2_flash->iled_cdev = iled_cdev; v4l2_flash->ops = ops; sd->dev = dev; - sd->of_node = of_node; + sd->of_node = of_node ? of_node : led_cdev->dev->of_node; v4l2_subdev_init(sd, &v4l2_flash_subdev_ops); sd->internal_ops = &v4l2_flash_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -654,10 +654,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) goto err_init_controls; - if (sd->of_node) - of_node_get(sd->of_node); - else - of_node_get(led_cdev->dev->of_node); + of_node_get(sd->of_node); ret = v4l2_async_register_subdev(sd); if (ret < 0) @@ -666,7 +663,7 @@ struct v4l2_flash *v4l2_flash_init( return v4l2_flash; err_async_register_sd: - of_node_put(led_cdev->dev->of_node); + of_node_put(sd->of_node); v4l2_ctrl_handler_free(sd->ctrl_handler); err_init_controls: media_entity_cleanup(&sd->entity); @@ -688,10 +685,7 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash) v4l2_async_unregister_subdev(sd); - if (sd->of_node) - of_node_put(sd->of_node); - else - of_node_put(led_cdev->dev->of_node); + of_node_put(sd->of_node); v4l2_ctrl_handler_free(sd->ctrl_handler); media_entity_cleanup(&sd->entity); -- cgit v1.2.3 From bd676c0c04ec94bd830b9192e2c33f2c4532278d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Oct 2016 18:42:30 -0200 Subject: [media] v4l2-flash-led-class: remove a now unused var commit 079933dbcb02 ("[media] v4l: flash led class: Fix of_node release in probe() error path") removed the need of an ancillary var at the release function, as reported by smatch: drivers/media/v4l2-core/v4l2-flash-led-class.c: In function 'v4l2_flash_release': drivers/media/v4l2-core/v4l2-flash-led-class.c:678:23: warning: variable 'led_cdev' set but not used [-Wunused-but-set-variable] struct led_classdev *led_cdev; ^~~~~~~~ Get rid of it. Fixes: commit 079933dbcb02 ("[media] v4l: flash led class: Fix of_node release in probe() error path") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 6b31c0aad84a..794e563f24f8 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -675,13 +675,11 @@ EXPORT_SYMBOL_GPL(v4l2_flash_init); void v4l2_flash_release(struct v4l2_flash *v4l2_flash) { struct v4l2_subdev *sd; - struct led_classdev *led_cdev; if (IS_ERR_OR_NULL(v4l2_flash)) return; sd = &v4l2_flash->sd; - led_cdev = &v4l2_flash->fled_cdev->led_cdev; v4l2_async_unregister_subdev(sd); -- cgit v1.2.3 From d2dc12d6c8325d1093ffb142315f6b4fc53f95e7 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 7 Oct 2016 16:07:43 -0300 Subject: [media] dvb-tc90522: Use kmalloc_array() in tc90522_master_xfer() A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kmalloc_array". This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tc90522.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index 31cd32532387..c2d45f071331 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -656,7 +656,7 @@ tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) for (i = 0; i < num; i++) if (msgs[i].flags & I2C_M_RD) rd_num++; - new_msgs = kmalloc(sizeof(*new_msgs) * (num + rd_num), GFP_KERNEL); + new_msgs = kmalloc_array(num + rd_num, sizeof(*new_msgs), GFP_KERNEL); if (!new_msgs) return -ENOMEM; -- cgit v1.2.3 From 68226b4dfa9b2e064e2f9e792bf7469f465054c7 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 7 Oct 2016 16:13:57 -0300 Subject: [media] dvb-tc90522: Rename a jump label in tc90522_probe() Adjust a jump label according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tc90522.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index c2d45f071331..4687e1546af2 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -794,14 +794,13 @@ static int tc90522_probe(struct i2c_client *client, i2c_set_adapdata(adap, state); ret = i2c_add_adapter(adap); if (ret < 0) - goto err; + goto free_state; cfg->tuner_i2c = state->cfg.tuner_i2c = adap; i2c_set_clientdata(client, &state->cfg); dev_info(&client->dev, "Toshiba TC90522 attached.\n"); return 0; - -err: +free_state: kfree(state); return ret; } -- cgit v1.2.3 From 045d69ce2116f72d9e658ff59427a11c93754a98 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 7 Oct 2016 17:07:27 -0300 Subject: [media] cx88-dsp: Use kmalloc_array() in read_rds_samples() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kmalloc_array". This issue was detected by using the Coccinelle software. * Replace the specification of a data type by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-dsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 7fafd132ccaf..341e24432fab 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -245,8 +245,7 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) current_address, current_address - srch->fifo_start, sample_count, cx_read(MO_AUD_INTSTAT)); - - samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL); + samples = kmalloc_array(sample_count, sizeof(*samples), GFP_KERNEL); if (!samples) return NULL; -- cgit v1.2.3 From 26f61c0ddf0e191fdab5c15f00c4bf8f3544be6b Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 7 Oct 2016 17:30:40 -0300 Subject: [media] cx88-dsp: Add some spaces for better code readability Use space characters at some source code places according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-dsp.c | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 341e24432fab..33f3c58f8197 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -31,7 +31,7 @@ #define INT_PI ((s32)(3.141592653589 * 32768.0)) #define compat_remainder(a, b) \ - ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0) + ((float)(((s32)((a) * 100)) % ((s32)((b) * 100))) / 100.0) #define baseband_freq(carrier, srate, tone) ((s32)( \ (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI)) @@ -82,15 +82,15 @@ static s32 int_cos(u32 x) if (period % 2) return -int_cos(x - INT_PI); x = x % INT_PI; - if (x > INT_PI/2) - return -int_cos(INT_PI/2 - (x % (INT_PI/2))); + if (x > INT_PI / 2) + return -int_cos(INT_PI / 2 - (x % (INT_PI / 2))); /* Now x is between 0 and INT_PI/2. * To calculate cos(x) we use it's Taylor polinom. */ - t2 = x*x/32768/2; - t4 = t2*x/32768*x/32768/3/4; - t6 = t4*x/32768*x/32768/5/6; - t8 = t6*x/32768*x/32768/7/8; - ret = 32768-t2+t4-t6+t8; + t2 = x * x / 32768 / 2; + t4 = t2 * x / 32768 * x / 32768 / 3 / 4; + t6 = t4 * x / 32768 * x / 32768 / 5 / 6; + t8 = t6 * x / 32768 * x / 32768 / 7 / 8; + ret = 32768 - t2 + t4 - t6 + t8; return ret; } @@ -100,14 +100,14 @@ static u32 int_goertzel(s16 x[], u32 N, u32 freq) * given frequency in the signal */ s32 s_prev = 0; s32 s_prev2 = 0; - s32 coeff = 2*int_cos(freq); + s32 coeff = 2 * int_cos(freq); u32 i; u64 tmp; u32 divisor; for (i = 0; i < N; i++) { - s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2; + s32 s = x[i] + ((s64)coeff * s_prev / 32768) - s_prev2; s_prev2 = s_prev; s_prev = s; } @@ -138,7 +138,7 @@ static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end) if (N > 192) { /* The last 192 samples are enough for noise detection */ - x += (N-192); + x += (N - 192); N = 192; } @@ -196,8 +196,8 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) if (core->tvaudio == WW_EIAJ) { /* EIAJ checks may need adjustments */ - if ((carrier > max(stereo, dual)*2) && - (carrier < max(stereo, dual)*6) && + if ((carrier > max(stereo, dual) * 2) && + (carrier < max(stereo, dual) * 6) && (carrier > 20 && carrier < 200) && (max(stereo, dual) > min(stereo, dual))) { /* For EIAJ the carrier is always present, @@ -205,11 +205,11 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) return ret; } } else { - if ((carrier > max(stereo, dual)*2) && - (carrier < max(stereo, dual)*8) && + if ((carrier > max(stereo, dual) * 2) && + (carrier < max(stereo, dual) * 8) && (carrier > 20 && carrier < 200) && (noise < 10) && - (max(stereo, dual) > min(stereo, dual)*2)) { + (max(stereo, dual) > min(stereo, dual) * 2)) { return ret; } } @@ -234,9 +234,9 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) s16 *samples; unsigned int i; - unsigned int bpl = srch->fifo_size/AUD_RDS_LINES; - unsigned int spl = bpl/4; - unsigned int sample_count = spl*(AUD_RDS_LINES-1); + unsigned int bpl = srch->fifo_size / AUD_RDS_LINES; + unsigned int spl = bpl / 4; + unsigned int sample_count = spl * (AUD_RDS_LINES - 1); u32 current_address = cx_read(srch->ptr1_reg); u32 offset = (current_address - srch->fifo_start + bpl); @@ -252,7 +252,7 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) *N = sample_count; for (i = 0; i < sample_count; i++) { - offset = offset % (AUD_RDS_LINES*bpl); + offset = offset % (AUD_RDS_LINES * bpl); samples[i] = cx_read(srch->fifo_start + offset); offset += 4; } -- cgit v1.2.3 From 73446966b9ab9da118bb905bdbb5e8d3a1826b25 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 9 Oct 2016 16:12:13 -0300 Subject: [media] blackfin-capture: Use kcalloc() in bcap_init_sensor_formats() A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus reuse the corresponding function "kcalloc". This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/bfin_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 8eb03397d736..c5e10439e8b9 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -169,7 +169,7 @@ static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) if (!num_formats) return -ENXIO; - sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL); + sf = kcalloc(num_formats, sizeof(*sf), GFP_KERNEL); if (!sf) return -ENOMEM; -- cgit v1.2.3 From e44e9489a7bda01bb26986fdf5b17559d26c26af Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 9 Oct 2016 16:30:18 -0300 Subject: [media] blackfin-capture: Delete an error message for a failed memory allocation The script "checkpatch.pl" pointed information out like the following. WARNING: Possible unnecessary 'out of memory' message Thus remove such a statement here. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/bfin_capture.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index c5e10439e8b9..2e6edc09b58f 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -802,10 +802,8 @@ static int bcap_probe(struct platform_device *pdev) } bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL); - if (!bcap_dev) { - v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n"); + if (!bcap_dev) return -ENOMEM; - } bcap_dev->cfg = config; -- cgit v1.2.3 From f42afd29e60585904fc5127862263437ed7cbbd5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 11 Oct 2016 04:40:41 -0300 Subject: [media] DaVinci-VPBE: Use kmalloc_array() in vpbe_initialize() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kmalloc_array". This issue was detected by using the Coccinelle software. * Replace the specification of a data type by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 7d2670732805..785d6cf93152 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -676,9 +676,9 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) * store venc sd index. */ num_encoders = vpbe_dev->cfg->num_ext_encoders + 1; - vpbe_dev->encoders = kmalloc( - sizeof(struct v4l2_subdev *)*num_encoders, - GFP_KERNEL); + vpbe_dev->encoders = kmalloc_array(num_encoders, + sizeof(*vpbe_dev->encoders), + GFP_KERNEL); if (NULL == vpbe_dev->encoders) { v4l2_err(&vpbe_dev->v4l2_dev, "unable to allocate memory for encoders sub devices"); -- cgit v1.2.3 From 2ac0989242fbf2f2da7109eab08f68382884a81a Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 11 Oct 2016 04:56:13 -0300 Subject: [media] DaVinci-VPBE: Delete two error messages for a failed memory allocation The script "checkpatch.pl" pointed information out like the following. WARNING: Possible unnecessary 'out of memory' message Thus remove such a logging statement in two functions. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 785d6cf93152..79c2ebe3862a 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -680,8 +680,6 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) sizeof(*vpbe_dev->encoders), GFP_KERNEL); if (NULL == vpbe_dev->encoders) { - v4l2_err(&vpbe_dev->v4l2_dev, - "unable to allocate memory for encoders sub devices"); ret = -ENOMEM; goto fail_dev_unregister; } @@ -837,10 +835,9 @@ static int vpbe_probe(struct platform_device *pdev) } vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL); - if (vpbe_dev == NULL) { - v4l2_err(pdev->dev.driver, "Unable to allocate memory for vpbe_device\n"); + if (!vpbe_dev) return -ENOMEM; - } + vpbe_dev->cfg = cfg; vpbe_dev->ops = vpbe_dev_ops; vpbe_dev->pdev = &pdev->dev; -- cgit v1.2.3 From 135387513d1b0d35baa0433dfa9acc1fb9d97e40 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 11 Oct 2016 08:37:10 -0300 Subject: [media] DaVinci-VPBE: Adjust 16 checks for null pointers The script "checkpatch.pl" pointed information out like the following. Comparison to NULL could be written ... Thus fix the affected source code places. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 79c2ebe3862a..c8c69442c793 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -107,7 +107,7 @@ static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg, static int vpbe_g_cropcap(struct vpbe_device *vpbe_dev, struct v4l2_cropcap *cropcap) { - if (NULL == cropcap) + if (!cropcap) return -EINVAL; cropcap->bounds.left = 0; cropcap->bounds.top = 0; @@ -149,7 +149,7 @@ static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, int curr_output = output_index; int i; - if (NULL == mode) + if (!mode) return -EINVAL; for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) { @@ -166,7 +166,7 @@ static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev, struct vpbe_enc_mode_info *mode_info) { - if (NULL == mode_info) + if (!mode_info) return -EINVAL; *mode_info = vpbe_dev->current_timings; @@ -356,7 +356,7 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev, ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, s_dv_timings, dv_timings); - if (!ret && (vpbe_dev->amp != NULL)) { + if (!ret && vpbe_dev->amp) { /* Call amplifier subdevice */ ret = v4l2_subdev_call(vpbe_dev->amp, video, s_dv_timings, dv_timings); @@ -512,7 +512,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, int ret = 0; int i; - if ((NULL == mode_info) || (NULL == mode_info->name)) + if (!mode_info || !mode_info->name) return -EINVAL; for (i = 0; i < cfg->outputs[out_index].num_modes; i++) { @@ -536,7 +536,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, } /* Only custom timing should reach here */ - if (preset_mode == NULL) + if (!preset_mode) return -EINVAL; mutex_lock(&vpbe_dev->lock); @@ -570,9 +570,9 @@ static int platform_device_get(struct device *dev, void *data) struct platform_device *pdev = to_platform_device(dev); struct vpbe_device *vpbe_dev = data; - if (strstr(pdev->name, "vpbe-osd") != NULL) + if (strstr(pdev->name, "vpbe-osd")) vpbe_dev->osd_device = platform_get_drvdata(pdev); - if (strstr(pdev->name, "vpbe-venc") != NULL) + if (strstr(pdev->name, "vpbe-venc")) vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); return 0; @@ -606,7 +606,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) * from the platform device by iteration of platform drivers and * matching with device name */ - if (NULL == vpbe_dev || NULL == dev) { + if (!vpbe_dev || !dev) { printk(KERN_ERR "Null device pointers.\n"); return -ENODEV; } @@ -652,7 +652,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev, vpbe_dev->cfg->venc.module_name); /* register venc sub device */ - if (vpbe_dev->venc == NULL) { + if (!vpbe_dev->venc) { v4l2_err(&vpbe_dev->v4l2_dev, "vpbe unable to init venc sub device\n"); ret = -ENODEV; @@ -660,8 +660,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) } /* initialize osd device */ osd_device = vpbe_dev->osd_device; - - if (NULL != osd_device->ops.initialize) { + if (osd_device->ops.initialize) { err = osd_device->ops.initialize(osd_device); if (err) { v4l2_err(&vpbe_dev->v4l2_dev, @@ -679,7 +678,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) vpbe_dev->encoders = kmalloc_array(num_encoders, sizeof(*vpbe_dev->encoders), GFP_KERNEL); - if (NULL == vpbe_dev->encoders) { + if (!vpbe_dev->encoders) { ret = -ENOMEM; goto fail_dev_unregister; } @@ -713,7 +712,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) } /* Add amplifier subdevice for dm365 */ if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && - vpbe_dev->cfg->amp != NULL) { + vpbe_dev->cfg->amp) { amp_info = vpbe_dev->cfg->amp; if (amp_info->is_i2c) { vpbe_dev->amp = v4l2_i2c_new_subdev_board( @@ -821,7 +820,7 @@ static int vpbe_probe(struct platform_device *pdev) struct vpbe_config *cfg; int ret = -EINVAL; - if (pdev->dev.platform_data == NULL) { + if (!pdev->dev.platform_data) { v4l2_err(pdev->dev.driver, "No platform data\n"); return -ENODEV; } -- cgit v1.2.3 From 9d2fe9ae298d6144546e168d4b0067b2340ec246 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 11 Oct 2016 08:43:25 -0300 Subject: [media] DaVinci-VPBE: Return an error code only as a constant in vpbe_probe() * Return an error code without storing it in an intermediate variable. * Delete the local variable "ret" which became unnecessary with this refactoring. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index c8c69442c793..3ac4ba35832a 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -818,7 +818,6 @@ static int vpbe_probe(struct platform_device *pdev) { struct vpbe_device *vpbe_dev; struct vpbe_config *cfg; - int ret = -EINVAL; if (!pdev->dev.platform_data) { v4l2_err(pdev->dev.driver, "No platform data\n"); @@ -830,7 +829,7 @@ static int vpbe_probe(struct platform_device *pdev) !cfg->osd.module_name[0] || !cfg->venc.module_name[0]) { v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n"); - return ret; + return -EINVAL; } vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL); -- cgit v1.2.3 From ca7948aa85290f55b8929a8c028352913167bca3 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 04:51:29 -0300 Subject: [media] DaVinci-VPBE: Return the success indication only as a constant in vpbe_set_mode() * Return a success code without storing it in an intermediate variable. * Delete the local variable "ret" which became unnecessary with this refactoring. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 3ac4ba35832a..50b9e3df68b5 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -509,7 +509,6 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, struct v4l2_dv_timings dv_timings; struct osd_state *osd_device; int out_index = vpbe_dev->current_out_index; - int ret = 0; int i; if (!mode_info || !mode_info->name) @@ -549,8 +548,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, vpbe_dev->current_timings.upper_margin); mutex_unlock(&vpbe_dev->lock); - - return ret; + return 0; } static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev) -- cgit v1.2.3 From 837fdcf05af645c3961cae69fd188a0fee1add52 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 04:54:26 -0300 Subject: [media] DaVinci-VPBE: Reduce the scope for a variable in vpbe_set_default_output() * Move the definition for the variable "ret" into an if branch so that an extra initialisation can be avoided at the beginning by this refactoring. * Return a success code as a constant at the end. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 50b9e3df68b5..77b3365b71ef 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -297,19 +297,19 @@ out: static int vpbe_set_default_output(struct vpbe_device *vpbe_dev) { struct vpbe_config *cfg = vpbe_dev->cfg; - int ret = 0; int i; for (i = 0; i < cfg->num_outputs; i++) { if (!strcmp(def_output, cfg->outputs[i].output.name)) { - ret = vpbe_set_output(vpbe_dev, i); + int ret = vpbe_set_output(vpbe_dev, i); + if (!ret) vpbe_dev->current_out_index = i; return ret; } } - return ret; + return 0; } /** -- cgit v1.2.3 From 15a78313b7fd43763aeba584c385f1fb17a1bdb5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:10:19 -0300 Subject: [media] DaVinci-VPBE: Rename a jump label in vpbe_set_output() Adjust jump labels according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 77b3365b71ef..968c2a67468f 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -254,20 +254,20 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) sd_index = vpbe_find_encoder_sd_index(cfg, index); if (sd_index < 0) { ret = -EINVAL; - goto out; + goto unlock; } if_params = cfg->outputs[index].if_params; venc_device->setup_if_config(if_params); if (ret) - goto out; + goto unlock; } /* Set output at the encoder */ ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, s_routing, 0, enc_out_index, 0); if (ret) - goto out; + goto unlock; /* * It is assumed that venc or extenal encoder will set a default @@ -289,7 +289,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) vpbe_dev->current_sd_index = sd_index; vpbe_dev->current_out_index = index; } -out: +unlock: mutex_unlock(&vpbe_dev->lock); return ret; } -- cgit v1.2.3 From 630bf79a455bbb5fd13e7721280cd149860bcd56 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:16:23 -0300 Subject: [media] DaVinci-VPBE: Delete an unnecessary variable initialisation in vpbe_set_output() The local variable "ret" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 968c2a67468f..7dcdb7f4b323 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -230,7 +230,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) u32 if_params; int enc_out_index; int sd_index; - int ret = 0; + int ret; if (index >= cfg->num_outputs) return -EINVAL; -- cgit v1.2.3 From ed011a23c90796c386ae7004ef0823ade6583d21 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:20:02 -0300 Subject: [media] DaVinci-VPFE-Capture: Use kmalloc_array() in vpfe_probe() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kmalloc_array". This issue was detected by using the Coccinelle software. * Replace the specification of a data type by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index ca22c3493f55..a9bc35e785a3 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1938,8 +1938,9 @@ static int vpfe_probe(struct platform_device *pdev) video_set_drvdata(&vpfe_dev->video_dev, vpfe_dev); i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); num_subdevs = vpfe_cfg->num_subdevs; - vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, - GFP_KERNEL); + vpfe_dev->sd = kmalloc_array(num_subdevs, + sizeof(*vpfe_dev->sd), + GFP_KERNEL); if (NULL == vpfe_dev->sd) { v4l2_err(&vpfe_dev->v4l2_dev, "unable to allocate memory for subdevice pointers\n"); -- cgit v1.2.3 From 11691f0e8aaef776320938c9018f5785d09f59c5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:22:47 -0300 Subject: [media] DaVinci-VPFE-Capture: Delete three error messages for a failed memory allocation The script "checkpatch.pl" pointed information out like the following. WARNING: Possible unnecessary 'out of memory' message Thus remove such a logging statement in two functions. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index a9bc35e785a3..22f48342584b 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -512,11 +512,9 @@ static int vpfe_open(struct file *file) /* Allocate memory for the file handle object */ fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL); - if (NULL == fh) { - v4l2_err(&vpfe_dev->v4l2_dev, - "unable to allocate memory for file handle object\n"); + if (!fh) return -ENOMEM; - } + /* store pointer to fh in private_data member of file */ file->private_data = fh; fh->vpfe_dev = vpfe_dev; @@ -1851,11 +1849,8 @@ static int vpfe_probe(struct platform_device *pdev) /* Allocate memory for ccdc configuration */ ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); - if (NULL == ccdc_cfg) { - v4l2_err(pdev->dev.driver, - "Memory allocation failed for ccdc_cfg\n"); + if (!ccdc_cfg) goto probe_free_dev_mem; - } mutex_lock(&ccdc_lock); @@ -1942,8 +1937,6 @@ static int vpfe_probe(struct platform_device *pdev) sizeof(*vpfe_dev->sd), GFP_KERNEL); if (NULL == vpfe_dev->sd) { - v4l2_err(&vpfe_dev->v4l2_dev, - "unable to allocate memory for subdevice pointers\n"); ret = -ENOMEM; goto probe_out_video_unregister; } -- cgit v1.2.3 From e4c0cd0ae34b5e8ea3e8f4eced531dccabe3124c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:24:57 -0300 Subject: [media] DaVinci-VPFE-Capture: Improve another size determination in vpfe_probe() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 22f48342584b..9109a286a869 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1848,7 +1848,7 @@ static int vpfe_probe(struct platform_device *pdev) } /* Allocate memory for ccdc configuration */ - ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); + ccdc_cfg = kmalloc(sizeof(*ccdc_cfg), GFP_KERNEL); if (!ccdc_cfg) goto probe_free_dev_mem; -- cgit v1.2.3 From efb74461f5a66c0004d0c13ef59c86bcf5961477 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:30:28 -0300 Subject: [media] DaVinci-VPFE-Capture: Delete an unnecessary variable initialisation in vpfe_probe() * Return an error code as a constant after a failed call of the function "vpfe_initialize". * The local variable "ret" will be set then to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 9109a286a869..cee14aa95061 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1817,7 +1817,7 @@ static int vpfe_probe(struct platform_device *pdev) struct vpfe_device *vpfe_dev; struct i2c_adapter *i2c_adap; struct video_device *vfd; - int ret = -ENOMEM, i, j; + int ret, i, j; int num_subdevs = 0; /* Get the pointer to the device object */ @@ -1826,7 +1826,7 @@ static int vpfe_probe(struct platform_device *pdev) if (!vpfe_dev) { v4l2_err(pdev->dev.driver, "Failed to allocate memory for vpfe_dev\n"); - return ret; + return -ENOMEM; } vpfe_dev->pdev = &pdev->dev; -- cgit v1.2.3 From 1d3811d35c0fc8d8c6cb3d8e666261ca84687b03 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:44:05 -0300 Subject: [media] DaVinci-VPFE-Capture: Improve another size determination in vpfe_open() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index cee14aa95061..ab073f273b95 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -511,7 +511,7 @@ static int vpfe_open(struct file *file) } /* Allocate memory for the file handle object */ - fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL); + fh = kmalloc(sizeof(*fh), GFP_KERNEL); if (!fh) return -ENOMEM; -- cgit v1.2.3 From c580f295663ea22b49edeefbdcdf2e67ce9ef91f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:46:28 -0300 Subject: [media] DaVinci-VPFE-Capture: Adjust 13 checks for null pointers Convert comparisons with the preprocessor symbol "NULL" to condition checks without it. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index ab073f273b95..71f1ac1adec0 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -229,7 +229,7 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev) BUG_ON(!dev->hw_ops.getfid); mutex_lock(&ccdc_lock); - if (NULL == ccdc_cfg) { + if (!ccdc_cfg) { /* * TODO. Will this ever happen? if so, we need to fix it. * Proabably we need to add the request to a linked list and @@ -265,7 +265,7 @@ EXPORT_SYMBOL(vpfe_register_ccdc_device); */ void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) { - if (NULL == dev) { + if (!dev) { printk(KERN_ERR "invalid ccdc device ptr\n"); return; } @@ -469,7 +469,7 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe_dev) /* now open the ccdc device to initialize it */ mutex_lock(&ccdc_lock); - if (NULL == ccdc_dev) { + if (!ccdc_dev) { v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n"); ret = -ENODEV; goto unlock; @@ -582,7 +582,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id) goto clear_intr; /* only for 6446 this will be applicable */ - if (NULL != ccdc_dev->hw_ops.reset) + if (ccdc_dev->hw_ops.reset) ccdc_dev->hw_ops.reset(); if (field == V4L2_FIELD_NONE) { @@ -822,7 +822,7 @@ static const struct vpfe_pixel_format * int temp, found; vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); - if (NULL == vpfe_pix_fmt) { + if (!vpfe_pix_fmt) { /* * use current pixel format in the vpfe device. We * will find this pix format in the table @@ -964,7 +964,7 @@ static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, /* Fill in the information about format */ pix_fmt = vpfe_lookup_pix_format(pix); - if (NULL != pix_fmt) { + if (pix_fmt) { temp_index = fmt->index; *fmt = pix_fmt->fmtdesc; fmt->index = temp_index; @@ -990,8 +990,7 @@ static int vpfe_s_fmt_vid_cap(struct file *file, void *priv, /* Check for valid frame format */ pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix); - - if (NULL == pix_fmts) + if (!pix_fmts) return -EINVAL; /* store the pixel format in the device object */ @@ -1017,7 +1016,7 @@ static int vpfe_try_fmt_vid_cap(struct file *file, void *priv, v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n"); pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix); - if (NULL == pix_fmts) + if (!pix_fmts) return -EINVAL; return 0; } @@ -1831,7 +1830,7 @@ static int vpfe_probe(struct platform_device *pdev) vpfe_dev->pdev = &pdev->dev; - if (NULL == pdev->dev.platform_data) { + if (!pdev->dev.platform_data) { v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); ret = -ENODEV; goto probe_free_dev_mem; @@ -1839,9 +1838,7 @@ static int vpfe_probe(struct platform_device *pdev) vpfe_cfg = pdev->dev.platform_data; vpfe_dev->cfg = vpfe_cfg; - if (NULL == vpfe_cfg->ccdc || - NULL == vpfe_cfg->card_name || - NULL == vpfe_cfg->sub_devs) { + if (!vpfe_cfg->ccdc || !vpfe_cfg->card_name || !vpfe_cfg->sub_devs) { v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n"); ret = -ENOENT; goto probe_free_dev_mem; @@ -1936,7 +1933,7 @@ static int vpfe_probe(struct platform_device *pdev) vpfe_dev->sd = kmalloc_array(num_subdevs, sizeof(*vpfe_dev->sd), GFP_KERNEL); - if (NULL == vpfe_dev->sd) { + if (!vpfe_dev->sd) { ret = -ENOMEM; goto probe_out_video_unregister; } -- cgit v1.2.3 From 2a0de2c84288fdf9381f6e2a85c0c6825221851e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 05:50:54 -0300 Subject: [media] DaVinci-VPFE-Capture: Delete an unnecessary variable initialisation in 11 functions The local variable "ret" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 71f1ac1adec0..ca044bf1c05c 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -384,7 +384,7 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, }; struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format; struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix; - int i, ret = 0; + int i, ret; for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) { if (vpfe_standards[i].std_id & std_id) { @@ -453,7 +453,7 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, static int vpfe_initialize_device(struct vpfe_device *vpfe_dev) { - int ret = 0; + int ret; /* set first input of current subdevice as the current input */ vpfe_dev->current_input = 0; @@ -978,7 +978,7 @@ static int vpfe_s_fmt_vid_cap(struct file *file, void *priv, { struct vpfe_device *vpfe_dev = video_drvdata(file); const struct vpfe_pixel_format *pix_fmts; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n"); @@ -1110,7 +1110,7 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) int subdev_index, inp_index; struct vpfe_route *route; u32 input = 0, output = 0; - int ret = -EINVAL; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); @@ -1176,7 +1176,7 @@ static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id) { struct vpfe_device *vpfe_dev = video_drvdata(file); struct vpfe_subdev_info *sdinfo; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n"); @@ -1195,7 +1195,7 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) { struct vpfe_device *vpfe_dev = video_drvdata(file); struct vpfe_subdev_info *sdinfo; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); @@ -1344,7 +1344,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, { struct vpfe_device *vpfe_dev = video_drvdata(file); struct vpfe_fh *fh = file->private_data; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n"); @@ -1476,7 +1476,7 @@ static int vpfe_streamon(struct file *file, void *priv, struct vpfe_fh *fh = file->private_data; struct vpfe_subdev_info *sdinfo; unsigned long addr; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n"); @@ -1559,7 +1559,7 @@ static int vpfe_streamoff(struct file *file, void *priv, struct vpfe_device *vpfe_dev = video_drvdata(file); struct vpfe_fh *fh = file->private_data; struct vpfe_subdev_info *sdinfo; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n"); @@ -1645,7 +1645,7 @@ static int vpfe_s_selection(struct file *file, void *priv, { struct vpfe_device *vpfe_dev = video_drvdata(file); struct v4l2_rect rect = sel->r; - int ret = 0; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_selection\n"); @@ -1703,7 +1703,7 @@ static long vpfe_param_handler(struct file *file, void *priv, bool valid_prio, unsigned int cmd, void *param) { struct vpfe_device *vpfe_dev = video_drvdata(file); - int ret = 0; + int ret; v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n"); -- cgit v1.2.3 From 19d4695a4fbde30881ad9005e7f46e569b1fc911 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 06:22:23 -0300 Subject: [media] DaVinci-VPFE-Capture: Move two assignments in vpfe_s_input() Move assignments for two local variables into an else branch so that their setting will only be performed after corresponding data processing succeeded by this function. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index ca044bf1c05c..86509d2f274a 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1109,7 +1109,7 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) struct vpfe_subdev_info *sdinfo; int subdev_index, inp_index; struct vpfe_route *route; - u32 input = 0, output = 0; + u32 input, output; int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); @@ -1142,6 +1142,9 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) if (route && sdinfo->can_route) { input = route->input; output = route->output; + } else { + input = 0; + output = 0; } if (sd) -- cgit v1.2.3 From b899065640fc0c8b02d762bd5869c0afd3120c64 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 09:54:21 -0300 Subject: [media] DaVinci-VPFE-Capture: Delete unnecessary braces in vpfe_isr() Do not use curly brackets at one source code place where a single statement should be sufficient. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 86509d2f274a..1acca83426ea 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -615,9 +615,8 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id) * interleavely or separately in memory, reconfigure * the CCDC memory address */ - if (field == V4L2_FIELD_SEQ_TB) { + if (field == V4L2_FIELD_SEQ_TB) vpfe_schedule_bottom_field(vpfe_dev); - } goto clear_intr; } /* -- cgit v1.2.3 From 96ca88423605116c041b5e5a6ef3af685402afb1 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:10:54 -0300 Subject: [media] DaVinci-VPFE-Capture: Delete an unnecessary return statement in vpfe_unregister_ccdc_device() The script "checkpatch.pl" pointed information out like the following. WARNING: void function return statements are not generally useful Thus remove such a statement here. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 1acca83426ea..71caebf125f1 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -281,7 +281,6 @@ void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) mutex_lock(&ccdc_lock); ccdc_dev = NULL; mutex_unlock(&ccdc_lock); - return; } EXPORT_SYMBOL(vpfe_unregister_ccdc_device); -- cgit v1.2.3 From b442c46f1b10f5e91025e36824362839ea3f3331 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:15:34 -0300 Subject: [media] DaVinci-VPIF-Capture: Use kcalloc() in vpif_probe() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kcalloc". This issue was detected by using the Coccinelle software. * Replace the specification of a data type by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index c6a3a904afc8..8a7d46210a44 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1459,8 +1459,7 @@ static __init int vpif_probe(struct platform_device *pdev) vpif_obj.config = pdev->dev.platform_data; subdev_count = vpif_obj.config->subdev_count; - vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, - GFP_KERNEL); + vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); if (vpif_obj.sd == NULL) { vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; -- cgit v1.2.3 From bc285799f7e8c61eaacdd73aa8644b1eaf504bb4 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:18:45 -0300 Subject: [media] DaVinci-VPIF-Capture: Delete an error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 8a7d46210a44..515384b25ea1 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1461,7 +1461,6 @@ static __init int vpif_probe(struct platform_device *pdev) subdev_count = vpif_obj.config->subdev_count; vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); if (vpif_obj.sd == NULL) { - vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; goto vpif_unregister; } -- cgit v1.2.3 From 03161cdb69ef98434a2c8e85234aae7975ca4501 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:20:34 -0300 Subject: [media] DaVinci-VPIF-Capture: Adjust ten checks for null pointers The script "checkpatch.pl" pointed information out like the following. Comparison to NULL could be written ... Thus fix the affected source code places. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 515384b25ea1..0c44e2b84434 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -291,10 +291,10 @@ static void vpif_stop_streaming(struct vb2_queue *vq) vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } else { - if (common->cur_frm != NULL) + if (common->cur_frm) vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); - if (common->next_frm != NULL) + if (common->next_frm) vb2_buffer_done(&common->next_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } @@ -648,7 +648,7 @@ static int vpif_input_to_subdev( vpif_dbg(2, debug, "vpif_input_to_subdev\n"); subdev_name = chan_cfg->inputs[input_index].subdev_name; - if (subdev_name == NULL) + if (!subdev_name) return -1; /* loop through the sub device list to get the sub device info */ @@ -764,7 +764,7 @@ static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) vpif_dbg(2, debug, "vpif_g_std\n"); - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -794,7 +794,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) vpif_dbg(2, debug, "vpif_s_std\n"); - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1050,7 +1050,7 @@ vpif_enum_dv_timings(struct file *file, void *priv, struct v4l2_input input; int ret; - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1084,7 +1084,7 @@ vpif_query_dv_timings(struct file *file, void *priv, struct v4l2_input input; int ret; - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1120,7 +1120,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, struct v4l2_input input; int ret; - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1213,7 +1213,7 @@ static int vpif_g_dv_timings(struct file *file, void *priv, struct vpif_capture_chan_config *chan_cfg; struct v4l2_input input; - if (config->chan_config[ch->channel_id].inputs == NULL) + if (!config->chan_config[ch->channel_id].inputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1460,7 +1460,7 @@ static __init int vpif_probe(struct platform_device *pdev) subdev_count = vpif_obj.config->subdev_count; vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); - if (vpif_obj.sd == NULL) { + if (!vpif_obj.sd) { err = -ENOMEM; goto vpif_unregister; } -- cgit v1.2.3 From 6a842cc29dbfd311a289bb7f34865828e951791d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:22:45 -0300 Subject: [media] DaVinci-VPIF-Capture: Delete an unnecessary variable initialisation in vpif_querystd() The local variable "ret" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 0c44e2b84434..77f67a05d047 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -731,7 +731,7 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id) { struct video_device *vdev = video_devdata(file); struct channel_obj *ch = video_get_drvdata(vdev); - int ret = 0; + int ret; vpif_dbg(2, debug, "vpif_querystd\n"); -- cgit v1.2.3 From c64d61df9a5d67e50ed347287d80a4b75e9d660d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:25:08 -0300 Subject: [media] DaVinci-VPIF-Capture: Delete an unnecessary variable initialisation in vpif_channel_isr() The local variable "channel_id" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 77f67a05d047..f791f5c402bf 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -375,7 +375,7 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) struct vpif_device *dev = &vpif_obj; struct common_obj *common; struct channel_obj *ch; - int channel_id = 0; + int channel_id; int fid = -1, i; channel_id = *(int *)(dev_id); -- cgit v1.2.3 From d5cf467ecec5a3924a602018c6e405ad6d0dbecc Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:30:44 -0300 Subject: [media] DaVinci-VPIF-Display: Use kcalloc() in vpif_probe() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kcalloc". This issue was detected by using the Coccinelle software. * Replace the specification of a data type by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 6b3ea1e8e97f..0faab86db9a1 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1274,8 +1274,7 @@ static __init int vpif_probe(struct platform_device *pdev) vpif_obj.config = pdev->dev.platform_data; subdev_count = vpif_obj.config->subdev_count; subdevdata = vpif_obj.config->subdevinfo; - vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, - GFP_KERNEL); + vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); if (vpif_obj.sd == NULL) { vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; -- cgit v1.2.3 From ded1c8fa7563614bac9c3e69b0dec8238032725c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:38:41 -0300 Subject: [media] DaVinci-VPIF-Display: Delete an error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 0faab86db9a1..987c17d3825d 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1276,7 +1276,6 @@ static __init int vpif_probe(struct platform_device *pdev) subdevdata = vpif_obj.config->subdevinfo; vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); if (vpif_obj.sd == NULL) { - vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; goto vpif_unregister; } -- cgit v1.2.3 From 396c88e6c80cc30d4ef8dc927aae1b15f251a217 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:40:32 -0300 Subject: [media] DaVinci-VPIF-Display: Adjust 11 checks for null pointers The script "checkpatch.pl" pointed information out like the following. Comparison to NULL could be written... Thus fix the affected source code places. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 987c17d3825d..867bf5c63cb6 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -271,10 +271,10 @@ static void vpif_stop_streaming(struct vb2_queue *vq) vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } else { - if (common->cur_frm != NULL) + if (common->cur_frm) vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); - if (common->next_frm != NULL) + if (common->next_frm) vb2_buffer_done(&common->next_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } @@ -686,7 +686,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) struct v4l2_output output; int ret; - if (config->chan_config[ch->channel_id].outputs == NULL) + if (!config->chan_config[ch->channel_id].outputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -732,7 +732,7 @@ static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) struct vpif_display_chan_config *chan_cfg; struct v4l2_output output; - if (config->chan_config[ch->channel_id].outputs == NULL) + if (!config->chan_config[ch->channel_id].outputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -783,11 +783,11 @@ vpif_output_to_subdev(struct vpif_display_config *vpif_cfg, vpif_dbg(2, debug, "vpif_output_to_subdev\n"); - if (chan_cfg->outputs == NULL) + if (!chan_cfg->outputs) return -1; subdev_name = chan_cfg->outputs[index].subdev_name; - if (subdev_name == NULL) + if (!subdev_name) return -1; /* loop through the sub device list to get the sub device info */ @@ -833,7 +833,7 @@ static int vpif_set_output(struct vpif_display_config *vpif_cfg, } ch->output_idx = index; ch->sd = sd; - if (chan_cfg->outputs != NULL) + if (chan_cfg->outputs) /* update tvnorms from the sub device output info */ ch->video_dev.tvnorms = chan_cfg->outputs[index].output.std; return 0; @@ -885,7 +885,7 @@ vpif_enum_dv_timings(struct file *file, void *priv, struct v4l2_output output; int ret; - if (config->chan_config[ch->channel_id].outputs == NULL) + if (!config->chan_config[ch->channel_id].outputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -922,7 +922,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv, struct v4l2_output output; int ret; - if (config->chan_config[ch->channel_id].outputs == NULL) + if (!config->chan_config[ch->channel_id].outputs) return -ENODATA; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1016,7 +1016,7 @@ static int vpif_g_dv_timings(struct file *file, void *priv, struct video_obj *vid_ch = &ch->video; struct v4l2_output output; - if (config->chan_config[ch->channel_id].outputs == NULL) + if (!config->chan_config[ch->channel_id].outputs) goto error; chan_cfg = &config->chan_config[ch->channel_id]; @@ -1275,7 +1275,7 @@ static __init int vpif_probe(struct platform_device *pdev) subdev_count = vpif_obj.config->subdev_count; subdevdata = vpif_obj.config->subdevinfo; vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); - if (vpif_obj.sd == NULL) { + if (!vpif_obj.sd) { err = -ENOMEM; goto vpif_unregister; } -- cgit v1.2.3 From 3ce5f660147039f880949d339c578e5af553876f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:43:12 -0300 Subject: [media] DaVinci-VPIF-Display: Delete an unnecessary variable initialisation in vpif_channel_isr() The local variable "channel_id" will be reassigned with the following statement at the beginning. Thus omit the explicit initialisation. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 867bf5c63cb6..3bf68aace5af 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -363,7 +363,7 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) struct channel_obj *ch; struct common_obj *common; int fid = -1, i; - int channel_id = 0; + int channel_id; channel_id = *(int *)(dev_id); if (!vpif_intr_status(channel_id + 2)) -- cgit v1.2.3 From ea0e437cf9443ae58e38bff1242ff0c80d0c4efb Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 12 Oct 2016 10:45:03 -0300 Subject: [media] DaVinci-VPIF-Display: Delete an unnecessary variable initialisation in process_progressive_mode() The local variable "addr" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 3bf68aace5af..e5f18448dbf7 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -301,7 +301,7 @@ static struct vb2_ops video_qops = { static void process_progressive_mode(struct common_obj *common) { - unsigned long addr = 0; + unsigned long addr; spin_lock(&common->irqlock); /* Get the next buffer from buffer queue */ -- cgit v1.2.3 From eadf081146ec327d6fbbb6aff28e3d9aac329dc6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 13 Oct 2016 11:39:04 -0300 Subject: [media] s5p-cec: mark PM functions as __maybe_unused again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bugfix removed the two callers of s5p_cec_runtime_suspend and s5p_cec_runtime_resume, leading to the return of a harmless warning that I had previously fixed in commit aee8937089b1 ("[media] s5p_cec: mark suspend/resume as __maybe_unused"): staging/media/s5p-cec/s5p_cec.c:234:12: error: ‘s5p_cec_runtime_suspend’ defined but not used [-Werror=unused-function] staging/media/s5p-cec/s5p_cec.c:242:12: error: ‘s5p_cec_runtime_resume’ defined but not used [-Werror=unused-function] This adds the __maybe_unused annotations to the function that were not removed and that are now unused when CONFIG_PM is disabled. Fixes: 57b978ada073 ("[media] s5p-cec: fix system and runtime PM integration") Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/s5p-cec/s5p_cec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 1780a08b73c9..58d756231136 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -231,7 +231,7 @@ static int s5p_cec_remove(struct platform_device *pdev) return 0; } -static int s5p_cec_runtime_suspend(struct device *dev) +static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev) { struct s5p_cec_dev *cec = dev_get_drvdata(dev); @@ -239,7 +239,7 @@ static int s5p_cec_runtime_suspend(struct device *dev) return 0; } -static int s5p_cec_runtime_resume(struct device *dev) +static int __maybe_unused s5p_cec_runtime_resume(struct device *dev) { struct s5p_cec_dev *cec = dev_get_drvdata(dev); int ret; -- cgit v1.2.3 From 6b2bed891253c08e7f4c17dbd46b71fc87f22eef Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Oct 2016 04:32:24 -0300 Subject: [media] st-hva: fix some error handling in hva_hw_probe() The devm_ioremap_resource() returns error pointers, never NULL. The platform_get_resource() returns NULL on error, never error pointers. The error code needs to be set, as well. The current code returns PTR_ERR(NULL) which is success. Fixes: 57b2c0628b60 ("[media] st-hva: multi-format video encoder V4L2 driver") Signed-off-by: Dan Carpenter Acked-by: Jean-Christophe Trotin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/hva/hva-hw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index d341d4994528..cf2a8d884536 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -305,16 +305,16 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva) /* get memory for registers */ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); hva->regs = devm_ioremap_resource(dev, regs); - if (IS_ERR_OR_NULL(hva->regs)) { + if (IS_ERR(hva->regs)) { dev_err(dev, "%s failed to get regs\n", HVA_PREFIX); return PTR_ERR(hva->regs); } /* get memory for esram */ esram = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (IS_ERR_OR_NULL(esram)) { + if (!esram) { dev_err(dev, "%s failed to get esram\n", HVA_PREFIX); - return PTR_ERR(esram); + return -ENODEV; } hva->esram_addr = esram->start; hva->esram_size = resource_size(esram); -- cgit v1.2.3 From c53a846c48f21c909102677c127ece94b1247668 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sun, 16 Oct 2016 07:38:22 -0200 Subject: [media] usbtv: add video controls Brightness, Contrast, Hue and Color Saturation are supported. Signed-off-by: Lubomir Rintel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbtv/usbtv-video.c | 97 ++++++++++++++++++++++++++++++++++- drivers/media/usb/usbtv/usbtv.h | 3 ++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 6cbe4a245c9f..86ffbf8780f2 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Lubomir Rintel + * Copyright (c) 2013,2016 Lubomir Rintel * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -259,6 +259,10 @@ static int usbtv_setup_capture(struct usbtv *usbtv) if (ret) return ret; + ret = v4l2_ctrl_handler_setup(&usbtv->ctrl); + if (ret) + return ret; + return 0; } @@ -696,11 +700,83 @@ static const struct vb2_ops usbtv_vb2_ops = { .stop_streaming = usbtv_stop_streaming, }; +static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct usbtv *usbtv = container_of(ctrl->handler, struct usbtv, + ctrl); + u8 data[3]; + u16 index, size; + int ret; + + /* + * Read in the current brightness/contrast registers. We need them + * both, because the values are for some reason interleaved. + */ + if (ctrl->id == V4L2_CID_BRIGHTNESS || ctrl->id == V4L2_CID_CONTRAST) { + ret = usb_control_msg(usbtv->udev, + usb_sndctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, USBTV_BASE + 0x0244, (void *)data, 3, 0); + } + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + index = USBTV_BASE + 0x0244; + size = 3; + data[0] &= 0xf0; + data[0] |= (ctrl->val >> 8) & 0xf; + data[2] = ctrl->val & 0xff; + break; + case V4L2_CID_CONTRAST: + index = USBTV_BASE + 0x0244; + size = 3; + data[0] &= 0x0f; + data[0] |= (ctrl->val >> 4) & 0xf0; + data[1] = ctrl->val & 0xff; + break; + case V4L2_CID_SATURATION: + index = USBTV_BASE + 0x0242; + data[0] = ctrl->val >> 8; + data[1] = ctrl->val & 0xff; + size = 2; + break; + case V4L2_CID_HUE: + index = USBTV_BASE + 0x0240; + size = 2; + if (ctrl->val > 0) { + data[0] = 0x92 + (ctrl->val >> 8); + data[1] = ctrl->val & 0xff; + } else { + data[0] = 0x82 + (-ctrl->val >> 8); + data[1] = -ctrl->val & 0xff; + } + break; + default: + return -EINVAL; + } + + ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0), + USBTV_CONTROL_REG, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, (void *)data, size, 0); + if (ret < 0) { + dev_warn(usbtv->dev, "Failed to submit a control request.\n"); + return ret; + } + + return 0; +} + +static const struct v4l2_ctrl_ops usbtv_ctrl_ops = { + .s_ctrl = usbtv_s_ctrl, +}; + static void usbtv_release(struct v4l2_device *v4l2_dev) { struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev); v4l2_device_unregister(&usbtv->v4l2_dev); + v4l2_ctrl_handler_free(&usbtv->ctrl); vb2_queue_release(&usbtv->vb2q); kfree(usbtv); } @@ -731,7 +807,24 @@ int usbtv_video_init(struct usbtv *usbtv) return ret; } + /* controls */ + v4l2_ctrl_handler_init(&usbtv->ctrl, 4); + v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops, + V4L2_CID_CONTRAST, 0, 0x3ff, 1, 0x1d0); + v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 0x3ff, 1, 0x1c0); + v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops, + V4L2_CID_SATURATION, 0, 0x3ff, 1, 0x200); + v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops, + V4L2_CID_HUE, -0xdff, 0xdff, 1, 0x000); + ret = usbtv->ctrl.error; + if (ret < 0) { + dev_warn(usbtv->dev, "Could not initialize controls\n"); + goto ctrl_fail; + } + /* v4l2 structure */ + usbtv->v4l2_dev.ctrl_handler = &usbtv->ctrl; usbtv->v4l2_dev.release = usbtv_release; ret = v4l2_device_register(usbtv->dev, &usbtv->v4l2_dev); if (ret < 0) { @@ -760,6 +853,8 @@ int usbtv_video_init(struct usbtv *usbtv) vdev_fail: v4l2_device_unregister(&usbtv->v4l2_dev); v4l2_fail: +ctrl_fail: + v4l2_ctrl_handler_free(&usbtv->ctrl); vb2_queue_release(&usbtv->vb2q); return ret; diff --git a/drivers/media/usb/usbtv/usbtv.h b/drivers/media/usb/usbtv/usbtv.h index 011f9fdc77a9..0231e449877e 100644 --- a/drivers/media/usb/usbtv/usbtv.h +++ b/drivers/media/usb/usbtv/usbtv.h @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -45,6 +46,7 @@ #define USBTV_VIDEO_ENDP 0x81 #define USBTV_AUDIO_ENDP 0x83 #define USBTV_BASE 0xc000 +#define USBTV_CONTROL_REG 11 #define USBTV_REQUEST_REG 12 /* Number of concurrent isochronous urbs submitted. @@ -87,6 +89,7 @@ struct usbtv { /* video */ struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler ctrl; struct video_device vdev; struct vb2_queue vb2q; struct mutex v4l2_lock; -- cgit v1.2.3 From 62de7d99dcfe5ceff0c40d27a819a2256c8dfc73 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 13:13:02 -0200 Subject: [media] usbtv: don't do DMA on stack As reported by smatch: drivers/media/usb/usbtv/usbtv-video.c:716 usbtv_s_ctrl() error: doing dma on the stack (data) drivers/media/usb/usbtv/usbtv-video.c:758 usbtv_s_ctrl() error: doing dma on the stack (data) We should not do it, as it won't work on Kernels 4.9 and upper. So, alloc a buffer for it. Fixes: c53a846c48f2 ("[media] usbtv: add video controls") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbtv/usbtv-video.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 86ffbf8780f2..d3b6d3dfaa09 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -704,10 +704,14 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) { struct usbtv *usbtv = container_of(ctrl->handler, struct usbtv, ctrl); - u8 data[3]; + u8 *data; u16 index, size; int ret; + data = kmalloc(3, GFP_KERNEL); + if (!data) + return -ENOMEM; + /* * Read in the current brightness/contrast registers. We need them * both, because the values are for some reason interleaved. @@ -717,6 +721,8 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) usb_sndctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, USBTV_BASE + 0x0244, (void *)data, 3, 0); + if (ret < 0) + goto error; } switch (ctrl->id) { @@ -752,6 +758,7 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) } break; default: + kfree(data); return -EINVAL; } @@ -759,12 +766,13 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) USBTV_CONTROL_REG, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, (void *)data, size, 0); - if (ret < 0) { + +error: + if (ret < 0) dev_warn(usbtv->dev, "Failed to submit a control request.\n"); - return ret; - } - return 0; + kfree(data); + return ret; } static const struct v4l2_ctrl_ops usbtv_ctrl_ops = { -- cgit v1.2.3 From 3184c3bf67d1360a303dd02edccab41e37a637bd Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 17 Oct 2016 13:44:08 -0200 Subject: [media] v4l: vsp1: Fix module autoload for OF registration If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/media/platform/vsp1/vsp1.ko | grep alias alias: vsp1 After this patch: $ modinfo drivers/media/platform/vsp1/vsp1.ko | grep alias alias: vsp1 alias: of:N*T*Crenesas,vsp2C* alias: of:N*T*Crenesas,vsp2 alias: of:N*T*Crenesas,vsp1C* alias: of:N*T*Crenesas,vsp1 Signed-off-by: Javier Martinez Canillas Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 57c713a4e1df..aa237b48ad55 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -770,6 +770,7 @@ static const struct of_device_id vsp1_of_match[] = { { .compatible = "renesas,vsp2" }, { }, }; +MODULE_DEVICE_TABLE(of, vsp1_of_match); static struct platform_driver vsp1_platform_driver = { .probe = vsp1_probe, -- cgit v1.2.3 From d6023d33a4ac9bc53975c9029a59135d71a76268 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 17 Oct 2016 13:44:09 -0200 Subject: [media] v4l: rcar-fcp: Fix module autoload for OF registration If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/media/platform/rcar-fcp.ko | grep alias alias: rcar-fcp After this patch: $ modinfo drivers/media/platform/rcar-fcp.ko | grep alias alias: rcar-fcp alias: of:N*T*Crenesas,fcpvC* alias: of:N*T*Crenesas,fcpv alias: of:N*T*Crenesas,fcpfC* alias: of:N*T*Crenesas,fcpf Signed-off-by: Javier Martinez Canillas Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-fcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c index f3a3f31cdfa9..7146fc5ef168 100644 --- a/drivers/media/platform/rcar-fcp.c +++ b/drivers/media/platform/rcar-fcp.c @@ -169,6 +169,7 @@ static const struct of_device_id rcar_fcp_of_match[] = { { .compatible = "renesas,fcpv" }, { }, }; +MODULE_DEVICE_TABLE(of, rcar_fcp_of_match); static struct platform_driver rcar_fcp_platform_driver = { .probe = rcar_fcp_probe, -- cgit v1.2.3 From 5bb50fe731fbb681bc5459e0d39b5bdbd950c33b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 17 Oct 2016 13:44:10 -0200 Subject: [media] rc: meson-ir: Fix module autoload If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/media/rc/meson-ir.ko | grep alias $ After this patch: $ modinfo drivers/media/rc/meson-ir.ko | grep alias alias: of:N*T*Camlogic,meson-gxbb-irC* alias: of:N*T*Camlogic,meson-gxbb-ir alias: of:N*T*Camlogic,meson8b-irC* alias: of:N*T*Camlogic,meson8b-ir alias: of:N*T*Camlogic,meson6-irC* alias: of:N*T*Camlogic,meson6-ir Signed-off-by: Javier Martinez Canillas Acked-by: Kevin Hilman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/meson-ir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 003fff07ade2..7eb3f4f1ddcd 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -218,6 +218,7 @@ static const struct of_device_id meson_ir_match[] = { { .compatible = "amlogic,meson-gxbb-ir" }, { }, }; +MODULE_DEVICE_TABLE(of, meson_ir_match); static struct platform_driver meson_ir_driver = { .probe = meson_ir_probe, -- cgit v1.2.3 From 0dc5fb0a0b378c2b1ad98021d385441ec24a015d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 17 Oct 2016 13:44:11 -0200 Subject: [media] s5p-cec: Fix module autoload If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/staging/media/s5p-cec/s5p-cec.ko | grep alias $ After this patch: $ modinfo drivers/staging/media/s5p-cec/s5p-cec.ko | grep alias alias: of:N*T*Csamsung,s5p-cecC* alias: of:N*T*Csamsung,s5p-cec Signed-off-by: Javier Martinez Canillas Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/s5p-cec/s5p_cec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 58d756231136..097e20298886 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -263,6 +263,7 @@ static const struct of_device_id s5p_cec_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, s5p_cec_match); static struct platform_driver s5p_cec_pdrv = { .probe = s5p_cec_probe, -- cgit v1.2.3 From 2411434a2b78b38f70b3447d46b9c7db4f20fe54 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 17 Oct 2016 13:44:12 -0200 Subject: [media] st-cec: Fix module autoload If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/staging/media//st-cec/stih-cec.ko | grep alias $ After this patch: $ modinfo drivers/staging/media//st-cec/stih-cec.ko | grep alias alias: of:N*T*Cst,stih-cecC* alias: of:N*T*Cst,stih-cec Signed-off-by: Javier Martinez Canillas Acked-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/st-cec/stih-cec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c index b0aee1d4d5d0..1f1542e8154f 100644 --- a/drivers/staging/media/st-cec/stih-cec.c +++ b/drivers/staging/media/st-cec/stih-cec.c @@ -362,6 +362,7 @@ static const struct of_device_id stih_cec_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, stih_cec_match); static struct platform_driver stih_cec_pdrv = { .probe = stih_cec_probe, -- cgit v1.2.3 From 84512f3e1c5439dbd79f82ef6b24294a6c3e53a3 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 22 Oct 2016 05:26:37 -0200 Subject: [media] v4l: doc: Fix typo in vidioc-g-tuner.rst This patch fix spelling typos found in vidioc-g-tuner.rst Signed-off-by: Masanari Iida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/vidioc-g-tuner.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst index e8aa8cd7065f..57c79fa43866 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst @@ -201,10 +201,10 @@ To change the radio frequency the * - ``V4L2_TUNER_SDR`` - 4 - Tuner controls the A/D and/or D/A block of a - Sofware Digital Radio (SDR) + Software Digital Radio (SDR) * - ``V4L2_TUNER_RF`` - 5 - - Tuner controls the RF part of a Sofware Digital Radio (SDR) + - Tuner controls the RF part of a Software Digital Radio (SDR) .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| -- cgit v1.2.3 From 5fc4b067ec082c3127e0156f800769b7e0dce078 Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Sat, 22 Oct 2016 13:34:36 -0200 Subject: [media] media: solo6x10: fix lockup by avoiding delayed register write This fixes a lockup at device probing which happens on some solo6010 hardware samples. This is a regression introduced by commit e1ceb25a1569 ("[media] SOLO6x10: remove unneeded register locking and barriers") The observed lockup happens in solo_set_motion_threshold() called from solo_motion_config(). This extra "flushing" is not fundamentally needed for every write, but apparently the code in driver assumes such behaviour at last in some places. Actual fix was proposed by Hans Verkuil. Fixes: e1ceb25a1569 ("[media] SOLO6x10: remove unneeded register locking and barriers") Cc: stable@vger.kernel.org # 4.3 and up Signed-off-by: Andrey Utkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h index 5bd498735a66..3f8da5e8c430 100644 --- a/drivers/media/pci/solo6x10/solo6x10.h +++ b/drivers/media/pci/solo6x10/solo6x10.h @@ -284,7 +284,10 @@ static inline u32 solo_reg_read(struct solo_dev *solo_dev, int reg) static inline void solo_reg_write(struct solo_dev *solo_dev, int reg, u32 data) { + u16 val; + writel(data, solo_dev->reg_base + reg); + pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val); } static inline void solo_irq_on(struct solo_dev *dev, u32 mask) -- cgit v1.2.3 From 55d80506c5f7c3a44bad4a2bedeb3cc8235a69a1 Mon Sep 17 00:00:00 2001 From: Vincent Stehlé Date: Thu, 27 Oct 2016 18:23:25 -0200 Subject: [media] media: mtk-mdp: NULL-terminate mtk_mdp_comp_dt_ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mtk_mdp_comp_dt_ids[] array should be NULL-terminated; add therefore an empty entry in the end. Fixes: c8eb2d7e8202fd9c ("[media] media: Add Mediatek MDP Driver") Signed-off-by: Vincent Stehlé Cc: Minghsiu Tsai Cc: Mauro Carvalho Chehab Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 40a229d8a1f5..53296e22a024 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -50,7 +50,8 @@ static const struct of_device_id mtk_mdp_comp_dt_ids[] = { }, { .compatible = "mediatek,mt8173-mdp-wrot", .data = (void *)MTK_MDP_WROT - } + }, + { }, }; static const struct of_device_id mtk_mdp_of_ids[] = { -- cgit v1.2.3 From f76fb34a25965f0a5d9cee9f6c5ecc4f96928dc4 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Thu, 27 Oct 2016 20:34:37 -0200 Subject: [media] media: fix platform_no_drv_owner.cocci warnings drivers/media/platform/mtk-mdp/mtk_mdp_core.c:284:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci CC: Minghsiu Tsai Signed-off-by: Fengguang Wu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 53296e22a024..51f2b50e406f 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -282,7 +282,6 @@ static struct platform_driver mtk_mdp_driver = { .remove = mtk_mdp_remove, .driver = { .name = MTK_MDP_MODULE_NAME, - .owner = THIS_MODULE, .pm = &mtk_mdp_pm_ops, .of_match_table = mtk_mdp_of_ids, } -- cgit v1.2.3 From 4a3229834d5f41e5ad9fc60b444c5924853ee6bc Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 29 Oct 2016 14:17:55 -0200 Subject: [media] s5p-cec: remove unused including Remove including that don't need it. Signed-off-by: Wei Yongjun Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/s5p-cec/s5p_cec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 097e20298886..33e435855d66 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From 29a8d9792514557e26a9b05deaf671f2d83fa8ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 6 Sep 2016 19:52:24 -0300 Subject: [media] squash lines for simple wrapper functions Remove unneeded variables and assignments. Signed-off-by: Masahiro Yamada Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 8 ++------ drivers/media/pci/meye/meye.c | 5 +---- drivers/media/pci/ttpci/av7110.c | 4 +--- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 17 +++-------------- drivers/media/platform/ti-vpe/cal.c | 6 +----- drivers/media/rc/fintek-cir.c | 6 +----- drivers/media/usb/dvb-usb-v2/lmedm04.c | 14 ++++++-------- drivers/media/usb/dvb-usb/m920x.c | 10 +++------- drivers/media/usb/gspca/jl2005bcd.c | 5 +---- drivers/media/usb/gspca/sq905c.c | 5 +---- 10 files changed, 20 insertions(+), 60 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 98edf46b22d0..cdb7048874c5 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1520,12 +1520,8 @@ static int dtv_set_frontend(struct dvb_frontend *fe); static bool is_dvbv3_delsys(u32 delsys) { - bool status; - - status = (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) || - (delsys == SYS_DVBS) || (delsys == SYS_ATSC); - - return status; + return (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) || + (delsys == SYS_DVBS) || (delsys == SYS_ATSC); } /** diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 11d81389ab1e..e825bc93ea7a 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -586,10 +586,7 @@ static void mchip_hic_stop(void) /* get the next ready frame from the dma engine */ static u32 mchip_get_frame(void) { - u32 v; - - v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum)); - return v; + return mchip_read(MCHIP_MM_FIR(meye.mchip_fnum)); } /* frees the current frame from the dma engine */ diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index fbcc2e5c9414..37e7e6684e3c 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -2925,9 +2925,7 @@ static struct saa7146_extension av7110_extension_driver = { static int __init av7110_init(void) { - int retval; - retval = saa7146_register_extension(&av7110_extension_driver); - return retval; + return saa7146_register_extension(&av7110_extension_driver); } diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c index 0912d0a892e2..a1d823ab0c63 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c @@ -178,20 +178,12 @@ void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version) unsigned int exynos4_jpeg_get_int_status(void __iomem *base) { - unsigned int int_status; - - int_status = readl(base + EXYNOS4_INT_STATUS_REG); - - return int_status; + return readl(base + EXYNOS4_INT_STATUS_REG); } unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base) { - unsigned int fifo_status; - - fifo_status = readl(base + EXYNOS4_FIFO_STATUS_REG); - - return fifo_status; + return readl(base + EXYNOS4_FIFO_STATUS_REG); } void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value) @@ -296,10 +288,7 @@ void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt) unsigned int exynos4_jpeg_get_stream_size(void __iomem *base) { - unsigned int size; - - size = readl(base + EXYNOS4_BITSTREAM_SIZE_REG); - return size; + return readl(base + EXYNOS4_BITSTREAM_SIZE_REG); } void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size) diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 44323cb5d287..b2d166b2221a 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -483,11 +483,7 @@ static void cal_get_hwinfo(struct cal_dev *dev) static inline int cal_runtime_get(struct cal_dev *dev) { - int r; - - r = pm_runtime_get_sync(&dev->pdev->dev); - - return r; + return pm_runtime_get_sync(&dev->pdev->dev); } static inline void cal_runtime_put(struct cal_dev *dev) diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index bd7b3bdb1a88..ecab69ea3d51 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -104,11 +104,7 @@ static inline void fintek_cir_reg_write(struct fintek_dev *fintek, u8 val, u8 of /* read val from cir config register */ static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset) { - u8 val; - - val = inb(fintek->cir_addr + offset); - - return val; + return inb(fintek->cir_addr + offset); } /* dump current cir register contents */ diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 0e8fb89896c4..5fea02672685 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -156,21 +156,19 @@ struct lme2510_state { static int lme2510_bulk_write(struct usb_device *dev, u8 *snd, int len, u8 pipe) { - int ret, actual_l; + int actual_l; - ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), - snd, len , &actual_l, 100); - return ret; + return usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), + snd, len, &actual_l, 100); } static int lme2510_bulk_read(struct usb_device *dev, u8 *rev, int len, u8 pipe) { - int ret, actual_l; + int actual_l; - ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), - rev, len , &actual_l, 200); - return ret; + return usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), + rev, len, &actual_l, 200); } static int lme2510_usb_talk(struct dvb_usb_device *d, diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index eafc5c82467f..70672e1e5ec7 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -55,13 +55,9 @@ static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, static inline int m920x_write(struct usb_device *udev, u8 request, u16 value, u16 index) { - int ret; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - request, USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, NULL, 0, 2000); - - return ret; + return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, + USB_TYPE_VENDOR | USB_DIR_OUT, value, index, + NULL, 0, 2000); } static inline int m920x_write_seq(struct usb_device *udev, u8 request, diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c index ac295f04bd18..b12ecb72df4c 100644 --- a/drivers/media/usb/gspca/jl2005bcd.c +++ b/drivers/media/usb/gspca/jl2005bcd.c @@ -299,10 +299,7 @@ static int jl2005c_stream_start_cif_small(struct gspca_dev *gspca_dev) static int jl2005c_stop(struct gspca_dev *gspca_dev) { - int retval; - - retval = jl2005c_write_reg(gspca_dev, 0x07, 0x00); - return retval; + return jl2005c_write_reg(gspca_dev, 0x07, 0x00); } /* diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c index e02b8c1d06a2..6c45dcc44eb0 100644 --- a/drivers/media/usb/gspca/sq905c.c +++ b/drivers/media/usb/gspca/sq905c.c @@ -257,11 +257,8 @@ static void sd_stop0(struct gspca_dev *gspca_dev) /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - int ret; - /* connect to the camera and reset it. */ - ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - return ret; + return sq905c_command(gspca_dev, SQ905C_CLEAR, 0); } /* Set up for getting frames. */ -- cgit v1.2.3 From 20d93338bf250f3f6adeb71cc234fca966ef51d7 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 19 Sep 2016 03:19:28 -0300 Subject: [media] st-hva: fix a copy-and-paste variable name error The second check for an error on hva->lmi_err_reg appears to be a copy-and-paste error, it should be hva->emi_err_reg instead. Signed-off-by: Colin Ian King Acked-by: Jean-Christophe Trotin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/hva/hva-hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index cf2a8d884536..68d625b412b6 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -245,7 +245,7 @@ static irqreturn_t hva_hw_err_irq_thread(int irq, void *arg) ctx->hw_err = true; } - if (hva->lmi_err_reg) { + if (hva->emi_err_reg) { dev_err(dev, "%s external memory interface error: 0x%08x\n", ctx->name, hva->emi_err_reg); ctx->hw_err = true; -- cgit v1.2.3 From 708f48e76d6de7a90e583e2b1e6b54be1a53cc1b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 18 Oct 2016 11:15:32 -0200 Subject: [media] v4l: Document that m2m devices have a file handle specific context Memory-to-memory V4L2 devices all have file handle specific context. Say this in the API documentation so that the user space may rely on it being the case. Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/dev-codec.rst | 2 +- include/media/v4l2-mem2mem.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/dev-codec.rst b/Documentation/media/uapi/v4l/dev-codec.rst index d9f218449ddd..c61e938bd8dc 100644 --- a/Documentation/media/uapi/v4l/dev-codec.rst +++ b/Documentation/media/uapi/v4l/dev-codec.rst @@ -26,7 +26,7 @@ parameters The MPEG controls actually support many more codecs than just MPEG. See :ref:`mpeg-controls`. -Memory-to-memory devices can often be used as a shared resource: you can +Memory-to-memory devices function as a shared resource: you can open the video node multiple times, each application setting up their own codec properties that are local to the file handle, and each can use it independently from the others. The driver will arbitrate access to diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 1b355344c804..3ccd01bd245e 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -90,6 +90,9 @@ struct v4l2_m2m_queue_ctx { * %TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT. * @finished: Wait queue used to signalize when a job queue finished. * @priv: Instance private data + * + * The memory to memory context is specific to a file handle, NOT to e.g. + * a device. */ struct v4l2_m2m_ctx { /* optional cap/out vb2 queues lock */ -- cgit v1.2.3 From a503ff812430e104f591287b512aa4e3a83f20b1 Mon Sep 17 00:00:00 2001 From: Jonathan Sims Date: Sun, 23 Oct 2016 16:19:07 -0200 Subject: [media] hdpvr: fix interrupted recording This is a reworking of a patch originally submitted by Ryley Angus, modified by Hans Verkuil and then seemingly forgotten before changes suggested by Keith Pyle here: http://www.mail-archive.com/linux-media@vger.kernel.org/msg75163.html were made and tested. I have implemented the suggested changes and have been testing for the last 2 months. I am no longer experiencing lockups while recording (with blue light on, requiring power cycling) which had been a long standing problem with the HD-PVR. I have not noticed any other problems since applying the patch. Signed-off-by: Jonathan Sims Reported-by: Ryley Angus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/hdpvr/hdpvr-video.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index e3e7682d0f0e..7fb036d6a86e 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -449,6 +449,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, if (buf->status != BUFSTAT_READY && dev->status != STATUS_DISCONNECTED) { + int err; /* return nonblocking */ if (file->f_flags & O_NONBLOCK) { if (!ret) @@ -456,9 +457,24 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, goto err; } - if (wait_event_interruptible(dev->wait_data, - buf->status == BUFSTAT_READY)) - return -ERESTARTSYS; + err = wait_event_interruptible_timeout(dev->wait_data, + buf->status == BUFSTAT_READY, + msecs_to_jiffies(1000)); + if (err < 0) { + ret = err; + goto err; + } + if (!err) { + v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, + "timeout: restart streaming\n"); + hdpvr_stop_streaming(dev); + msecs_to_jiffies(4000); + err = hdpvr_start_streaming(dev); + if (err) { + ret = err; + goto err; + } + } } if (buf->status != BUFSTAT_READY) -- cgit v1.2.3 From 8fbe91e7918af8adfad45828ae8acfc2f01cb6a5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 16 Sep 2016 07:47:08 -0300 Subject: [media] videodev2.h: checkpatch cleanup Format comments according to what checkpatch wants. No other changes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 50 +++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 4364ce6b0aa6..7d3e2e9673af 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1303,33 +1303,43 @@ struct v4l2_bt_timings { /* Flags */ -/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary - GTF' curve (GTF). In both cases the horizontal and/or vertical blanking - intervals are reduced, allowing a higher resolution over the same - bandwidth. This is a read-only flag. */ +/* + * CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary + * GTF' curve (GTF). In both cases the horizontal and/or vertical blanking + * intervals are reduced, allowing a higher resolution over the same + * bandwidth. This is a read-only flag. + */ #define V4L2_DV_FL_REDUCED_BLANKING (1 << 0) -/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple - of six. These formats can be optionally played at 1 / 1.001 speed. - This is a read-only flag. */ +/* + * CEA-861 specific: set for CEA-861 formats with a framerate of a multiple + * of six. These formats can be optionally played at 1 / 1.001 speed. + * This is a read-only flag. + */ #define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1) -/* CEA-861 specific: only valid for video transmitters, the flag is cleared - by receivers. - If the framerate of the format is a multiple of six, then the pixelclock - used to set up the transmitter is divided by 1.001 to make it compatible - with 60 Hz based standards such as NTSC and PAL-M that use a framerate of - 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate - such frequencies, then the flag will also be cleared. */ +/* + * CEA-861 specific: only valid for video transmitters, the flag is cleared + * by receivers. + * If the framerate of the format is a multiple of six, then the pixelclock + * used to set up the transmitter is divided by 1.001 to make it compatible + * with 60 Hz based standards such as NTSC and PAL-M that use a framerate of + * 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate + * such frequencies, then the flag will also be cleared. + */ #define V4L2_DV_FL_REDUCED_FPS (1 << 2) -/* Specific to interlaced formats: if set, then field 1 is really one half-line - longer and field 2 is really one half-line shorter, so each field has - exactly the same number of half-lines. Whether half-lines can be detected - or used depends on the hardware. */ +/* + * Specific to interlaced formats: if set, then field 1 is really one half-line + * longer and field 2 is really one half-line shorter, so each field has + * exactly the same number of half-lines. Whether half-lines can be detected + * or used depends on the hardware. + */ #define V4L2_DV_FL_HALF_LINE (1 << 3) -/* If set, then this is a Consumer Electronics (CE) video format. Such formats +/* + * If set, then this is a Consumer Electronics (CE) video format. Such formats * differ from other formats (commonly called IT formats) in that if RGB * encoding is used then by default the RGB values use limited range (i.e. * use the range 16-235) as opposed to 0-255. All formats defined in CEA-861 - * except for the 640x480 format are CE formats. */ + * except for the 640x480 format are CE formats. + */ #define V4L2_DV_FL_IS_CE_VIDEO (1 << 4) /* Some formats like SMPTE-125M have an interlaced signal with a odd * total height. For these formats, if this flag is set, the first -- cgit v1.2.3 From 4f100ff65955c1076f90b4b7be92c4f86d70adff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 14 Jul 2016 07:58:35 -0300 Subject: [media] videodev2.h: add VICs and picture aspect ratio Add picture aspect ratio information, the CEA-861 VIC (Video Identification Code) and the HDMI VIC to struct v4l2_bt_timings. The picture aspect was chosen rather than the pixel aspect since 1) the CEA-861 standard uses picture aspect, and 2) pixel aspect ratio can become tricky when dealing with pixel repeat timings. While we don't support those yet at the moment, this might become necessary. And in that case using picture aspect ratio makes more sense. And converting picture aspect ratio to pixel aspect ratio is easy enough. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 7d3e2e9673af..d3f613e2c54a 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1254,6 +1254,9 @@ struct v4l2_standard { * (aka field 2) of interlaced field formats * @standards: Standards the timing belongs to * @flags: Flags + * @picture_aspect: The picture aspect ratio (hor/vert). + * @cea861_vic: VIC code as per the CEA-861 standard. + * @hdmi_vic: VIC code as per the HDMI standard. * @reserved: Reserved fields, must be zeroed. * * A note regarding vertical interlaced timings: height refers to the total @@ -1283,7 +1286,10 @@ struct v4l2_bt_timings { __u32 il_vbackporch; __u32 standards; __u32 flags; - __u32 reserved[14]; + struct v4l2_fract picture_aspect; + __u8 cea861_vic; + __u8 hdmi_vic; + __u8 reserved[46]; } __attribute__ ((packed)); /* Interlaced or progressive format */ @@ -1345,7 +1351,24 @@ struct v4l2_bt_timings { * total height. For these formats, if this flag is set, the first * field has the extra line. If not, it is the second field. */ -#define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE (1 << 5) +#define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE (1 << 5) +/* + * If set, then the picture_aspect field is valid. Otherwise assume that the + * pixels are square, so the picture aspect ratio is the same as the width to + * height ratio. + */ +#define V4L2_DV_FL_HAS_PICTURE_ASPECT (1 << 6) +/* + * If set, then the cea861_vic field is valid and contains the Video + * Identification Code as per the CEA-861 standard. + */ +#define V4L2_DV_FL_HAS_CEA861_VIC (1 << 7) +/* + * If set, then the hdmi_vic field is valid and contains the Video + * Identification Code as per the HDMI standard (HDMI Vendor Specific + * InfoFrame). + */ +#define V4L2_DV_FL_HAS_HDMI_VIC (1 << 8) /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ -- cgit v1.2.3 From a5e18f1401d12271770105919be403c303e8275d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 16 Sep 2016 07:38:04 -0300 Subject: [media] vidioc-g-dv-timings.rst: document the new dv_timings flags Document the new flags. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst | 11 +++++++++++ Documentation/media/videodev2.h.rst.exceptions | 3 +++ 2 files changed, 14 insertions(+) diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst index 7dd943ff14cd..aea276502f5e 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst @@ -270,3 +270,14 @@ EBUSY - Some formats like SMPTE-125M have an interlaced signal with a odd total height. For these formats, if this flag is set, the first field has the extra line. Else, it is the second field. + * - ``V4L2_DV_FL_HAS_PICTURE_ASPECT`` + - If set, then the picture_aspect field is valid. Otherwise assume that + the pixels are square, so the picture aspect ratio is the same as the + width to height ratio. + * - ``V4L2_DV_FL_HAS_CEA861_VIC`` + - If set, then the cea861_vic field is valid and contains the Video + Identification Code as per the CEA-861 standard. + * - ``V4L2_DV_FL_HAS_HDMI_VIC`` + - If set, then the hdmi_vic field is valid and contains the Video + Identification Code as per the HDMI standard (HDMI Vendor Specific + InfoFrame). diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions index 12622b2593fa..e11a0d0a8931 100644 --- a/Documentation/media/videodev2.h.rst.exceptions +++ b/Documentation/media/videodev2.h.rst.exceptions @@ -280,6 +280,9 @@ replace define V4L2_DV_FL_REDUCED_FPS dv-bt-standards replace define V4L2_DV_FL_HALF_LINE dv-bt-standards replace define V4L2_DV_FL_IS_CE_VIDEO dv-bt-standards replace define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE dv-bt-standards +replace define V4L2_DV_FL_HAS_PICTURE_ASPECT dv-bt-standards +replace define V4L2_DV_FL_HAS_CEA861_VIC dv-bt-standards +replace define V4L2_DV_FL_HAS_HDMI_VIC dv-bt-standards replace define V4L2_DV_BT_656_1120 dv-timing-types -- cgit v1.2.3 From cf0381205dec0ab10b0a17ac016c593cc7a0077f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 14 Jul 2016 07:59:01 -0300 Subject: [media] v4l2-dv-timings: add VICs and picture aspect ratio Add the CEA-861 VIC, the HDMI VIC and the picture aspect ratio information where applicable. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-dv-timings.h | 97 +++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index f31957166337..da2955154381 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -1,7 +1,7 @@ /* * V4L2 DV timings header. * - * Copyright (C) 2012 Hans Verkuil + * Copyright (C) 2012-2016 Hans Verkuil * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -11,11 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA */ #ifndef _V4L2_DV_TIMINGS_H @@ -33,13 +28,14 @@ .bt = { _width , ## args } #endif -/* CEA-861-E timings (i.e. standard HDTV timings) */ +/* CEA-861-F timings (i.e. standard HDTV timings) */ #define V4L2_DV_BT_CEA_640X480P59_94 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, \ 25175000, 16, 96, 48, 10, 2, 33, 0, 0, 0, \ - V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, 0) \ + V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 1) \ } /* Note: these are the nominal timings, for HDMI links this format is typically @@ -49,14 +45,18 @@ V4L2_INIT_BT_TIMINGS(720, 480, 1, 0, \ 13500000, 19, 62, 57, 4, 3, 15, 4, 3, 16, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_PICTURE_ASPECT | V4L2_DV_FL_HAS_CEA861_VIC, \ + { 4, 3 }, 6) \ } #define V4L2_DV_BT_CEA_720X480P59_94 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 480, 0, 0, \ 27000000, 16, 62, 60, 9, 6, 30, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_PICTURE_ASPECT | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 4, 3 }, 2) \ } /* Note: these are the nominal timings, for HDMI links this format is typically @@ -66,14 +66,18 @@ V4L2_INIT_BT_TIMINGS(720, 576, 1, 0, \ 13500000, 12, 63, 69, 2, 3, 19, 2, 3, 20, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_PICTURE_ASPECT | V4L2_DV_FL_HAS_CEA861_VIC, \ + { 4, 3 }, 21) \ } #define V4L2_DV_BT_CEA_720X576P50 { \ .type = V4L2_DV_BT_656_1120, \ V4L2_INIT_BT_TIMINGS(720, 576, 0, 0, \ 27000000, 12, 64, 68, 5, 5, 39, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_PICTURE_ASPECT | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 4, 3 }, 17) \ } #define V4L2_DV_BT_CEA_1280X720P24 { \ @@ -82,7 +86,7 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 59400000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, \ V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 60) \ } #define V4L2_DV_BT_CEA_1280X720P25 { \ @@ -90,7 +94,8 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 2420, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 61) \ } #define V4L2_DV_BT_CEA_1280X720P30 { \ @@ -99,7 +104,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 62) \ } #define V4L2_DV_BT_CEA_1280X720P50 { \ @@ -107,7 +113,8 @@ V4L2_INIT_BT_TIMINGS(1280, 720, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 440, 40, 220, 5, 5, 20, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 19) \ } #define V4L2_DV_BT_CEA_1280X720P60 { \ @@ -116,7 +123,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 110, 40, 220, 5, 5, 20, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 4) \ } #define V4L2_DV_BT_CEA_1920X1080P24 { \ @@ -125,7 +133,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 32) \ } #define V4L2_DV_BT_CEA_1920X1080P25 { \ @@ -133,7 +142,8 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 33) \ } #define V4L2_DV_BT_CEA_1920X1080P30 { \ @@ -142,7 +152,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 34) \ } #define V4L2_DV_BT_CEA_1920X1080I50 { \ @@ -151,7 +162,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 74250000, 528, 44, 148, 2, 5, 15, 2, 5, 16, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 20) \ } #define V4L2_DV_BT_CEA_1920X1080P50 { \ @@ -159,7 +171,8 @@ V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 148500000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 31) \ } #define V4L2_DV_BT_CEA_1920X1080I60 { \ @@ -169,7 +182,8 @@ 74250000, 88, 44, 148, 2, 5, 15, 2, 5, 16, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | \ - V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 5) \ } #define V4L2_DV_BT_CEA_1920X1080P60 { \ @@ -178,7 +192,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 148500000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \ V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 16) \ } #define V4L2_DV_BT_CEA_3840X2160P24 { \ @@ -187,7 +202,9 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC | V4L2_DV_FL_HAS_HDMI_VIC, \ + { 0, 0 }, 93, 3) \ } #define V4L2_DV_BT_CEA_3840X2160P25 { \ @@ -195,7 +212,9 @@ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC | \ + V4L2_DV_FL_HAS_HDMI_VIC, { 0, 0 }, 94, 2) \ } #define V4L2_DV_BT_CEA_3840X2160P30 { \ @@ -204,7 +223,9 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC | V4L2_DV_FL_HAS_HDMI_VIC, \ + { 0, 0 }, 95, 1) \ } #define V4L2_DV_BT_CEA_3840X2160P50 { \ @@ -212,7 +233,8 @@ V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 96) \ } #define V4L2_DV_BT_CEA_3840X2160P60 { \ @@ -221,7 +243,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 97) \ } #define V4L2_DV_BT_CEA_4096X2160P24 { \ @@ -230,7 +253,9 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC | V4L2_DV_FL_HAS_HDMI_VIC, \ + { 0, 0 }, 98, 4) \ } #define V4L2_DV_BT_CEA_4096X2160P25 { \ @@ -238,7 +263,8 @@ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 99) \ } #define V4L2_DV_BT_CEA_4096X2160P30 { \ @@ -247,7 +273,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 100) \ } #define V4L2_DV_BT_CEA_4096X2160P50 { \ @@ -255,7 +282,8 @@ V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ - V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_BT_STD_CEA861, \ + V4L2_DV_FL_IS_CE_VIDEO | V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 101) \ } #define V4L2_DV_BT_CEA_4096X2160P60 { \ @@ -264,7 +292,8 @@ V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ - V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ + V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO | \ + V4L2_DV_FL_HAS_CEA861_VIC, { 0, 0 }, 102) \ } -- cgit v1.2.3 From 652430763f9f48af0fea83ef9a6fecf7680d9210 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 14 Jul 2016 07:59:12 -0300 Subject: [media] v4l2-dv-timings: add helpers for vic and pixelaspect ratio Add a helper to find timings based on the CEA-861 VIC code. Also, add a helper that returns the pixel aspect ratio based on the v4l2_dv_timings struct. [mchehab@s-opensource.com: fix coding style] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/Kconfig | 1 + drivers/media/v4l2-core/v4l2-dv-timings.c | 59 +++++++++++++++++++++++++++++-- include/media/v4l2-dv-timings.h | 20 ++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 367523a3c774..6b1b78ff1417 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -6,6 +6,7 @@ config VIDEO_V4L2 tristate depends on (I2C || I2C=n) && VIDEO_DEV + select RATIONAL default (I2C || I2C=n) && VIDEO_DEV config VIDEO_ADV_DEBUG diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 730a7c392c1d..5c8c49d240d1 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -224,6 +225,24 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t, } EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cap); +bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic) +{ + unsigned int i; + + for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) { + const struct v4l2_bt_timings *bt = + &v4l2_dv_timings_presets[i].bt; + + if ((bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) && + bt->cea861_vic == vic) { + *t = v4l2_dv_timings_presets[i]; + return true; + } + } + return false; +} +EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic); + /** * v4l2_match_dv_timings - check if two timings match * @t1 - compare this v4l2_dv_timings struct... @@ -306,7 +325,8 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", bt->il_vsync, bt->il_vbackporch); pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock); - pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s\n", dev_prefix, bt->flags, + pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s%s%s%s\n", + dev_prefix, bt->flags, (bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ? " REDUCED_BLANKING" : "", ((bt->flags & V4L2_DV_FL_REDUCED_BLANKING) && @@ -320,16 +340,51 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) ? " CE_VIDEO" : "", (bt->flags & V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) ? - " FIRST_FIELD_EXTRA_LINE" : ""); + " FIRST_FIELD_EXTRA_LINE" : "", + (bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT) ? + " HAS_PICTURE_ASPECT" : "", + (bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) ? + " HAS_CEA861_VIC" : "", + (bt->flags & V4L2_DV_FL_HAS_HDMI_VIC) ? + " HAS_HDMI_VIC" : ""); pr_info("%s: standards (0x%x):%s%s%s%s%s\n", dev_prefix, bt->standards, (bt->standards & V4L2_DV_BT_STD_CEA861) ? " CEA" : "", (bt->standards & V4L2_DV_BT_STD_DMT) ? " DMT" : "", (bt->standards & V4L2_DV_BT_STD_CVT) ? " CVT" : "", (bt->standards & V4L2_DV_BT_STD_GTF) ? " GTF" : "", (bt->standards & V4L2_DV_BT_STD_SDI) ? " SDI" : ""); + if (bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT) + pr_info("%s: picture aspect (hor:vert): %u:%u\n", dev_prefix, + bt->picture_aspect.numerator, + bt->picture_aspect.denominator); + if (bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) + pr_info("%s: CEA-861 VIC: %u\n", dev_prefix, bt->cea861_vic); + if (bt->flags & V4L2_DV_FL_HAS_HDMI_VIC) + pr_info("%s: HDMI VIC: %u\n", dev_prefix, bt->hdmi_vic); } EXPORT_SYMBOL_GPL(v4l2_print_dv_timings); +struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t) +{ + struct v4l2_fract ratio = { 1, 1 }; + unsigned long n, d; + + if (t->type != V4L2_DV_BT_656_1120) + return ratio; + if (!(t->bt.flags & V4L2_DV_FL_HAS_PICTURE_ASPECT)) + return ratio; + + ratio.numerator = t->bt.width * t->bt.picture_aspect.denominator; + ratio.denominator = t->bt.height * t->bt.picture_aspect.numerator; + + rational_best_approximation(ratio.numerator, ratio.denominator, + ratio.numerator, ratio.denominator, &n, &d); + ratio.numerator = n; + ratio.denominator = d; + return ratio; +} +EXPORT_SYMBOL_GPL(v4l2_dv_timings_aspect_ratio); + /* * CVT defines * Based on Coordinated Video Timings Standard diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index 0a7d9e1fc8c8..61a18893e004 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -100,13 +100,23 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t, v4l2_check_dv_timings_fnc fnc, void *fnc_handle); +/** + * v4l2_find_dv_timings_cea861_vic() - find timings based on CEA-861 VIC + * @t: the timings data. + * @vic: CEA-861 VIC code + * + * On success it will fill in @t with the found timings and it returns true. + * On failure it will return false. + */ +bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic); + /** * v4l2_match_dv_timings() - do two timings match? * * @measured: the measured timings data. * @standard: the timings according to the standard. * @pclock_delta: maximum delta in Hz between standard->pixelclock and - * the measured timings. + * the measured timings. * @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not * match. * @@ -185,6 +195,14 @@ bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync, */ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait); +/** + * v4l2_dv_timings_aspect_ratio - calculate the aspect ratio based on the + * v4l2_dv_timings information. + * + * @t: the timings data. + */ +struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t); + /* * reduce_fps - check if conditions for reduced fps are true. * bt - v4l2 timing structure -- cgit v1.2.3 From d736e348a0bcf25972c23d743821b91d3694e328 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 17 Jul 2016 05:42:07 -0300 Subject: [media] cobalt: add cropcap support Now that the timings contain picture aspect ratio information, we can support cropcap to return the pixel aspect ratio. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-v4l2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 5c76637900d0..3fea24613059 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -1084,12 +1084,33 @@ static int cobalt_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) return 0; } +static int cobalt_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cc) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_dv_timings timings; + int err = 0; + + if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (s->input == 1) + timings = cea1080p60; + else + err = v4l2_subdev_call(s->sd, video, g_dv_timings, &timings); + if (!err) { + cc->bounds.width = cc->defrect.width = timings.bt.width; + cc->bounds.height = cc->defrect.height = timings.bt.height; + cc->pixelaspect = v4l2_dv_timings_aspect_ratio(&timings); + } + return err; +} + static const struct v4l2_ioctl_ops cobalt_ioctl_ops = { .vidioc_querycap = cobalt_querycap, .vidioc_g_parm = cobalt_g_parm, .vidioc_log_status = cobalt_log_status, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_cropcap = cobalt_cropcap, .vidioc_enum_input = cobalt_enum_input, .vidioc_g_input = cobalt_g_input, .vidioc_s_input = cobalt_s_input, -- cgit v1.2.3 From 827c1f525a07e07997bee034a84d32216af10e58 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 14 Jul 2016 11:53:47 -0300 Subject: [media] adv7604: add vic detect Obtain the correct timings based on the VIC code from the AVI InfoFrame. It does a sanity check to see if at least the measured width and height are in line with what the VIC code reports. If not, then use the timings instead of the VIC code (as per the CEA-861 spec). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index fa7046ef09b2..5630eb22daaa 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -1566,10 +1566,24 @@ static int adv76xx_query_dv_timings(struct v4l2_subdev *sd, V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; if (is_digital_input(sd)) { + bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80; + u8 vic = 0; + u32 w, h; + + w = hdmi_read16(sd, 0x07, info->linewidth_mask); + h = hdmi_read16(sd, 0x09, info->field0_height_mask); + + if (hdmi_signal && (io_read(sd, 0x60) & 1)) + vic = infoframe_read(sd, 0x04); + + if (vic && v4l2_find_dv_timings_cea861_vic(timings, vic) && + bt->width == w && bt->height == h) + goto found; + timings->type = V4L2_DV_BT_656_1120; - bt->width = hdmi_read16(sd, 0x07, info->linewidth_mask); - bt->height = hdmi_read16(sd, 0x09, info->field0_height_mask); + bt->width = w; + bt->height = h; bt->pixelclock = info->read_hdmi_pixelclock(sd); bt->hfrontporch = hdmi_read16(sd, 0x20, info->hfrontporch_mask); bt->hsync = hdmi_read16(sd, 0x22, info->hsync_mask); -- cgit v1.2.3 From 64bab1a20c21875dd021e426ec9d8a21dfb4b3ac Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Fri, 4 Nov 2016 05:58:31 -0200 Subject: [media] staging: st-cec: add parentheses around complex macros This patch fixes the following checkpatch.pl error: ERROR: Macros with complex values should be enclosed in parentheses Signed-off-by: Maninder Singh Acked-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/st-cec/stih-cec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c index 1f1542e8154f..eed1fd6bbefa 100644 --- a/drivers/staging/media/st-cec/stih-cec.c +++ b/drivers/staging/media/st-cec/stih-cec.c @@ -107,11 +107,11 @@ /* Constants for CEC_BIT_TOUT_THRESH register */ #define CEC_SBIT_TOUT_47MS BIT(1) -#define CEC_SBIT_TOUT_48MS BIT(0) | BIT(1) +#define CEC_SBIT_TOUT_48MS (BIT(0) | BIT(1)) #define CEC_SBIT_TOUT_50MS BIT(2) #define CEC_DBIT_TOUT_27MS BIT(0) #define CEC_DBIT_TOUT_28MS BIT(1) -#define CEC_DBIT_TOUT_29MS BIT(0) | BIT(1) +#define CEC_DBIT_TOUT_29MS (BIT(0) | BIT(1)) /* Constants for CEC_BIT_PULSE_THRESH register */ #define CEC_BIT_LPULSE_03MS BIT(1) -- cgit v1.2.3 From 2eaa68f33b86bf9a6c6cbfaf773d74f1f8bddd4e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 6 Nov 2016 17:40:20 -0200 Subject: [media] DaVinci-VPBE: Check return value of a setup_if_config() call in vpbe_set_output() * A function was called over the pointer "setup_if_config" in the data structure "venc_platform_data". But the return value was not used so far. Thus assign it to the local variable "ret" which will be checked with the next statement. Fixes: 9a7f95ad1c946efdd7a7a72df27db738260a0fd8 ("[media] davinci vpbe: add dm365 VPBE display driver changes") * Pass a value to this function call without storing it in an intermediate variable before. * Delete the local variable "if_params" which became unnecessary with this refactoring. Acked-by: Lad, Prabhakar Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 7dcdb7f4b323..8c8cbeb7d90f 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -227,7 +227,6 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) vpbe_current_encoder_info(vpbe_dev); struct vpbe_config *cfg = vpbe_dev->cfg; struct venc_platform_data *venc_device = vpbe_dev->venc_device; - u32 if_params; int enc_out_index; int sd_index; int ret; @@ -257,8 +256,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) goto unlock; } - if_params = cfg->outputs[index].if_params; - venc_device->setup_if_config(if_params); + ret = venc_device->setup_if_config(cfg->outputs[index].if_params); if (ret) goto unlock; } -- cgit v1.2.3 From e91b6006bfa65600a14e79b7d8371ec711a7c84f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 6 Nov 2016 18:54:38 -0200 Subject: [media] DaVinci-VPFE-Capture: Replace a memcpy() call by an assignment in vpfe_enum_input() Use a direct assignment for an array element which can be set over the pointer variable "inp" instead of calling the function "memcpy" here. Suggested-by: Hans Verkuil Signed-off-by: Markus Elfring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 71caebf125f1..6c41782b3ba0 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1086,7 +1086,7 @@ static int vpfe_enum_input(struct file *file, void *priv, return -EINVAL; } sdinfo = &vpfe_dev->cfg->sub_devs[subdev]; - memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input)); + *inp = sdinfo->inputs[index]; return 0; } -- cgit v1.2.3 From e92ca73b7057ebdba5ea926f25f51b77b41f6c80 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 9 Nov 2016 06:00:53 -0200 Subject: [media] cec-core.rst: improve documentation Improve the internal CEC documentation. In particular add a section that specifies that transmit-related interrupts should be processed before receive interrupts. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/cec-core.rst | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 88c33b53ec13..8a88dd4ce3d4 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -106,13 +106,13 @@ your driver: int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); - void (\*adap_log_status)(struct cec_adapter *adap); + void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); /* High-level callbacks */ ... }; -The three low-level ops deal with various aspects of controlling the CEC adapter +The five low-level ops deal with various aspects of controlling the CEC adapter hardware: @@ -238,6 +238,18 @@ When a CEC message was received: Speaks for itself. +Implementing the interrupt handler +---------------------------------- + +Typically the CEC hardware provides interrupts that signal when a transmit +finished and whether it was successful or not, and it provides and interrupt +when a CEC message was received. + +The CEC driver should always process the transmit interrupts first before +handling the receive interrupt. The framework expects to see the cec_transmit_done +call before the cec_received_msg call, otherwise it can get confused if the +received message was in reply to the transmitted message. + Implementing the High-Level CEC Adapter --------------------------------------- @@ -247,11 +259,11 @@ CEC protocol driven. The following high-level callbacks are available: .. code-block:: none struct cec_adap_ops { - /\* Low-level callbacks \*/ + /* Low-level callbacks */ ... - /\* High-level CEC message callback \*/ - int (\*received)(struct cec_adapter \*adap, struct cec_msg \*msg); + /* High-level CEC message callback */ + int (*received)(struct cec_adapter *adap, struct cec_msg *msg); }; The received() callback allows the driver to optionally handle a newly @@ -263,7 +275,7 @@ received CEC message If the driver wants to process a CEC message, then it can implement this callback. If it doesn't want to handle this message, then it should return -ENOMSG, otherwise the CEC framework assumes it processed this message and -it will not no anything with it. +it will not do anything with it. CEC framework functions -- cgit v1.2.3 From 93d39efdb1f8c8c4b848122b8c8ad986690fe9ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 9 Nov 2016 06:31:10 -0200 Subject: [media] control.rst: improve the queryctrl code examples The code examples on how to enumerate controls were really long in the tooth. Update them. Using FLAG_NEXT_CTRL is preferred these days, so give that example first. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/control.rst | 88 ++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/Documentation/media/uapi/v4l/control.rst b/Documentation/media/uapi/v4l/control.rst index d3f1450c4b08..51112badb804 100644 --- a/Documentation/media/uapi/v4l/control.rst +++ b/Documentation/media/uapi/v4l/control.rst @@ -312,21 +312,20 @@ more menu type controls. .. _enum_all_controls: -Example: Enumerating all user controls -====================================== +Example: Enumerating all controls +================================= .. code-block:: c - struct v4l2_queryctrl queryctrl; struct v4l2_querymenu querymenu; - static void enumerate_menu(void) + static void enumerate_menu(__u32 id) { printf(" Menu items:\\n"); memset(&querymenu, 0, sizeof(querymenu)); - querymenu.id = queryctrl.id; + querymenu.id = id; for (querymenu.index = queryctrl.minimum; querymenu.index <= queryctrl.maximum; @@ -337,6 +336,55 @@ Example: Enumerating all user controls } } + memset(&queryctrl, 0, sizeof(queryctrl)); + + queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; + while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { + if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { + printf("Control %s\\n", queryctrl.name); + + if (queryctrl.type == V4L2_CTRL_TYPE_MENU) + enumerate_menu(queryctrl.id); + } + + queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + } + if (errno != EINVAL) { + perror("VIDIOC_QUERYCTRL"); + exit(EXIT_FAILURE); + } + +Example: Enumerating all controls including compound controls +============================================================= + +.. code-block:: c + + struct v4l2_query_ext_ctrl query_ext_ctrl; + + memset(&query_ext_ctrl, 0, sizeof(query_ext_ctrl)); + + query_ext_ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; + while (0 == ioctl(fd, VIDIOC_QUERY_EXT_CTRL, &query_ext_ctrl)) { + if (!(query_ext_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { + printf("Control %s\\n", query_ext_ctrl.name); + + if (query_ext_ctrl.type == V4L2_CTRL_TYPE_MENU) + enumerate_menu(query_ext_ctrl.id); + } + + query_ext_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; + } + if (errno != EINVAL) { + perror("VIDIOC_QUERY_EXT_CTRL"); + exit(EXIT_FAILURE); + } + +Example: Enumerating all user controls (old style) +================================================== + +.. code-block:: c + + memset(&queryctrl, 0, sizeof(queryctrl)); for (queryctrl.id = V4L2_CID_BASE; @@ -349,7 +397,7 @@ Example: Enumerating all user controls printf("Control %s\\n", queryctrl.name); if (queryctrl.type == V4L2_CTRL_TYPE_MENU) - enumerate_menu(); + enumerate_menu(queryctrl.id); } else { if (errno == EINVAL) continue; @@ -368,7 +416,7 @@ Example: Enumerating all user controls printf("Control %s\\n", queryctrl.name); if (queryctrl.type == V4L2_CTRL_TYPE_MENU) - enumerate_menu(); + enumerate_menu(queryctrl.id); } else { if (errno == EINVAL) break; @@ -379,32 +427,6 @@ Example: Enumerating all user controls } -Example: Enumerating all user controls (alternative) -==================================================== - -.. code-block:: c - - memset(&queryctrl, 0, sizeof(queryctrl)); - - queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL; - while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { - if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER) - break; - if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) - continue; - - printf("Control %s\\n", queryctrl.name); - - if (queryctrl.type == V4L2_CTRL_TYPE_MENU) - enumerate_menu(); - - queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; - } - if (errno != EINVAL) { - perror("VIDIOC_QUERYCTRL"); - exit(EXIT_FAILURE); - } - Example: Changing controls ========================== -- cgit v1.2.3 From b7ccb9fb7994d0340314a5d467a8c4d3e37d6531 Mon Sep 17 00:00:00 2001 From: Wu-Cheng Li Date: Thu, 10 Nov 2016 03:24:05 -0200 Subject: [media] mtk-vcodec: add index check in decoder vidioc_qbuf vb2_qbuf will check the buffer index. If a driver overrides vidioc_qbuf and use the buffer index, the driver needs to check the index. Signed-off-by: Wu-Cheng Li Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 05209193ff7e..074659227864 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -533,6 +533,10 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv, } vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type); + if (buf->index >= vq->num_buffers) { + mtk_v4l2_debug(1, "buffer index %d out of range", buf->index); + return -EINVAL; + } vb = vq->bufs[buf->index]; vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); mtkbuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); -- cgit v1.2.3 From 9f750b2b15125e842a2bd0a8c16f06ee65da26a2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 11 Nov 2016 08:33:05 -0200 Subject: [media] cobalt: fix copy-and-paste error The vmr_stat variable was filled with the contents of the control register, not the status register. Classic copy-and-paste error. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 3fea24613059..def4a3b37084 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -527,7 +527,7 @@ static void cobalt_video_input_status_show(struct cobalt_stream *s) cvi_ctrl = ioread32(&cvi->control); cvi_stat = ioread32(&cvi->status); vmr_ctrl = ioread32(&vmr->control); - vmr_stat = ioread32(&vmr->control); + vmr_stat = ioread32(&vmr->status); cobalt_info("rx%d: cvi resolution: %dx%d\n", rx, ioread32(&cvi->frame_width), ioread32(&cvi->frame_height)); cobalt_info("rx%d: cvi control: %s%s%s\n", rx, -- cgit v1.2.3 From acd4973563f5f80a833f2cc97c5f45048be93250 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 06:47:10 -0200 Subject: [media] pulse8-cec: set all_device_types when restoring config When the persistent state is restored, the all_device_types field was never filled in. Fix this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/pulse8-cec/pulse8-cec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/media/pulse8-cec/pulse8-cec.c b/drivers/staging/media/pulse8-cec/pulse8-cec.c index 1732c3857b8e..9092494bb43c 100644 --- a/drivers/staging/media/pulse8-cec/pulse8-cec.c +++ b/drivers/staging/media/pulse8-cec/pulse8-cec.c @@ -375,27 +375,35 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, switch (log_addrs->primary_device_type[0]) { case CEC_OP_PRIM_DEVTYPE_TV: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; break; case CEC_OP_PRIM_DEVTYPE_RECORD: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; break; case CEC_OP_PRIM_DEVTYPE_TUNER: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; break; case CEC_OP_PRIM_DEVTYPE_PLAYBACK: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; break; case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; break; case CEC_OP_PRIM_DEVTYPE_SWITCH: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; break; case CEC_OP_PRIM_DEVTYPE_PROCESSOR: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; break; default: log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n", log_addrs->primary_device_type[0]); break; -- cgit v1.2.3 From 77edf603f22425dedd5963e9b86db7ebb15c6caf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 07:41:17 -0200 Subject: [media] cec rst: convert tables and drop the 'row' comments This uses Laurent's python script to convert all tables, dropping the useless 'row' comments. See commit c2b66cafdf02 ("[media] v4l: doc: Remove row numbers from tables") for the script that was used. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/cec/cec-ioc-adap-g-caps.rst | 156 +++---- .../media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 475 ++++++++------------- Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 182 +++----- Documentation/media/uapi/cec/cec-ioc-g-mode.rst | 317 ++++++-------- Documentation/media/uapi/cec/cec-ioc-receive.rst | 394 +++++++---------- 5 files changed, 579 insertions(+), 945 deletions(-) diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst index a35dca281178..2b0ddb14b280 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst @@ -48,41 +48,21 @@ returns the information to the application. The ioctl never fails. :stub-columns: 0 :widths: 1 1 16 - - - .. row 1 - - - char - - - ``driver[32]`` - - - The name of the cec adapter driver. - - - .. row 2 - - - char - - - ``name[32]`` - - - The name of this CEC adapter. The combination ``driver`` and - ``name`` must be unique. - - - .. row 3 - - - __u32 - - - ``capabilities`` - - - The capabilities of the CEC adapter, see - :ref:`cec-capabilities`. - - - .. row 4 - - - __u32 - - - ``version`` - - - CEC Framework API version, formatted with the ``KERNEL_VERSION()`` - macro. + * - char + - ``driver[32]`` + - The name of the cec adapter driver. + * - char + - ``name[32]`` + - The name of this CEC adapter. The combination ``driver`` and + ``name`` must be unique. + * - __u32 + - ``capabilities`` + - The capabilities of the CEC adapter, see + :ref:`cec-capabilities`. + * - __u32 + - ``version`` + - CEC Framework API version, formatted with the ``KERNEL_VERSION()`` + macro. .. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}| @@ -94,68 +74,50 @@ returns the information to the application. The ioctl never fails. :stub-columns: 0 :widths: 3 1 8 - - - .. _`CEC-CAP-PHYS-ADDR`: - - - ``CEC_CAP_PHYS_ADDR`` - - - 0x00000001 - - - Userspace has to configure the physical address by calling - :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `. If - this capability isn't set, then setting the physical address is - handled by the kernel whenever the EDID is set (for an HDMI - receiver) or read (for an HDMI transmitter). - - - .. _`CEC-CAP-LOG-ADDRS`: - - - ``CEC_CAP_LOG_ADDRS`` - - - 0x00000002 - - - Userspace has to configure the logical addresses by calling - :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. If - this capability isn't set, then the kernel will have configured - this. - - - .. _`CEC-CAP-TRANSMIT`: - - - ``CEC_CAP_TRANSMIT`` - - - 0x00000004 - - - Userspace can transmit CEC messages by calling - :ref:`ioctl CEC_TRANSMIT `. This implies that - userspace can be a follower as well, since being able to transmit - messages is a prerequisite of becoming a follower. If this - capability isn't set, then the kernel will handle all CEC - transmits and process all CEC messages it receives. - - - .. _`CEC-CAP-PASSTHROUGH`: - - - ``CEC_CAP_PASSTHROUGH`` - - - 0x00000008 - - - Userspace can use the passthrough mode by calling - :ref:`ioctl CEC_S_MODE `. - - - .. _`CEC-CAP-RC`: - - - ``CEC_CAP_RC`` - - - 0x00000010 - - - This adapter supports the remote control protocol. - - - .. _`CEC-CAP-MONITOR-ALL`: - - - ``CEC_CAP_MONITOR_ALL`` - - - 0x00000020 - - - The CEC hardware can monitor all messages, not just directed and - broadcast messages. + * .. _`CEC-CAP-PHYS-ADDR`: + + - ``CEC_CAP_PHYS_ADDR`` + - 0x00000001 + - Userspace has to configure the physical address by calling + :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `. If + this capability isn't set, then setting the physical address is + handled by the kernel whenever the EDID is set (for an HDMI + receiver) or read (for an HDMI transmitter). + * .. _`CEC-CAP-LOG-ADDRS`: + + - ``CEC_CAP_LOG_ADDRS`` + - 0x00000002 + - Userspace has to configure the logical addresses by calling + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. If + this capability isn't set, then the kernel will have configured + this. + * .. _`CEC-CAP-TRANSMIT`: + + - ``CEC_CAP_TRANSMIT`` + - 0x00000004 + - Userspace can transmit CEC messages by calling + :ref:`ioctl CEC_TRANSMIT `. This implies that + userspace can be a follower as well, since being able to transmit + messages is a prerequisite of becoming a follower. If this + capability isn't set, then the kernel will handle all CEC + transmits and process all CEC messages it receives. + * .. _`CEC-CAP-PASSTHROUGH`: + + - ``CEC_CAP_PASSTHROUGH`` + - 0x00000008 + - Userspace can use the passthrough mode by calling + :ref:`ioctl CEC_S_MODE `. + * .. _`CEC-CAP-RC`: + + - ``CEC_CAP_RC`` + - 0x00000010 + - This adapter supports the remote control protocol. + * .. _`CEC-CAP-MONITOR-ALL`: + + - ``CEC_CAP_MONITOR_ALL`` + - 0x00000020 + - The CEC hardware can monitor all messages, not just directed and + broadcast messages. diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index 940a16d8d55e..af35f7185439 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -77,134 +77,79 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 1 1 16 - - - .. row 1 - - - __u8 - - - ``log_addr[CEC_MAX_LOG_ADDRS]`` - - - The actual logical addresses that were claimed. This is set by the - driver. If no logical address could be claimed, then it is set to - ``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then - ``log_addr[0]`` is set to 0xf and all others to - ``CEC_LOG_ADDR_INVALID``. - - - .. row 2 - - - __u16 - - - ``log_addr_mask`` - - - The bitmask of all logical addresses this adapter has claimed. If - this adapter is Unregistered then ``log_addr_mask`` sets bit 15 - and clears all other bits. If this adapter is not configured at - all, then ``log_addr_mask`` is set to 0. Set by the driver. - - - .. row 3 - - - __u8 - - - ``cec_version`` - - - The CEC version that this adapter shall use. See - :ref:`cec-versions`. Used to implement the - ``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages. - Note that :ref:`CEC_OP_CEC_VERSION_1_3A ` is not allowed by the CEC - framework. - - - .. row 4 - - - __u8 - - - ``num_log_addrs`` - - - Number of logical addresses to set up. Must be ≤ - ``available_log_addrs`` as returned by - :ref:`CEC_ADAP_G_CAPS`. All arrays in - this structure are only filled up to index - ``available_log_addrs``-1. The remaining array elements will be - ignored. Note that the CEC 2.0 standard allows for a maximum of 2 - logical addresses, although some hardware has support for more. - ``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual - number of logical addresses it could claim, which may be less than - what was requested. If this field is set to 0, then the CEC - adapter shall clear all claimed logical addresses and all other - fields will be ignored. - - - .. row 5 - - - __u32 - - - ``vendor_id`` - - - The vendor ID is a 24-bit number that identifies the specific - vendor or entity. Based on this ID vendor specific commands may be - defined. If you do not want a vendor ID then set it to - ``CEC_VENDOR_ID_NONE``. - - - .. row 6 - - - __u32 - - - ``flags`` - - - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. - - - .. row 7 - - - char - - - ``osd_name[15]`` - - - The On-Screen Display name as is returned by the - ``CEC_MSG_SET_OSD_NAME`` message. - - - .. row 8 - - - __u8 - - - ``primary_device_type[CEC_MAX_LOG_ADDRS]`` - - - Primary device type for each logical address. See - :ref:`cec-prim-dev-types` for possible types. - - - .. row 9 - - - __u8 - - - ``log_addr_type[CEC_MAX_LOG_ADDRS]`` - - - Logical address types. See :ref:`cec-log-addr-types` for - possible types. The driver will update this with the actual - logical address type that it claimed (e.g. it may have to fallback - to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED `). - - - .. row 10 - - - __u8 - - - ``all_device_types[CEC_MAX_LOG_ADDRS]`` - - - CEC 2.0 specific: the bit mask of all device types. See - :ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0 - ``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave - this field to 0, or fill it in according to the CEC 2.0 guidelines to - give the CEC framework more information about the device type, even - though the framework won't use it directly in the CEC message. - - - .. row 11 - - - __u8 - - - ``features[CEC_MAX_LOG_ADDRS][12]`` - - - Features for each logical address. It is used in the CEC 2.0 - ``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the - RC Profile and the Device Features. For CEC 1.4 you can either leave - this field to all 0, or fill it in according to the CEC 2.0 guidelines to - give the CEC framework more information about the device type, even - though the framework won't use it directly in the CEC message. + * - __u8 + - ``log_addr[CEC_MAX_LOG_ADDRS]`` + - The actual logical addresses that were claimed. This is set by the + driver. If no logical address could be claimed, then it is set to + ``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then + ``log_addr[0]`` is set to 0xf and all others to + ``CEC_LOG_ADDR_INVALID``. + * - __u16 + - ``log_addr_mask`` + - The bitmask of all logical addresses this adapter has claimed. If + this adapter is Unregistered then ``log_addr_mask`` sets bit 15 + and clears all other bits. If this adapter is not configured at + all, then ``log_addr_mask`` is set to 0. Set by the driver. + * - __u8 + - ``cec_version`` + - The CEC version that this adapter shall use. See + :ref:`cec-versions`. Used to implement the + ``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages. + Note that :ref:`CEC_OP_CEC_VERSION_1_3A ` is not allowed by the CEC + framework. + * - __u8 + - ``num_log_addrs`` + - Number of logical addresses to set up. Must be ≤ + ``available_log_addrs`` as returned by + :ref:`CEC_ADAP_G_CAPS`. All arrays in + this structure are only filled up to index + ``available_log_addrs``-1. The remaining array elements will be + ignored. Note that the CEC 2.0 standard allows for a maximum of 2 + logical addresses, although some hardware has support for more. + ``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual + number of logical addresses it could claim, which may be less than + what was requested. If this field is set to 0, then the CEC + adapter shall clear all claimed logical addresses and all other + fields will be ignored. + * - __u32 + - ``vendor_id`` + - The vendor ID is a 24-bit number that identifies the specific + vendor or entity. Based on this ID vendor specific commands may be + defined. If you do not want a vendor ID then set it to + ``CEC_VENDOR_ID_NONE``. + * - __u32 + - ``flags`` + - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. + * - char + - ``osd_name[15]`` + - The On-Screen Display name as is returned by the + ``CEC_MSG_SET_OSD_NAME`` message. + * - __u8 + - ``primary_device_type[CEC_MAX_LOG_ADDRS]`` + - Primary device type for each logical address. See + :ref:`cec-prim-dev-types` for possible types. + * - __u8 + - ``log_addr_type[CEC_MAX_LOG_ADDRS]`` + - Logical address types. See :ref:`cec-log-addr-types` for + possible types. The driver will update this with the actual + logical address type that it claimed (e.g. it may have to fallback + to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED `). + * - __u8 + - ``all_device_types[CEC_MAX_LOG_ADDRS]`` + - CEC 2.0 specific: the bit mask of all device types. See + :ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0 + ``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave + this field to 0, or fill it in according to the CEC 2.0 guidelines to + give the CEC framework more information about the device type, even + though the framework won't use it directly in the CEC message. + * - __u8 + - ``features[CEC_MAX_LOG_ADDRS][12]`` + - Features for each logical address. It is used in the CEC 2.0 + ``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the + RC Profile and the Device Features. For CEC 1.4 you can either leave + this field to all 0, or fill it in according to the CEC 2.0 guidelines to + give the CEC framework more information about the device type, even + though the framework won't use it directly in the CEC message. .. _cec-log-addrs-flags: @@ -213,17 +158,14 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 3 1 4 + * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: - - .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: - - - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` - - - 1 - - - By default if no logical address of the requested type can be claimed, then - it will go back to the unconfigured state. If this flag is set, then it will - fallback to the Unregistered logical address. Note that if the Unregistered - logical address was explicitly requested, then this flag has no effect. + - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` + - 1 + - By default if no logical address of the requested type can be claimed, then + it will go back to the unconfigured state. If this flag is set, then it will + fallback to the Unregistered logical address. Note that if the Unregistered + logical address was explicitly requested, then this flag has no effect. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| @@ -234,30 +176,21 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 3 1 4 + * .. _`CEC-OP-CEC-VERSION-1-3A`: - - .. _`CEC-OP-CEC-VERSION-1-3A`: - - - ``CEC_OP_CEC_VERSION_1_3A`` - - - 4 - - - CEC version according to the HDMI 1.3a standard. - - - .. _`CEC-OP-CEC-VERSION-1-4B`: + - ``CEC_OP_CEC_VERSION_1_3A`` + - 4 + - CEC version according to the HDMI 1.3a standard. + * .. _`CEC-OP-CEC-VERSION-1-4B`: - - ``CEC_OP_CEC_VERSION_1_4B`` + - ``CEC_OP_CEC_VERSION_1_4B`` + - 5 + - CEC version according to the HDMI 1.4b standard. + * .. _`CEC-OP-CEC-VERSION-2-0`: - - 5 - - - CEC version according to the HDMI 1.4b standard. - - - .. _`CEC-OP-CEC-VERSION-2-0`: - - - ``CEC_OP_CEC_VERSION_2_0`` - - - 6 - - - CEC version according to the HDMI 2.0 standard. + - ``CEC_OP_CEC_VERSION_2_0`` + - 6 + - CEC version according to the HDMI 2.0 standard. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| @@ -269,62 +202,41 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 3 1 4 + * .. _`CEC-OP-PRIM-DEVTYPE-TV`: - - .. _`CEC-OP-PRIM-DEVTYPE-TV`: - - - ``CEC_OP_PRIM_DEVTYPE_TV`` - - - 0 + - ``CEC_OP_PRIM_DEVTYPE_TV`` + - 0 + - Use for a TV. + * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`: - - Use for a TV. + - ``CEC_OP_PRIM_DEVTYPE_RECORD`` + - 1 + - Use for a recording device. + * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`: - - .. _`CEC-OP-PRIM-DEVTYPE-RECORD`: + - ``CEC_OP_PRIM_DEVTYPE_TUNER`` + - 3 + - Use for a device with a tuner. + * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`: - - ``CEC_OP_PRIM_DEVTYPE_RECORD`` + - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK`` + - 4 + - Use for a playback device. + * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`: - - 1 + - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM`` + - 5 + - Use for an audio system (e.g. an audio/video receiver). + * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`: - - Use for a recording device. + - ``CEC_OP_PRIM_DEVTYPE_SWITCH`` + - 6 + - Use for a CEC switch. + * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`: - - .. _`CEC-OP-PRIM-DEVTYPE-TUNER`: - - - ``CEC_OP_PRIM_DEVTYPE_TUNER`` - - - 3 - - - Use for a device with a tuner. - - - .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`: - - - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK`` - - - 4 - - - Use for a playback device. - - - .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`: - - - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM`` - - - 5 - - - Use for an audio system (e.g. an audio/video receiver). - - - .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`: - - - ``CEC_OP_PRIM_DEVTYPE_SWITCH`` - - - 6 - - - Use for a CEC switch. - - - .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`: - - - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC`` - - - 7 - - - Use for a video processor device. + - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC`` + - 7 + - Use for a video processor device. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| @@ -336,64 +248,43 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 3 1 16 + * .. _`CEC-LOG-ADDR-TYPE-TV`: - - .. _`CEC-LOG-ADDR-TYPE-TV`: - - - ``CEC_LOG_ADDR_TYPE_TV`` - - - 0 - - - Use for a TV. - - - .. _`CEC-LOG-ADDR-TYPE-RECORD`: - - - ``CEC_LOG_ADDR_TYPE_RECORD`` - - - 1 - - - Use for a recording device. - - - .. _`CEC-LOG-ADDR-TYPE-TUNER`: - - - ``CEC_LOG_ADDR_TYPE_TUNER`` - - - 2 + - ``CEC_LOG_ADDR_TYPE_TV`` + - 0 + - Use for a TV. + * .. _`CEC-LOG-ADDR-TYPE-RECORD`: - - Use for a tuner device. + - ``CEC_LOG_ADDR_TYPE_RECORD`` + - 1 + - Use for a recording device. + * .. _`CEC-LOG-ADDR-TYPE-TUNER`: - - .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`: + - ``CEC_LOG_ADDR_TYPE_TUNER`` + - 2 + - Use for a tuner device. + * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`: - - ``CEC_LOG_ADDR_TYPE_PLAYBACK`` + - ``CEC_LOG_ADDR_TYPE_PLAYBACK`` + - 3 + - Use for a playback device. + * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`: - - 3 + - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM`` + - 4 + - Use for an audio system device. + * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`: - - Use for a playback device. + - ``CEC_LOG_ADDR_TYPE_SPECIFIC`` + - 5 + - Use for a second TV or for a video processor device. + * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`: - - .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`: - - - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM`` - - - 4 - - - Use for an audio system device. - - - .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`: - - - ``CEC_LOG_ADDR_TYPE_SPECIFIC`` - - - 5 - - - Use for a second TV or for a video processor device. - - - .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`: - - - ``CEC_LOG_ADDR_TYPE_UNREGISTERED`` - - - 6 - - - Use this if you just want to remain unregistered. Used for pure - CEC switches or CDC-only devices (CDC: Capability Discovery and - Control). + - ``CEC_LOG_ADDR_TYPE_UNREGISTERED`` + - 6 + - Use this if you just want to remain unregistered. Used for pure + CEC switches or CDC-only devices (CDC: Capability Discovery and + Control). @@ -406,54 +297,36 @@ logical address types are already defined will return with error ``EBUSY``. :stub-columns: 0 :widths: 3 1 4 + * .. _`CEC-OP-ALL-DEVTYPE-TV`: - - .. _`CEC-OP-ALL-DEVTYPE-TV`: - - - ``CEC_OP_ALL_DEVTYPE_TV`` - - - 0x80 - - - This supports the TV type. - - - .. _`CEC-OP-ALL-DEVTYPE-RECORD`: - - - ``CEC_OP_ALL_DEVTYPE_RECORD`` - - - 0x40 - - - This supports the Recording type. - - - .. _`CEC-OP-ALL-DEVTYPE-TUNER`: - - - ``CEC_OP_ALL_DEVTYPE_TUNER`` - - - 0x20 - - - This supports the Tuner type. - - - .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`: - - - ``CEC_OP_ALL_DEVTYPE_PLAYBACK`` - - - 0x10 - - - This supports the Playback type. - - - .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`: - - - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM`` - - - 0x08 + - ``CEC_OP_ALL_DEVTYPE_TV`` + - 0x80 + - This supports the TV type. + * .. _`CEC-OP-ALL-DEVTYPE-RECORD`: - - This supports the Audio System type. + - ``CEC_OP_ALL_DEVTYPE_RECORD`` + - 0x40 + - This supports the Recording type. + * .. _`CEC-OP-ALL-DEVTYPE-TUNER`: - - .. _`CEC-OP-ALL-DEVTYPE-SWITCH`: + - ``CEC_OP_ALL_DEVTYPE_TUNER`` + - 0x20 + - This supports the Tuner type. + * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`: - - ``CEC_OP_ALL_DEVTYPE_SWITCH`` + - ``CEC_OP_ALL_DEVTYPE_PLAYBACK`` + - 0x10 + - This supports the Playback type. + * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`: - - 0x04 + - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM`` + - 0x08 + - This supports the Audio System type. + * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`: - - This supports the CEC Switch or Video Processing type. + - ``CEC_OP_ALL_DEVTYPE_SWITCH`` + - 0x04 + - This supports the CEC Switch or Video Processing type. diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index e283588a830b..e256c6605de7 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -58,26 +58,16 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 1 1 8 - - - .. row 1 - - - __u16 - - - ``phys_addr`` - - - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no + * - __u16 + - ``phys_addr`` + - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no valid physical address is set. - - - .. row 2 - - - __u16 - - - ``log_addr_mask`` - - - The current set of claimed logical addresses. This is 0 if no logical - addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. - If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device - has the unregistered logical address. In that case all other bits are 0. + * - __u16 + - ``log_addr_mask`` + - The current set of claimed logical addresses. This is 0 if no logical + addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. + If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device + has the unregistered logical address. In that case all other bits are 0. .. c:type:: cec_event_lost_msgs @@ -89,22 +79,17 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 1 1 16 - - - .. row 1 - - - __u32 - - - ``lost_msgs`` - - - Set to the number of lost messages since the filehandle was opened - or since the last time this event was dequeued for this - filehandle. The messages lost are the oldest messages. So when a - new message arrives and there is no more room, then the oldest - message is discarded to make room for the new one. The internal - size of the message queue guarantees that all messages received in - the last two seconds will be stored. Since messages should be - replied to within a second according to the CEC specification, - this is more than enough. + * - __u32 + - ``lost_msgs`` + - Set to the number of lost messages since the filehandle was opened + or since the last time this event was dequeued for this + filehandle. The messages lost are the oldest messages. So when a + new message arrives and there is no more room, then the oldest + message is discarded to make room for the new one. The internal + size of the message queue guarantees that all messages received in + the last two seconds will be stored. Since messages should be + replied to within a second according to the CEC specification, + this is more than enough. .. tabularcolumns:: |p{1.0cm}|p{4.2cm}|p{2.5cm}|p{8.8cm}| @@ -116,62 +101,32 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 1 1 1 8 - - - .. row 1 - - - __u64 - - - ``ts`` - - - :cspan:`1` Timestamp of the event in ns. - - The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access - the same clock from userspace use :c:func:`clock_gettime`. - - - .. row 2 - - - __u32 - - - ``event`` - - - :cspan:`1` The CEC event type, see :ref:`cec-events`. - - - .. row 3 - - - __u32 - - - ``flags`` - - - :cspan:`1` Event flags, see :ref:`cec-event-flags`. - - - .. row 4 - - - union - - - (anonymous) - - - - - - - - .. row 5 - - - - - struct cec_event_state_change - - - ``state_change`` - - - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE ` - event. - - - .. row 6 - - - - - struct cec_event_lost_msgs - - - ``lost_msgs`` - - - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS ` - event. + * - __u64 + - ``ts`` + - :cspan:`1` Timestamp of the event in ns. + + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access + the same clock from userspace use :c:func:`clock_gettime`. + * - __u32 + - ``event`` + - :cspan:`1` The CEC event type, see :ref:`cec-events`. + * - __u32 + - ``flags`` + - :cspan:`1` Event flags, see :ref:`cec-event-flags`. + * - union + - (anonymous) + - + - + * - + - struct cec_event_state_change + - ``state_change`` + - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE ` + event. + * - + - struct cec_event_lost_msgs + - ``lost_msgs`` + - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS ` + event. .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| @@ -183,25 +138,19 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 3 1 16 + * .. _`CEC-EVENT-STATE-CHANGE`: - - .. _`CEC-EVENT-STATE-CHANGE`: - - - ``CEC_EVENT_STATE_CHANGE`` - - - 1 - - - Generated when the CEC Adapter's state changes. When open() is - called an initial event will be generated for that filehandle with - the CEC Adapter's state at that time. - - - .. _`CEC-EVENT-LOST-MSGS`: + - ``CEC_EVENT_STATE_CHANGE`` + - 1 + - Generated when the CEC Adapter's state changes. When open() is + called an initial event will be generated for that filehandle with + the CEC Adapter's state at that time. + * .. _`CEC-EVENT-LOST-MSGS`: - - ``CEC_EVENT_LOST_MSGS`` - - - 2 - - - Generated if one or more CEC messages were lost because the - application didn't dequeue CEC messages fast enough. + - ``CEC_EVENT_LOST_MSGS`` + - 2 + - Generated if one or more CEC messages were lost because the + application didn't dequeue CEC messages fast enough. .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| @@ -213,17 +162,14 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 3 1 8 + * .. _`CEC-EVENT-FL-INITIAL-VALUE`: - - .. _`CEC-EVENT-FL-INITIAL-VALUE`: - - - ``CEC_EVENT_FL_INITIAL_VALUE`` - - - 1 - - - Set for the initial events that are generated when the device is - opened. See the table above for which events do this. This allows - applications to learn the initial state of the CEC adapter at - open() time. + - ``CEC_EVENT_FL_INITIAL_VALUE`` + - 1 + - Set for the initial events that are generated when the device is + opened. See the table above for which events do this. This allows + applications to learn the initial state of the CEC adapter at + open() time. diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst index 70a41902ab58..4f5818b9d277 100644 --- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst @@ -83,37 +83,28 @@ Available initiator modes are: :stub-columns: 0 :widths: 3 1 16 - - - .. _`CEC-MODE-NO-INITIATOR`: - - - ``CEC_MODE_NO_INITIATOR`` - - - 0x0 - - - This is not an initiator, i.e. it cannot transmit CEC messages or - make any other changes to the CEC adapter. - - - .. _`CEC-MODE-INITIATOR`: - - - ``CEC_MODE_INITIATOR`` - - - 0x1 - - - This is an initiator (the default when the device is opened) and - it can transmit CEC messages and make changes to the CEC adapter, - unless there is an exclusive initiator. - - - .. _`CEC-MODE-EXCL-INITIATOR`: - - - ``CEC_MODE_EXCL_INITIATOR`` - - - 0x2 - - - This is an exclusive initiator and this file descriptor is the - only one that can transmit CEC messages and make changes to the - CEC adapter. If someone else is already the exclusive initiator - then an attempt to become one will return the ``EBUSY`` error code - error. + * .. _`CEC-MODE-NO-INITIATOR`: + + - ``CEC_MODE_NO_INITIATOR`` + - 0x0 + - This is not an initiator, i.e. it cannot transmit CEC messages or + make any other changes to the CEC adapter. + * .. _`CEC-MODE-INITIATOR`: + + - ``CEC_MODE_INITIATOR`` + - 0x1 + - This is an initiator (the default when the device is opened) and + it can transmit CEC messages and make changes to the CEC adapter, + unless there is an exclusive initiator. + * .. _`CEC-MODE-EXCL-INITIATOR`: + + - ``CEC_MODE_EXCL_INITIATOR`` + - 0x2 + - This is an exclusive initiator and this file descriptor is the + only one that can transmit CEC messages and make changes to the + CEC adapter. If someone else is already the exclusive initiator + then an attempt to become one will return the ``EBUSY`` error code + error. Available follower modes are: @@ -127,86 +118,68 @@ Available follower modes are: :stub-columns: 0 :widths: 3 1 16 - - - .. _`CEC-MODE-NO-FOLLOWER`: - - - ``CEC_MODE_NO_FOLLOWER`` - - - 0x00 - - - This is not a follower (the default when the device is opened). - - - .. _`CEC-MODE-FOLLOWER`: - - - ``CEC_MODE_FOLLOWER`` - - - 0x10 - - - This is a follower and it will receive CEC messages unless there - is an exclusive follower. You cannot become a follower if - :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` - was specified, the ``EINVAL`` error code is returned in that case. - - - .. _`CEC-MODE-EXCL-FOLLOWER`: - - - ``CEC_MODE_EXCL_FOLLOWER`` - - - 0x20 - - - This is an exclusive follower and only this file descriptor will - receive CEC messages for processing. If someone else is already - the exclusive follower then an attempt to become one will return - the ``EBUSY`` error code. You cannot become a follower if - :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` - was specified, the ``EINVAL`` error code is returned in that case. - - - .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`: - - - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU`` - - - 0x30 - - - This is an exclusive follower and only this file descriptor will - receive CEC messages for processing. In addition it will put the - CEC device into passthrough mode, allowing the exclusive follower - to handle most core messages instead of relying on the CEC - framework for that. If someone else is already the exclusive - follower then an attempt to become one will return the ``EBUSY`` error - code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` - is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, - the ``EINVAL`` error code is returned in that case. - - - .. _`CEC-MODE-MONITOR`: - - - ``CEC_MODE_MONITOR`` - - - 0xe0 - - - Put the file descriptor into monitor mode. Can only be used in - combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error - code will be returned. In monitor mode all messages this CEC - device transmits and all messages it receives (both broadcast - messages and directed messages for one its logical addresses) will - be reported. This is very useful for debugging. This is only - allowed if the process has the ``CAP_NET_ADMIN`` capability. If - that is not set, then the ``EPERM`` error code is returned. - - - .. _`CEC-MODE-MONITOR-ALL`: - - - ``CEC_MODE_MONITOR_ALL`` - - - 0xf0 - - - Put the file descriptor into 'monitor all' mode. Can only be used - in combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise - the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages - this CEC device transmits and all messages it receives, including - directed messages for other CEC devices will be reported. This is - very useful for debugging, but not all devices support this. This - mode requires that the :ref:`CEC_CAP_MONITOR_ALL ` capability is set, - otherwise the ``EINVAL`` error code is returned. This is only allowed if - the process has the ``CAP_NET_ADMIN`` capability. If that is not - set, then the ``EPERM`` error code is returned. + * .. _`CEC-MODE-NO-FOLLOWER`: + + - ``CEC_MODE_NO_FOLLOWER`` + - 0x00 + - This is not a follower (the default when the device is opened). + * .. _`CEC-MODE-FOLLOWER`: + + - ``CEC_MODE_FOLLOWER`` + - 0x10 + - This is a follower and it will receive CEC messages unless there + is an exclusive follower. You cannot become a follower if + :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` + was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-EXCL-FOLLOWER`: + + - ``CEC_MODE_EXCL_FOLLOWER`` + - 0x20 + - This is an exclusive follower and only this file descriptor will + receive CEC messages for processing. If someone else is already + the exclusive follower then an attempt to become one will return + the ``EBUSY`` error code. You cannot become a follower if + :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` + was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`: + + - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU`` + - 0x30 + - This is an exclusive follower and only this file descriptor will + receive CEC messages for processing. In addition it will put the + CEC device into passthrough mode, allowing the exclusive follower + to handle most core messages instead of relying on the CEC + framework for that. If someone else is already the exclusive + follower then an attempt to become one will return the ``EBUSY`` error + code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` + is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, + the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-MONITOR`: + + - ``CEC_MODE_MONITOR`` + - 0xe0 + - Put the file descriptor into monitor mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error + code will be returned. In monitor mode all messages this CEC + device transmits and all messages it receives (both broadcast + messages and directed messages for one its logical addresses) will + be reported. This is very useful for debugging. This is only + allowed if the process has the ``CAP_NET_ADMIN`` capability. If + that is not set, then the ``EPERM`` error code is returned. + * .. _`CEC-MODE-MONITOR-ALL`: + + - ``CEC_MODE_MONITOR_ALL`` + - 0xf0 + - Put the file descriptor into 'monitor all' mode. Can only be used + in combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise + the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages + this CEC device transmits and all messages it receives, including + directed messages for other CEC devices will be reported. This is + very useful for debugging, but not all devices support this. This + mode requires that the :ref:`CEC_CAP_MONITOR_ALL ` capability is set, + otherwise the ``EINVAL`` error code is returned. This is only allowed if + the process has the ``CAP_NET_ADMIN`` capability. If that is not + set, then the ``EPERM`` error code is returned. Core message processing details: @@ -220,76 +193,58 @@ Core message processing details: :stub-columns: 0 :widths: 1 8 - - - .. _`CEC-MSG-GET-CEC-VERSION`: - - - ``CEC_MSG_GET_CEC_VERSION`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the CEC version that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. - - - .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: - - - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the vendor ID that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. - - - .. _`CEC-MSG-ABORT`: - - - ``CEC_MSG_ABORT`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return a feature refused - message as per the specification. - - - .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: - - - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current physical - address. - - - .. _`CEC-MSG-GIVE-OSD-NAME`: - - - ``CEC_MSG_GIVE_OSD_NAME`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current OSD name as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. - - - .. _`CEC-MSG-GIVE-FEATURES`: - - - ``CEC_MSG_GIVE_FEATURES`` - - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current features as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` - or the message is ignored if the CEC version was older than 2.0. - - - .. _`CEC-MSG-USER-CONTROL-PRESSED`: - - - ``CEC_MSG_USER_CONTROL_PRESSED`` - - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - press. This message is always passed on to userspace. - - - .. _`CEC-MSG-USER-CONTROL-RELEASED`: - - - ``CEC_MSG_USER_CONTROL_RELEASED`` - - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - release. This message is always passed on to userspace. - - - .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: - - - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` - - - The CEC framework will make note of the reported physical address - and then just pass the message on to userspace. + * .. _`CEC-MSG-GET-CEC-VERSION`: + + - ``CEC_MSG_GET_CEC_VERSION`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will return the CEC version that was + set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: + + - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will return the vendor ID that was + set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + * .. _`CEC-MSG-ABORT`: + + - ``CEC_MSG_ABORT`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will return a feature refused + message as per the specification. + * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: + + - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will report the current physical + address. + * .. _`CEC-MSG-GIVE-OSD-NAME`: + + - ``CEC_MSG_GIVE_OSD_NAME`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will report the current OSD name as + was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + * .. _`CEC-MSG-GIVE-FEATURES`: + + - ``CEC_MSG_GIVE_FEATURES`` + - When in passthrough mode this message has to be handled by + userspace, otherwise the core will report the current features as + was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` + or the message is ignored if the CEC version was older than 2.0. + * .. _`CEC-MSG-USER-CONTROL-PRESSED`: + + - ``CEC_MSG_USER_CONTROL_PRESSED`` + - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key + press. This message is always passed on to userspace. + * .. _`CEC-MSG-USER-CONTROL-RELEASED`: + + - ``CEC_MSG_USER_CONTROL_RELEASED`` + - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key + release. This message is always passed on to userspace. + * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: + + - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` + - The CEC framework will make note of the reported physical address + and then just pass the message on to userspace. diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index d585b1bba6ac..21a88df3d9d9 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -86,173 +86,98 @@ result. :stub-columns: 0 :widths: 1 1 16 - - - .. row 1 - - - __u64 - - - ``tx_ts`` - - - Timestamp in ns of when the last byte of the message was transmitted. - The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access - the same clock from userspace use :c:func:`clock_gettime`. - - - .. row 2 - - - __u64 - - - ``rx_ts`` - - - Timestamp in ns of when the last byte of the message was received. - The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access - the same clock from userspace use :c:func:`clock_gettime`. - - - .. row 3 - - - __u32 - - - ``len`` - - - The length of the message. For :ref:`ioctl CEC_TRANSMIT ` this is filled in - by the application. The driver will fill this in for - :ref:`ioctl CEC_RECEIVE `. For :ref:`ioctl CEC_TRANSMIT ` it will be - filled in by the driver with the length of the reply message if ``reply`` was set. - - - .. row 4 - - - __u32 - - - ``timeout`` - - - The timeout in milliseconds. This is the time the device will wait - for a message to be received before timing out. If it is set to 0, - then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE `. - If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT `, - then it will be replaced by 1000 if the ``reply`` is non-zero or - ignored if ``reply`` is 0. - - - .. row 5 - - - __u32 - - - ``sequence`` - - - A non-zero sequence number is automatically assigned by the CEC framework - for all transmitted messages. It is used by the CEC framework when it queues - the transmit result (when transmit was called in non-blocking mode). This - allows the application to associate the received message with the original - transmit. - - - .. row 6 - - - __u32 - - - ``flags`` - - - Flags. No flags are defined yet, so set this to 0. - - - .. row 7 - - - __u8 - - - ``tx_status`` - - - The status bits of the transmitted message. See - :ref:`cec-tx-status` for the possible status values. It is 0 if - this messages was received, not transmitted. - - - .. row 8 - - - __u8 - - - ``msg[16]`` - - - The message payload. For :ref:`ioctl CEC_TRANSMIT ` this is filled in by the - application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE `. - For :ref:`ioctl CEC_TRANSMIT ` it will be filled in by the driver with - the payload of the reply message if ``timeout`` was set. - - - .. row 8 - - - __u8 - - - ``reply`` - - - Wait until this message is replied. If ``reply`` is 0 and the - ``timeout`` is 0, then don't wait for a reply but return after - transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE `. - The case where ``reply`` is 0 (this is the opcode for the Feature Abort - message) and ``timeout`` is non-zero is specifically allowed to make it - possible to send a message and wait up to ``timeout`` milliseconds for a - Feature Abort reply. In this case ``rx_status`` will either be set - to :ref:`CEC_RX_STATUS_TIMEOUT ` or - :ref:`CEC_RX_STATUS_FEATURE_ABORT `. - - - .. row 9 - - - __u8 - - - ``rx_status`` - - - The status bits of the received message. See - :ref:`cec-rx-status` for the possible status values. It is 0 if - this message was transmitted, not received, unless this is the - reply to a transmitted message. In that case both ``rx_status`` - and ``tx_status`` are set. - - - .. row 10 - - - __u8 - - - ``tx_status`` - - - The status bits of the transmitted message. See - :ref:`cec-tx-status` for the possible status values. It is 0 if - this messages was received, not transmitted. - - - .. row 11 - - - __u8 - - - ``tx_arb_lost_cnt`` - - - A counter of the number of transmit attempts that resulted in the - Arbitration Lost error. This is only set if the hardware supports - this, otherwise it is always 0. This counter is only valid if the - :ref:`CEC_TX_STATUS_ARB_LOST ` status bit is set. - - - .. row 12 - - - __u8 - - - ``tx_nack_cnt`` - - - A counter of the number of transmit attempts that resulted in the - Not Acknowledged error. This is only set if the hardware supports - this, otherwise it is always 0. This counter is only valid if the - :ref:`CEC_TX_STATUS_NACK ` status bit is set. - - - .. row 13 - - - __u8 - - - ``tx_low_drive_cnt`` - - - A counter of the number of transmit attempts that resulted in the - Arbitration Lost error. This is only set if the hardware supports - this, otherwise it is always 0. This counter is only valid if the - :ref:`CEC_TX_STATUS_LOW_DRIVE ` status bit is set. - - - .. row 14 - - - __u8 - - - ``tx_error_cnt`` - - - A counter of the number of transmit errors other than Arbitration - Lost or Not Acknowledged. This is only set if the hardware - supports this, otherwise it is always 0. This counter is only - valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. + * - __u64 + - ``tx_ts`` + - Timestamp in ns of when the last byte of the message was transmitted. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access + the same clock from userspace use :c:func:`clock_gettime`. + * - __u64 + - ``rx_ts`` + - Timestamp in ns of when the last byte of the message was received. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access + the same clock from userspace use :c:func:`clock_gettime`. + * - __u32 + - ``len`` + - The length of the message. For :ref:`ioctl CEC_TRANSMIT ` this is filled in + by the application. The driver will fill this in for + :ref:`ioctl CEC_RECEIVE `. For :ref:`ioctl CEC_TRANSMIT ` it will be + filled in by the driver with the length of the reply message if ``reply`` was set. + * - __u32 + - ``timeout`` + - The timeout in milliseconds. This is the time the device will wait + for a message to be received before timing out. If it is set to 0, + then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE `. + If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT `, + then it will be replaced by 1000 if the ``reply`` is non-zero or + ignored if ``reply`` is 0. + * - __u32 + - ``sequence`` + - A non-zero sequence number is automatically assigned by the CEC framework + for all transmitted messages. It is used by the CEC framework when it queues + the transmit result (when transmit was called in non-blocking mode). This + allows the application to associate the received message with the original + transmit. + * - __u32 + - ``flags`` + - Flags. No flags are defined yet, so set this to 0. + * - __u8 + - ``tx_status`` + - The status bits of the transmitted message. See + :ref:`cec-tx-status` for the possible status values. It is 0 if + this messages was received, not transmitted. + * - __u8 + - ``msg[16]`` + - The message payload. For :ref:`ioctl CEC_TRANSMIT ` this is filled in by the + application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE `. + For :ref:`ioctl CEC_TRANSMIT ` it will be filled in by the driver with + the payload of the reply message if ``timeout`` was set. + * - __u8 + - ``reply`` + - Wait until this message is replied. If ``reply`` is 0 and the + ``timeout`` is 0, then don't wait for a reply but return after + transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE `. + The case where ``reply`` is 0 (this is the opcode for the Feature Abort + message) and ``timeout`` is non-zero is specifically allowed to make it + possible to send a message and wait up to ``timeout`` milliseconds for a + Feature Abort reply. In this case ``rx_status`` will either be set + to :ref:`CEC_RX_STATUS_TIMEOUT ` or + :ref:`CEC_RX_STATUS_FEATURE_ABORT `. + * - __u8 + - ``rx_status`` + - The status bits of the received message. See + :ref:`cec-rx-status` for the possible status values. It is 0 if + this message was transmitted, not received, unless this is the + reply to a transmitted message. In that case both ``rx_status`` + and ``tx_status`` are set. + * - __u8 + - ``tx_status`` + - The status bits of the transmitted message. See + :ref:`cec-tx-status` for the possible status values. It is 0 if + this messages was received, not transmitted. + * - __u8 + - ``tx_arb_lost_cnt`` + - A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_ARB_LOST ` status bit is set. + * - __u8 + - ``tx_nack_cnt`` + - A counter of the number of transmit attempts that resulted in the + Not Acknowledged error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_NACK ` status bit is set. + * - __u8 + - ``tx_low_drive_cnt`` + - A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_LOW_DRIVE ` status bit is set. + * - __u8 + - ``tx_error_cnt`` + - A counter of the number of transmit errors other than Arbitration + Lost or Not Acknowledged. This is only set if the hardware + supports this, otherwise it is always 0. This counter is only + valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| @@ -264,64 +189,46 @@ result. :stub-columns: 0 :widths: 3 1 16 - - - .. _`CEC-TX-STATUS-OK`: - - - ``CEC_TX_STATUS_OK`` - - - 0x01 - - - The message was transmitted successfully. This is mutually - exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. Other bits can still - be set if earlier attempts met with failure before the transmit - was eventually successful. - - - .. _`CEC-TX-STATUS-ARB-LOST`: - - - ``CEC_TX_STATUS_ARB_LOST`` - - - 0x02 - - - CEC line arbitration was lost. - - - .. _`CEC-TX-STATUS-NACK`: - - - ``CEC_TX_STATUS_NACK`` - - - 0x04 - - - Message was not acknowledged. - - - .. _`CEC-TX-STATUS-LOW-DRIVE`: - - - ``CEC_TX_STATUS_LOW_DRIVE`` - - - 0x08 - - - Low drive was detected on the CEC bus. This indicates that a - follower detected an error on the bus and requests a - retransmission. - - - .. _`CEC-TX-STATUS-ERROR`: - - - ``CEC_TX_STATUS_ERROR`` - - - 0x10 - - - Some error occurred. This is used for any errors that do not fit - the previous two, either because the hardware could not tell which - error occurred, or because the hardware tested for other - conditions besides those two. - - - .. _`CEC-TX-STATUS-MAX-RETRIES`: - - - ``CEC_TX_STATUS_MAX_RETRIES`` - - - 0x20 - - - The transmit failed after one or more retries. This status bit is - mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still - be set to explain which failures were seen. + * .. _`CEC-TX-STATUS-OK`: + + - ``CEC_TX_STATUS_OK`` + - 0x01 + - The message was transmitted successfully. This is mutually + exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. Other bits can still + be set if earlier attempts met with failure before the transmit + was eventually successful. + * .. _`CEC-TX-STATUS-ARB-LOST`: + + - ``CEC_TX_STATUS_ARB_LOST`` + - 0x02 + - CEC line arbitration was lost. + * .. _`CEC-TX-STATUS-NACK`: + + - ``CEC_TX_STATUS_NACK`` + - 0x04 + - Message was not acknowledged. + * .. _`CEC-TX-STATUS-LOW-DRIVE`: + + - ``CEC_TX_STATUS_LOW_DRIVE`` + - 0x08 + - Low drive was detected on the CEC bus. This indicates that a + follower detected an error on the bus and requests a + retransmission. + * .. _`CEC-TX-STATUS-ERROR`: + + - ``CEC_TX_STATUS_ERROR`` + - 0x10 + - Some error occurred. This is used for any errors that do not fit + the previous two, either because the hardware could not tell which + error occurred, or because the hardware tested for other + conditions besides those two. + * .. _`CEC-TX-STATUS-MAX-RETRIES`: + + - ``CEC_TX_STATUS_MAX_RETRIES`` + - 0x20 + - The transmit failed after one or more retries. This status bit is + mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still + be set to explain which failures were seen. .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| @@ -333,32 +240,23 @@ result. :stub-columns: 0 :widths: 3 1 16 + * .. _`CEC-RX-STATUS-OK`: - - .. _`CEC-RX-STATUS-OK`: - - - ``CEC_RX_STATUS_OK`` - - - 0x01 - - - The message was received successfully. - - - .. _`CEC-RX-STATUS-TIMEOUT`: - - - ``CEC_RX_STATUS_TIMEOUT`` - - - 0x02 - - - The reply to an earlier transmitted message timed out. - - - .. _`CEC-RX-STATUS-FEATURE-ABORT`: - - - ``CEC_RX_STATUS_FEATURE_ABORT`` + - ``CEC_RX_STATUS_OK`` + - 0x01 + - The message was received successfully. + * .. _`CEC-RX-STATUS-TIMEOUT`: - - 0x04 + - ``CEC_RX_STATUS_TIMEOUT`` + - 0x02 + - The reply to an earlier transmitted message timed out. + * .. _`CEC-RX-STATUS-FEATURE-ABORT`: - - The message was received successfully but the reply was - ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message - was the reply to an earlier transmitted message. + - ``CEC_RX_STATUS_FEATURE_ABORT`` + - 0x04 + - The message was received successfully but the reply was + ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message + was the reply to an earlier transmitted message. -- cgit v1.2.3 From f4062625ede8f0280d8246437f4070c8eb7fe9f3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 07:59:34 -0200 Subject: [media] cec: add flag to cec_log_addrs to enable RC passthrough By default the CEC_MSG_USER_CONTROL_PRESSED/RELEASED messages are passed on to the follower(s) only. If the new CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU flag is set in the flags field of struct cec_log_addrs then these messages are also passed on to the remote control input subsystem and they will appear as keystrokes. This used to be the default behavior, but now you have to explicitly enable it. This is done to force the caller to think about possible security issues (e.g. if these messages are used to enter passwords). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 10 ++++++++++ drivers/staging/media/cec/TODO | 2 -- drivers/staging/media/cec/cec-adap.c | 6 ++++-- drivers/staging/media/cec/cec-api.c | 3 ++- include/linux/cec.h | 2 ++ 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index af35f7185439..571ae57b75ae 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -166,6 +166,16 @@ logical address types are already defined will return with error ``EBUSY``. it will go back to the unconfigured state. If this flag is set, then it will fallback to the Unregistered logical address. Note that if the Unregistered logical address was explicitly requested, then this flag has no effect. + * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`: + + - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU`` + - 2 + - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED`` + messages are only passed on to the follower(s), if any. If this flag is set, + then these messages are also passed on to the remote control input subsystem + and will appear as keystrokes. This features needs to be enabled explicitly. + If CEC is used to enter e.g. passwords, then you may not want to enable this + to avoid trivial snooping of the keystrokes. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO index 13224694a8ae..084120687d06 100644 --- a/drivers/staging/media/cec/TODO +++ b/drivers/staging/media/cec/TODO @@ -13,8 +13,6 @@ Hopefully this will happen later in 2016. Other TODOs: - There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that? -- Add a flag to inhibit passing CEC RC messages to the rc subsystem. - Applications should be able to choose this when calling S_LOG_ADDRS. - If the reply field of cec_msg is set then when the reply arrives it is only sent to the filehandle that transmitted the original message and not to any followers. Should this behavior change or perhaps diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index 611e07b78bfe..589e4576fbe9 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -1478,7 +1478,8 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, } case CEC_MSG_USER_CONTROL_PRESSED: - if (!(adap->capabilities & CEC_CAP_RC)) + if (!(adap->capabilities & CEC_CAP_RC) || + !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) break; #if IS_REACHABLE(CONFIG_RC_CORE) @@ -1515,7 +1516,8 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, break; case CEC_MSG_USER_CONTROL_RELEASED: - if (!(adap->capabilities & CEC_CAP_RC)) + if (!(adap->capabilities & CEC_CAP_RC) || + !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) break; #if IS_REACHABLE(CONFIG_RC_CORE) rc_keyup(adap->rc); diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c index e274e2f22398..040ca7ddf2b0 100644 --- a/drivers/staging/media/cec/cec-api.c +++ b/drivers/staging/media/cec/cec-api.c @@ -162,7 +162,8 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, return -ENOTTY; if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) return -EFAULT; - log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK; + log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK | + CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU; mutex_lock(&adap->lock); if (!adap->is_configuring && (!log_addrs.num_log_addrs || !adap->is_configured) && diff --git a/include/linux/cec.h b/include/linux/cec.h index 851968e803fa..825455fae3cc 100644 --- a/include/linux/cec.h +++ b/include/linux/cec.h @@ -391,6 +391,8 @@ struct cec_log_addrs { /* Allow a fallback to unregistered */ #define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) +/* Passthrough RC messages to the input subsystem */ +#define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1) /* Events */ -- cgit v1.2.3 From adc0c622783978ab0c740af77f98fc8f65c87d66 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 08:55:05 -0200 Subject: [media] cec: add CEC_MSG_FL_REPLY_TO_FOLLOWERS Give the caller more control over how replies to a transmit are handled. By default the reply will only go to the filehandle that called CEC_TRANSMIT. If this new flag is set, then the reply will also go to all followers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-receive.rst | 22 +++++++++++++++++++++- drivers/staging/media/cec/TODO | 4 ---- drivers/staging/media/cec/cec-adap.c | 6 +++--- drivers/staging/media/cec/cec-api.c | 1 + include/linux/cec.h | 5 ++++- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index 21a88df3d9d9..b4dffd2f7dfa 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -119,7 +119,7 @@ result. transmit. * - __u32 - ``flags`` - - Flags. No flags are defined yet, so set this to 0. + - Flags. See :ref:`cec-msg-flags` for a list of available flags. * - __u8 - ``tx_status`` - The status bits of the transmitted message. See @@ -180,6 +180,26 @@ result. valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. +.. _cec-msg-flags: + +.. flat-table:: Flags for struct cec_msg + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`: + + - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS`` + - 1 + - If a CEC transmit expects a reply, then by default that reply is only sent to + the filehandle that called :ref:`ioctl CEC_TRANSMIT `. If this + flag is set, then the reply is also sent to all followers, if any. If the + filehandle that called :ref:`ioctl CEC_TRANSMIT ` is also a + follower, then that filehandle will receive the reply twice: once as the + result of the :ref:`ioctl CEC_TRANSMIT `, and once via + :ref:`ioctl CEC_RECEIVE `. + + .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| .. _cec-tx-status: diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO index 084120687d06..ce69001b0428 100644 --- a/drivers/staging/media/cec/TODO +++ b/drivers/staging/media/cec/TODO @@ -13,10 +13,6 @@ Hopefully this will happen later in 2016. Other TODOs: - There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that? -- If the reply field of cec_msg is set then when the reply arrives it - is only sent to the filehandle that transmitted the original message - and not to any followers. Should this behavior change or perhaps - controlled through a cec_msg flag? - Should CEC_LOG_ADDR_TYPE_SPECIFIC be replaced by TYPE_2ND_TV and TYPE_PROCESSOR? And also TYPE_SWITCH and TYPE_CDC_ONLY in addition to the TYPE_UNREGISTERED? This should give the framework more information about the device type diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index 589e4576fbe9..6aceb1d4a7a0 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -587,7 +587,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, msg->tx_nack_cnt = 0; msg->tx_low_drive_cnt = 0; msg->tx_error_cnt = 0; - msg->flags = 0; msg->sequence = ++adap->sequence; if (!msg->sequence) msg->sequence = ++adap->sequence; @@ -823,6 +822,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) dst->rx_status = msg->rx_status; if (abort) dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; + msg->flags = dst->flags; /* Remove it from the wait_queue */ list_del_init(&data->list); @@ -1575,8 +1575,8 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, } skip_processing: - /* If this was a reply, then we're done */ - if (is_reply) + /* If this was a reply, then we're done, unless otherwise specified */ + if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS)) return 0; /* diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c index 040ca7ddf2b0..54148a6b3326 100644 --- a/drivers/staging/media/cec/cec-api.c +++ b/drivers/staging/media/cec/cec-api.c @@ -190,6 +190,7 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, return -ENOTTY; if (copy_from_user(&msg, parg, sizeof(msg))) return -EFAULT; + msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; mutex_lock(&adap->lock); if (!adap->is_configured) err = -ENONET; diff --git a/include/linux/cec.h b/include/linux/cec.h index 825455fae3cc..3f2f076027b1 100644 --- a/include/linux/cec.h +++ b/include/linux/cec.h @@ -175,7 +175,10 @@ static inline void cec_msg_set_reply_to(struct cec_msg *msg, msg->reply = msg->timeout = 0; } -/* cec status field */ +/* cec_msg flags field */ +#define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0) + +/* cec_msg tx/rx_status field */ #define CEC_TX_STATUS_OK (1 << 0) #define CEC_TX_STATUS_ARB_LOST (1 << 1) #define CEC_TX_STATUS_NACK (1 << 2) -- cgit v1.2.3 From 3074fe4a7da5775bcf31675d6d9e2687c434fef2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 10:48:22 -0200 Subject: [media] cec: filter invalid messages As per the CEC specification: - CEC messages with a too-small payload should be ignored. - Broadcast messages that are only allowed as directed messages should be ignored. - Directed messages that are only allowed as broadcast messages should be ignored. Implement this in the core CEC framework. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/cec/cec-adap.c | 157 ++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index 6aceb1d4a7a0..93b53e602e48 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -762,14 +762,105 @@ EXPORT_SYMBOL_GPL(cec_transmit_msg); static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, bool is_reply); +#define DIRECTED 0x80 +#define BCAST1_4 0x40 +#define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */ +#define BCAST (BCAST1_4 | BCAST2_0) +#define BOTH (BCAST | DIRECTED) + +/* + * Specify minimum length and whether the message is directed, broadcast + * or both. Messages that do not match the criteria are ignored as per + * the CEC specification. + */ +static const u8 cec_msg_size[256] = { + [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST, + [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED, + [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED, + [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED, + [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST, + [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST, + [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST, + [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST, + [CEC_MSG_STANDBY] = 2 | BOTH, + [CEC_MSG_RECORD_OFF] = 2 | DIRECTED, + [CEC_MSG_RECORD_ON] = 3 | DIRECTED, + [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED, + [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED, + [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED, + [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED, + [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED, + [CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED, + [CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED, + [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED, + [CEC_MSG_CEC_VERSION] = 3 | DIRECTED, + [CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED, + [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED, + [CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED, + [CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST, + [CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST, + [CEC_MSG_REPORT_FEATURES] = 6 | BCAST, + [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED, + [CEC_MSG_DECK_CONTROL] = 3 | DIRECTED, + [CEC_MSG_DECK_STATUS] = 3 | DIRECTED, + [CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED, + [CEC_MSG_PLAY] = 3 | DIRECTED, + [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED, + [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED, + [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED, + [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED, + [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED, + [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED, + [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST, + [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED, + [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED, + [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH, + [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH, + [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH, + [CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED, + [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED, + [CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED, + [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED, + [CEC_MSG_MENU_STATUS] = 3 | DIRECTED, + [CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED, + [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED, + [CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED, + [CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0, + [CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED, + [CEC_MSG_ABORT] = 2 | DIRECTED, + [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED, + [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED, + [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED, + [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, + [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, + [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, + [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, + [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, + [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED, + [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED, + [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED, + [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED, + [CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED, + [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, + [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, + [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, + [CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST, + [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, +}; + /* Called by the CEC adapter if a message is received */ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) { struct cec_data *data; u8 msg_init = cec_msg_initiator(msg); u8 msg_dest = cec_msg_destination(msg); + u8 cmd = msg->msg[1]; bool is_reply = false; bool valid_la = true; + u8 min_len = 0; if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) return; @@ -789,9 +880,71 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) if (!cec_msg_is_broadcast(msg)) valid_la = cec_has_log_addr(adap, msg_dest); + /* + * Check if the length is not too short or if the message is a + * broadcast message where a directed message was expected or + * vice versa. If so, then the message has to be ignored (according + * to section CEC 7.3 and CEC 12.2). + */ + if (valid_la && msg->len > 1 && cec_msg_size[cmd]) { + u8 dir_fl = cec_msg_size[cmd] & BOTH; + + min_len = cec_msg_size[cmd] & 0x1f; + if (msg->len < min_len) + valid_la = false; + else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) + valid_la = false; + else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) + valid_la = false; + else if (cec_msg_is_broadcast(msg) && + adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && + !(dir_fl & BCAST2_0)) + valid_la = false; + } + if (valid_la && min_len) { + /* These messages have special length requirements */ + switch (cmd) { + case CEC_MSG_TIMER_STATUS: + if (msg->msg[2] & 0x10) { + switch (msg->msg[2] & 0xf) { + case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: + case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: + if (msg->len < 5) + valid_la = false; + break; + } + } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { + if (msg->len < 5) + valid_la = false; + } + break; + case CEC_MSG_RECORD_ON: + switch (msg->msg[2]) { + case CEC_OP_RECORD_SRC_OWN: + break; + case CEC_OP_RECORD_SRC_DIGITAL: + if (msg->len < 10) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_ANALOG: + if (msg->len < 7) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_EXT_PLUG: + if (msg->len < 4) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: + if (msg->len < 5) + valid_la = false; + break; + } + break; + } + } + /* It's a valid message and not a poll or CDC message */ - if (valid_la && msg->len > 1 && msg->msg[1] != CEC_MSG_CDC_MESSAGE) { - u8 cmd = msg->msg[1]; + if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) { bool abort = cmd == CEC_MSG_FEATURE_ABORT; /* The aborted command is in msg[2] */ -- cgit v1.2.3 From f5580d8d6fd07a569e468fca51f435aa5b122fc4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Nov 2016 11:07:17 -0200 Subject: [media] cec: accept two replies for CEC_MSG_INITIATE_ARC The CEC_MSG_INITIATE_ARC message is special since it is the ONLY CEC message that accepts two possible valid replies: CEC_MSG_REPORT_ARC_INITIATED and CEC_MSG_REPORT_ARC_TERMINATED. So if the transmitted message is CEC_MSG_INITIATE_ARC and the remote side replied with CEC_MSG_REPORT_ARC_INITIATED or CEC_MSG_REPORT_ARC_TERMINATED, then a msg->reply value of CEC_MSG_REPORT_ARC_INITIATED or CEC_MSG_REPORT_ARC_TERMINATED will match either reply. I thought about either adding a second reply2 field, but that's ugly for all other messages that have only one reply, and what if in the future a new message is added that can have three replies? Another option would be to add a cec_msg flag, but really, the combination of CEC_MSG_REPORT_ARC_INITIATED and a reply value of one of the two possible replies already functions as a flag. Another advantage of this approach is that it is safe to re-use a cec_msg struct. No need to zero a flags field or a reply2 field. So since this really is an exception in the CEC specification, I decided to implement it as an exception as well. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-receive.rst | 8 ++++++++ drivers/staging/media/cec/TODO | 15 +-------------- drivers/staging/media/cec/cec-adap.c | 12 ++++++++++++ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index b4dffd2f7dfa..bdf015b1d1dc 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -142,6 +142,14 @@ result. Feature Abort reply. In this case ``rx_status`` will either be set to :ref:`CEC_RX_STATUS_TIMEOUT ` or :ref:`CEC_RX_STATUS_FEATURE_ABORT `. + + If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply`` + values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED`` + are processed differently: either value will match both possible replies. + The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC + message that has two possible replies other than Feature Abort. The + ``reply`` field will be updated with the actual reply so that it is + synchronized with the contents of the received message. * - __u8 - ``rx_status`` - The status bits of the received message. See diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO index ce69001b0428..5a4cfdf8d15e 100644 --- a/drivers/staging/media/cec/TODO +++ b/drivers/staging/media/cec/TODO @@ -1,18 +1,5 @@ -The reason why cec.c is still in staging is that I would like -to have a bit more confidence in the uABI. The kABI is fine, -no problem there, but I would like to let the public API mature -a bit. +TODOs: -Once I'm confident that I didn't miss anything then the cec.c source -can move to drivers/media and the linux/cec.h and linux/cec-funcs.h -headers can move to uapi/linux and added to uapi/linux/Kbuild to make -them public. - -Hopefully this will happen later in 2016. - -Other TODOs: - -- There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that? - Should CEC_LOG_ADDR_TYPE_SPECIFIC be replaced by TYPE_2ND_TV and TYPE_PROCESSOR? And also TYPE_SWITCH and TYPE_CDC_ONLY in addition to the TYPE_UNREGISTERED? This should give the framework more information about the device type diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index 93b53e602e48..a65d8667b78e 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -958,6 +958,18 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) list_for_each_entry(data, &adap->wait_queue, list) { struct cec_msg *dst = &data->msg; + /* + * The *only* CEC message that has two possible replies + * is CEC_MSG_INITIATE_ARC. + * In this case allow either of the two replies. + */ + if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && + (cmd == CEC_MSG_REPORT_ARC_INITIATED || + cmd == CEC_MSG_REPORT_ARC_TERMINATED) && + (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || + dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) + dst->reply = cmd; + /* Does the command match? */ if ((abort && cmd != dst->msg[1]) || (!abort && cmd != dst->reply)) -- cgit v1.2.3 From a69a168a1bd470cb8a8c5f2ff4b54463de615226 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Nov 2016 07:41:41 -0200 Subject: [media] cec: add proper support for CDC-Only CEC devices CDC-Only CEC devices are CEC devices that can only handle CDC messages, all other messages are ignored. Add a flag to signal that this is a CDC-Only device and act accordingly. Also add helper functions to identify if a CEC device is configured as a CDC-Only device, a second TV, a switch or a processor, since these variations cannot be determined by the logical address alone. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/cec/TODO | 4 --- drivers/staging/media/cec/cec-adap.c | 31 ++++++++++++++++++++- drivers/staging/media/cec/cec-api.c | 9 ++++++- include/linux/cec.h | 52 ++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 6 deletions(-) diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO index 5a4cfdf8d15e..504d35c7ae95 100644 --- a/drivers/staging/media/cec/TODO +++ b/drivers/staging/media/cec/TODO @@ -1,9 +1,5 @@ TODOs: -- Should CEC_LOG_ADDR_TYPE_SPECIFIC be replaced by TYPE_2ND_TV and TYPE_PROCESSOR? - And also TYPE_SWITCH and TYPE_CDC_ONLY in addition to the TYPE_UNREGISTERED? - This should give the framework more information about the device type - since SPECIFIC and UNREGISTERED give no useful information. - Once this is out of staging this should no longer be a separate config option, instead it should be selected by drivers that want it. - Revisit the IS_REACHABLE(RC_CORE): perhaps the RC_CORE support should diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c index a65d8667b78e..054cd06e2247 100644 --- a/drivers/staging/media/cec/cec-adap.c +++ b/drivers/staging/media/cec/cec-adap.c @@ -1233,7 +1233,8 @@ configured: mutex_unlock(&adap->lock); for (i = 0; i < las->num_log_addrs; i++) { - if (las->log_addr[i] == CEC_LOG_ADDR_INVALID) + if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || + (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) continue; /* @@ -1355,6 +1356,29 @@ int __cec_s_log_addrs(struct cec_adapter *adap, return 0; } + if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) { + /* + * Sanitize log_addrs fields if a CDC-Only device is + * requested. + */ + log_addrs->num_log_addrs = 1; + log_addrs->osd_name[0] = '\0'; + log_addrs->vendor_id = CEC_VENDOR_ID_NONE; + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + /* + * This is just an internal convention since a CDC-Only device + * doesn't have to be a switch. But switches already use + * unregistered, so it makes some kind of sense to pick this + * as the primary device. Since a CDC-Only device never sends + * any 'normal' CEC messages this primary device type is never + * sent over the CEC bus. + */ + log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; + log_addrs->all_device_types[0] = 0; + log_addrs->features[0][0] = 0; + log_addrs->features[0][1] = 0; + } + /* Ensure the osd name is 0-terminated */ log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0'; @@ -1575,6 +1599,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg); + /* If this is a CDC-Only device, then ignore any non-CDC messages */ + if (cec_is_cdc_only(&adap->log_addrs) && + msg->msg[1] != CEC_MSG_CDC_MESSAGE) + return 0; + if (adap->ops->received) { /* Allow drivers to process the message first */ if (adap->ops->received(adap, msg) != -ENOMSG) diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c index 54148a6b3326..d4bc4ee2c6e5 100644 --- a/drivers/staging/media/cec/cec-api.c +++ b/drivers/staging/media/cec/cec-api.c @@ -163,7 +163,8 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) return -EFAULT; log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK | - CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU; + CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU | + CEC_LOG_ADDRS_FL_CDC_ONLY; mutex_lock(&adap->lock); if (!adap->is_configuring && (!log_addrs.num_log_addrs || !adap->is_configured) && @@ -190,6 +191,12 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, return -ENOTTY; if (copy_from_user(&msg, parg, sizeof(msg))) return -EFAULT; + + /* A CDC-Only device can only send CDC messages */ + if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) && + (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE)) + return -EINVAL; + msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; mutex_lock(&adap->lock); if (!adap->is_configured) diff --git a/include/linux/cec.h b/include/linux/cec.h index 3f2f076027b1..9c87711c0e1c 100644 --- a/include/linux/cec.h +++ b/include/linux/cec.h @@ -396,6 +396,8 @@ struct cec_log_addrs { #define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) /* Passthrough RC messages to the input subsystem */ #define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1) +/* CDC-Only device: supports only CDC messages */ +#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2) /* Events */ @@ -1016,4 +1018,54 @@ struct cec_event { #define CEC_OP_HPD_ERROR_OTHER 3 #define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 4 +/* End of Messages */ + +/* Helper functions to identify the 'special' CEC devices */ + +static inline bool cec_is_2nd_tv(const struct cec_log_addrs *las) +{ + /* + * It is a second TV if the logical address is 14 or 15 and the + * primary device type is a TV. + */ + return las->num_log_addrs && + las->log_addr[0] >= CEC_LOG_ADDR_SPECIFIC && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_TV; +} + +static inline bool cec_is_processor(const struct cec_log_addrs *las) +{ + /* + * It is a processor if the logical address is 12-15 and the + * primary device type is a Processor. + */ + return las->num_log_addrs && + las->log_addr[0] >= CEC_LOG_ADDR_BACKUP_1 && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_PROCESSOR; +} + +static inline bool cec_is_switch(const struct cec_log_addrs *las) +{ + /* + * It is a switch if the logical address is 15 and the + * primary device type is a Switch and the CDC-Only flag is not set. + */ + return las->num_log_addrs == 1 && + las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && + !(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); +} + +static inline bool cec_is_cdc_only(const struct cec_log_addrs *las) +{ + /* + * It is a CDC-only device if the logical address is 15 and the + * primary device type is a Switch and the CDC-Only flag is set. + */ + return las->num_log_addrs == 1 && + las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && + (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); +} + #endif -- cgit v1.2.3 From 0dbacebede1e4e44bf500f94d692fad05eb2c293 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Nov 2016 08:25:28 -0200 Subject: [media] cec: move the CEC framework out of staging and to media The last open issues have been addressed, so it is time to move this out of staging and into the mainline and to move the public cec headers to include/uapi/linux. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/Makefile | 2 +- drivers/media/Kconfig | 16 + drivers/media/Makefile | 4 + drivers/media/cec/Makefile | 5 + drivers/media/cec/cec-adap.c | 1856 ++++++++++++++++++++++++++++ drivers/media/cec/cec-api.c | 588 +++++++++ drivers/media/cec/cec-core.c | 411 +++++++ drivers/media/cec/cec-priv.h | 56 + drivers/media/i2c/Kconfig | 6 +- drivers/media/platform/vivid/Kconfig | 2 +- drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/cec/Kconfig | 12 - drivers/staging/media/cec/Makefile | 5 - drivers/staging/media/cec/TODO | 9 - drivers/staging/media/cec/cec-adap.c | 1856 ---------------------------- drivers/staging/media/cec/cec-api.c | 588 --------- drivers/staging/media/cec/cec-core.c | 411 ------- drivers/staging/media/cec/cec-priv.h | 56 - drivers/staging/media/pulse8-cec/Kconfig | 2 +- drivers/staging/media/s5p-cec/Kconfig | 2 +- drivers/staging/media/st-cec/Kconfig | 2 +- include/linux/cec-funcs.h | 1971 ------------------------------ include/linux/cec.h | 1071 ---------------- include/media/cec.h | 2 +- include/uapi/linux/Kbuild | 2 + include/uapi/linux/cec-funcs.h | 1965 +++++++++++++++++++++++++++++ include/uapi/linux/cec.h | 1065 ++++++++++++++++ 28 files changed, 5977 insertions(+), 5991 deletions(-) create mode 100644 drivers/media/cec/Makefile create mode 100644 drivers/media/cec/cec-adap.c create mode 100644 drivers/media/cec/cec-api.c create mode 100644 drivers/media/cec/cec-core.c create mode 100644 drivers/media/cec/cec-priv.h delete mode 100644 drivers/staging/media/cec/Kconfig delete mode 100644 drivers/staging/media/cec/Makefile delete mode 100644 drivers/staging/media/cec/TODO delete mode 100644 drivers/staging/media/cec/cec-adap.c delete mode 100644 drivers/staging/media/cec/cec-api.c delete mode 100644 drivers/staging/media/cec/cec-core.c delete mode 100644 drivers/staging/media/cec/cec-priv.h delete mode 100644 include/linux/cec-funcs.h delete mode 100644 include/linux/cec.h create mode 100644 include/uapi/linux/cec-funcs.h create mode 100644 include/uapi/linux/cec.h diff --git a/Documentation/media/Makefile b/Documentation/media/Makefile index a7fb35291f6c..61afa052c501 100644 --- a/Documentation/media/Makefile +++ b/Documentation/media/Makefile @@ -51,7 +51,7 @@ $(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2. $(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions @$($(quiet)gen_rst) -$(BUILDDIR)/cec.h.rst: ${KAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions +$(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions @$($(quiet)gen_rst) $(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 7b8540291217..bc643cbf813e 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -80,6 +80,22 @@ config MEDIA_RC_SUPPORT Say Y when you have a TV or an IR device. +config MEDIA_CEC_SUPPORT + bool "HDMI CEC support" + select MEDIA_CEC_EDID + ---help--- + Enable support for HDMI CEC (Consumer Electronics Control), + which is an optional HDMI feature. + + Say Y when you have an HDMI receiver, transmitter or a USB CEC + adapter that supports HDMI CEC. + +config MEDIA_CEC_DEBUG + bool "HDMI CEC debugfs interface" + depends on MEDIA_CEC_SUPPORT && DEBUG_FS + ---help--- + Turns on the DebugFS interface for CEC devices. + config MEDIA_CEC_EDID bool diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 0deaa93efdee..d87ccb8eeabe 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -6,6 +6,10 @@ ifeq ($(CONFIG_MEDIA_CEC_EDID),y) obj-$(CONFIG_MEDIA_SUPPORT) += cec-edid.o endif +ifeq ($(CONFIG_MEDIA_CEC_SUPPORT),y) + obj-$(CONFIG_MEDIA_SUPPORT) += cec/ +endif + media-objs := media-device.o media-devnode.o media-entity.o # diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile new file mode 100644 index 000000000000..d6686337275f --- /dev/null +++ b/drivers/media/cec/Makefile @@ -0,0 +1,5 @@ +cec-objs := cec-core.o cec-adap.o cec-api.o + +ifeq ($(CONFIG_MEDIA_CEC_SUPPORT),y) + obj-$(CONFIG_MEDIA_SUPPORT) += cec.o +endif diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c new file mode 100644 index 000000000000..054cd06e2247 --- /dev/null +++ b/drivers/media/cec/cec-adap.c @@ -0,0 +1,1856 @@ +/* + * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cec-priv.h" + +static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx); +static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx); + +/* + * 400 ms is the time it takes for one 16 byte message to be + * transferred and 5 is the maximum number of retries. Add + * another 100 ms as a margin. So if the transmit doesn't + * finish before that time something is really wrong and we + * have to time out. + * + * This is a sign that something it really wrong and a warning + * will be issued. + */ +#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100) + +#define call_op(adap, op, arg...) \ + (adap->ops->op ? adap->ops->op(adap, ## arg) : 0) + +#define call_void_op(adap, op, arg...) \ + do { \ + if (adap->ops->op) \ + adap->ops->op(adap, ## arg); \ + } while (0) + +static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr) +{ + int i; + + for (i = 0; i < adap->log_addrs.num_log_addrs; i++) + if (adap->log_addrs.log_addr[i] == log_addr) + return i; + return -1; +} + +static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr) +{ + int i = cec_log_addr2idx(adap, log_addr); + + return adap->log_addrs.primary_device_type[i < 0 ? 0 : i]; +} + +/* + * Queue a new event for this filehandle. If ts == 0, then set it + * to the current time. + * + * The two events that are currently defined do not need to keep track + * of intermediate events, so no actual queue of events is needed, + * instead just store the latest state and the total number of lost + * messages. + * + * Should new events be added in the future that require intermediate + * results to be queued as well, then a proper queue data structure is + * required. But until then, just keep it simple. + */ +void cec_queue_event_fh(struct cec_fh *fh, + const struct cec_event *new_ev, u64 ts) +{ + struct cec_event *ev = &fh->events[new_ev->event - 1]; + + if (ts == 0) + ts = ktime_get_ns(); + + mutex_lock(&fh->lock); + if (new_ev->event == CEC_EVENT_LOST_MSGS && + fh->pending_events & (1 << new_ev->event)) { + /* + * If there is already a lost_msgs event, then just + * update the lost_msgs count. This effectively + * merges the old and new events into one. + */ + ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; + goto unlock; + } + + /* + * Intermediate states are not interesting, so just + * overwrite any older event. + */ + *ev = *new_ev; + ev->ts = ts; + fh->pending_events |= 1 << new_ev->event; + +unlock: + mutex_unlock(&fh->lock); + wake_up_interruptible(&fh->wait); +} + +/* Queue a new event for all open filehandles. */ +static void cec_queue_event(struct cec_adapter *adap, + const struct cec_event *ev) +{ + u64 ts = ktime_get_ns(); + struct cec_fh *fh; + + mutex_lock(&adap->devnode.lock); + list_for_each_entry(fh, &adap->devnode.fhs, list) + cec_queue_event_fh(fh, ev, ts); + mutex_unlock(&adap->devnode.lock); +} + +/* + * Queue a new message for this filehandle. If there is no more room + * in the queue, then send the LOST_MSGS event instead. + */ +static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) +{ + static const struct cec_event ev_lost_msg = { + .ts = 0, + .event = CEC_EVENT_LOST_MSGS, + .flags = 0, + { + .lost_msgs.lost_msgs = 1, + }, + }; + struct cec_msg_entry *entry; + + mutex_lock(&fh->lock); + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto lost_msgs; + + entry->msg = *msg; + /* Add new msg at the end of the queue */ + list_add_tail(&entry->list, &fh->msgs); + + /* + * if the queue now has more than CEC_MAX_MSG_RX_QUEUE_SZ + * messages, drop the oldest one and send a lost message event. + */ + if (fh->queued_msgs == CEC_MAX_MSG_RX_QUEUE_SZ) { + list_del(&entry->list); + goto lost_msgs; + } + fh->queued_msgs++; + mutex_unlock(&fh->lock); + wake_up_interruptible(&fh->wait); + return; + +lost_msgs: + mutex_unlock(&fh->lock); + cec_queue_event_fh(fh, &ev_lost_msg, 0); +} + +/* + * Queue the message for those filehandles that are in monitor mode. + * If valid_la is true (this message is for us or was sent by us), + * then pass it on to any monitoring filehandle. If this message + * isn't for us or from us, then only give it to filehandles that + * are in MONITOR_ALL mode. + * + * This can only happen if the CEC_CAP_MONITOR_ALL capability is + * set and the CEC adapter was placed in 'monitor all' mode. + */ +static void cec_queue_msg_monitor(struct cec_adapter *adap, + const struct cec_msg *msg, + bool valid_la) +{ + struct cec_fh *fh; + u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : + CEC_MODE_MONITOR_ALL; + + mutex_lock(&adap->devnode.lock); + list_for_each_entry(fh, &adap->devnode.fhs, list) { + if (fh->mode_follower >= monitor_mode) + cec_queue_msg_fh(fh, msg); + } + mutex_unlock(&adap->devnode.lock); +} + +/* + * Queue the message for follower filehandles. + */ +static void cec_queue_msg_followers(struct cec_adapter *adap, + const struct cec_msg *msg) +{ + struct cec_fh *fh; + + mutex_lock(&adap->devnode.lock); + list_for_each_entry(fh, &adap->devnode.fhs, list) { + if (fh->mode_follower == CEC_MODE_FOLLOWER) + cec_queue_msg_fh(fh, msg); + } + mutex_unlock(&adap->devnode.lock); +} + +/* Notify userspace of an adapter state change. */ +static void cec_post_state_event(struct cec_adapter *adap) +{ + struct cec_event ev = { + .event = CEC_EVENT_STATE_CHANGE, + }; + + ev.state_change.phys_addr = adap->phys_addr; + ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; + cec_queue_event(adap, &ev); +} + +/* + * A CEC transmit (and a possible wait for reply) completed. + * If this was in blocking mode, then complete it, otherwise + * queue the message for userspace to dequeue later. + * + * This function is called with adap->lock held. + */ +static void cec_data_completed(struct cec_data *data) +{ + /* + * Delete this transmit from the filehandle's xfer_list since + * we're done with it. + * + * Note that if the filehandle is closed before this transmit + * finished, then the release() function will set data->fh to NULL. + * Without that we would be referring to a closed filehandle. + */ + if (data->fh) + list_del(&data->xfer_list); + + if (data->blocking) { + /* + * Someone is blocking so mark the message as completed + * and call complete. + */ + data->completed = true; + complete(&data->c); + } else { + /* + * No blocking, so just queue the message if needed and + * free the memory. + */ + if (data->fh) + cec_queue_msg_fh(data->fh, &data->msg); + kfree(data); + } +} + +/* + * A pending CEC transmit needs to be cancelled, either because the CEC + * adapter is disabled or the transmit takes an impossibly long time to + * finish. + * + * This function is called with adap->lock held. + */ +static void cec_data_cancel(struct cec_data *data) +{ + /* + * It's either the current transmit, or it is a pending + * transmit. Take the appropriate action to clear it. + */ + if (data->adap->transmitting == data) { + data->adap->transmitting = NULL; + } else { + list_del_init(&data->list); + if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) + data->adap->transmit_queue_sz--; + } + + /* Mark it as an error */ + data->msg.tx_ts = ktime_get_ns(); + data->msg.tx_status = CEC_TX_STATUS_ERROR | + CEC_TX_STATUS_MAX_RETRIES; + data->attempts = 0; + data->msg.tx_error_cnt = 1; + /* Queue transmitted message for monitoring purposes */ + cec_queue_msg_monitor(data->adap, &data->msg, 1); + + cec_data_completed(data); +} + +/* + * Main CEC state machine + * + * Wait until the thread should be stopped, or we are not transmitting and + * a new transmit message is queued up, in which case we start transmitting + * that message. When the adapter finished transmitting the message it will + * call cec_transmit_done(). + * + * If the adapter is disabled, then remove all queued messages instead. + * + * If the current transmit times out, then cancel that transmit. + */ +int cec_thread_func(void *_adap) +{ + struct cec_adapter *adap = _adap; + + for (;;) { + unsigned int signal_free_time; + struct cec_data *data; + bool timeout = false; + u8 attempts; + + if (adap->transmitting) { + int err; + + /* + * We are transmitting a message, so add a timeout + * to prevent the state machine to get stuck waiting + * for this message to finalize and add a check to + * see if the adapter is disabled in which case the + * transmit should be canceled. + */ + err = wait_event_interruptible_timeout(adap->kthread_waitq, + kthread_should_stop() || + (!adap->is_configured && !adap->is_configuring) || + (!adap->transmitting && + !list_empty(&adap->transmit_queue)), + msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); + timeout = err == 0; + } else { + /* Otherwise we just wait for something to happen. */ + wait_event_interruptible(adap->kthread_waitq, + kthread_should_stop() || + (!adap->transmitting && + !list_empty(&adap->transmit_queue))); + } + + mutex_lock(&adap->lock); + + if ((!adap->is_configured && !adap->is_configuring) || + kthread_should_stop()) { + /* + * If the adapter is disabled, or we're asked to stop, + * then cancel any pending transmits. + */ + while (!list_empty(&adap->transmit_queue)) { + data = list_first_entry(&adap->transmit_queue, + struct cec_data, list); + cec_data_cancel(data); + } + if (adap->transmitting) + cec_data_cancel(adap->transmitting); + + /* + * Cancel the pending timeout work. We have to unlock + * the mutex when flushing the work since + * cec_wait_timeout() will take it. This is OK since + * no new entries can be added to wait_queue as long + * as adap->transmitting is NULL, which it is due to + * the cec_data_cancel() above. + */ + while (!list_empty(&adap->wait_queue)) { + data = list_first_entry(&adap->wait_queue, + struct cec_data, list); + + if (!cancel_delayed_work(&data->work)) { + mutex_unlock(&adap->lock); + flush_scheduled_work(); + mutex_lock(&adap->lock); + } + cec_data_cancel(data); + } + goto unlock; + } + + if (adap->transmitting && timeout) { + /* + * If we timeout, then log that. This really shouldn't + * happen and is an indication of a faulty CEC adapter + * driver, or the CEC bus is in some weird state. + */ + dprintk(0, "message %*ph timed out!\n", + adap->transmitting->msg.len, + adap->transmitting->msg.msg); + /* Just give up on this. */ + cec_data_cancel(adap->transmitting); + goto unlock; + } + + /* + * If we are still transmitting, or there is nothing new to + * transmit, then just continue waiting. + */ + if (adap->transmitting || list_empty(&adap->transmit_queue)) + goto unlock; + + /* Get a new message to transmit */ + data = list_first_entry(&adap->transmit_queue, + struct cec_data, list); + list_del_init(&data->list); + adap->transmit_queue_sz--; + /* Make this the current transmitting message */ + adap->transmitting = data; + + /* + * Suggested number of attempts as per the CEC 2.0 spec: + * 4 attempts is the default, except for 'secondary poll + * messages', i.e. poll messages not sent during the adapter + * configuration phase when it allocates logical addresses. + */ + if (data->msg.len == 1 && adap->is_configured) + attempts = 2; + else + attempts = 4; + + /* Set the suggested signal free time */ + if (data->attempts) { + /* should be >= 3 data bit periods for a retry */ + signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY; + } else if (data->new_initiator) { + /* should be >= 5 data bit periods for new initiator */ + signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; + } else { + /* + * should be >= 7 data bit periods for sending another + * frame immediately after another. + */ + signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER; + } + if (data->attempts == 0) + data->attempts = attempts; + + /* Tell the adapter to transmit, cancel on error */ + if (adap->ops->adap_transmit(adap, data->attempts, + signal_free_time, &data->msg)) + cec_data_cancel(data); + +unlock: + mutex_unlock(&adap->lock); + + if (kthread_should_stop()) + break; + } + return 0; +} + +/* + * Called by the CEC adapter if a transmit finished. + */ +void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, + u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt) +{ + struct cec_data *data; + struct cec_msg *msg; + u64 ts = ktime_get_ns(); + + dprintk(2, "cec_transmit_done %02x\n", status); + mutex_lock(&adap->lock); + data = adap->transmitting; + if (!data) { + /* + * This can happen if a transmit was issued and the cable is + * unplugged while the transmit is ongoing. Ignore this + * transmit in that case. + */ + dprintk(1, "cec_transmit_done without an ongoing transmit!\n"); + goto unlock; + } + + msg = &data->msg; + + /* Drivers must fill in the status! */ + WARN_ON(status == 0); + msg->tx_ts = ts; + msg->tx_status |= status; + msg->tx_arb_lost_cnt += arb_lost_cnt; + msg->tx_nack_cnt += nack_cnt; + msg->tx_low_drive_cnt += low_drive_cnt; + msg->tx_error_cnt += error_cnt; + + /* Mark that we're done with this transmit */ + adap->transmitting = NULL; + + /* + * If there are still retry attempts left and there was an error and + * the hardware didn't signal that it retried itself (by setting + * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. + */ + if (data->attempts > 1 && + !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { + /* Retry this message */ + data->attempts--; + /* Add the message in front of the transmit queue */ + list_add(&data->list, &adap->transmit_queue); + adap->transmit_queue_sz++; + goto wake_thread; + } + + data->attempts = 0; + + /* Always set CEC_TX_STATUS_MAX_RETRIES on error */ + if (!(status & CEC_TX_STATUS_OK)) + msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES; + + /* Queue transmitted message for monitoring purposes */ + cec_queue_msg_monitor(adap, msg, 1); + + if ((status & CEC_TX_STATUS_OK) && adap->is_configured && + msg->timeout) { + /* + * Queue the message into the wait queue if we want to wait + * for a reply. + */ + list_add_tail(&data->list, &adap->wait_queue); + schedule_delayed_work(&data->work, + msecs_to_jiffies(msg->timeout)); + } else { + /* Otherwise we're done */ + cec_data_completed(data); + } + +wake_thread: + /* + * Wake up the main thread to see if another message is ready + * for transmitting or to retry the current message. + */ + wake_up_interruptible(&adap->kthread_waitq); +unlock: + mutex_unlock(&adap->lock); +} +EXPORT_SYMBOL_GPL(cec_transmit_done); + +/* + * Called when waiting for a reply times out. + */ +static void cec_wait_timeout(struct work_struct *work) +{ + struct cec_data *data = container_of(work, struct cec_data, work.work); + struct cec_adapter *adap = data->adap; + + mutex_lock(&adap->lock); + /* + * Sanity check in case the timeout and the arrival of the message + * happened at the same time. + */ + if (list_empty(&data->list)) + goto unlock; + + /* Mark the message as timed out */ + list_del_init(&data->list); + data->msg.rx_ts = ktime_get_ns(); + data->msg.rx_status = CEC_RX_STATUS_TIMEOUT; + cec_data_completed(data); +unlock: + mutex_unlock(&adap->lock); +} + +/* + * Transmit a message. The fh argument may be NULL if the transmit is not + * associated with a specific filehandle. + * + * This function is called with adap->lock held. + */ +int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, + struct cec_fh *fh, bool block) +{ + struct cec_data *data; + u8 last_initiator = 0xff; + unsigned int timeout; + int res = 0; + + msg->rx_ts = 0; + msg->tx_ts = 0; + msg->rx_status = 0; + msg->tx_status = 0; + msg->tx_arb_lost_cnt = 0; + msg->tx_nack_cnt = 0; + msg->tx_low_drive_cnt = 0; + msg->tx_error_cnt = 0; + msg->sequence = ++adap->sequence; + if (!msg->sequence) + msg->sequence = ++adap->sequence; + + if (msg->reply && msg->timeout == 0) { + /* Make sure the timeout isn't 0. */ + msg->timeout = 1000; + } + + /* Sanity checks */ + if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { + dprintk(1, "cec_transmit_msg: invalid length %d\n", msg->len); + return -EINVAL; + } + if (msg->timeout && msg->len == 1) { + dprintk(1, "cec_transmit_msg: can't reply for poll msg\n"); + return -EINVAL; + } + memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); + if (msg->len == 1) { + if (cec_msg_initiator(msg) != 0xf || + cec_msg_destination(msg) == 0xf) { + dprintk(1, "cec_transmit_msg: invalid poll message\n"); + return -EINVAL; + } + if (cec_has_log_addr(adap, cec_msg_destination(msg))) { + /* + * If the destination is a logical address our adapter + * has already claimed, then just NACK this. + * It depends on the hardware what it will do with a + * POLL to itself (some OK this), so it is just as + * easy to handle it here so the behavior will be + * consistent. + */ + msg->tx_ts = ktime_get_ns(); + msg->tx_status = CEC_TX_STATUS_NACK | + CEC_TX_STATUS_MAX_RETRIES; + msg->tx_nack_cnt = 1; + return 0; + } + } + if (msg->len > 1 && !cec_msg_is_broadcast(msg) && + cec_has_log_addr(adap, cec_msg_destination(msg))) { + dprintk(1, "cec_transmit_msg: destination is the adapter itself\n"); + return -EINVAL; + } + if (cec_msg_initiator(msg) != 0xf && + !cec_has_log_addr(adap, cec_msg_initiator(msg))) { + dprintk(1, "cec_transmit_msg: initiator has unknown logical address %d\n", + cec_msg_initiator(msg)); + return -EINVAL; + } + if (!adap->is_configured && !adap->is_configuring) + return -ENONET; + + if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) + return -EBUSY; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { + msg->msg[2] = adap->phys_addr >> 8; + msg->msg[3] = adap->phys_addr & 0xff; + } + + if (msg->timeout) + dprintk(2, "cec_transmit_msg: %*ph (wait for 0x%02x%s)\n", + msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); + else + dprintk(2, "cec_transmit_msg: %*ph%s\n", + msg->len, msg->msg, !block ? " (nb)" : ""); + + data->msg = *msg; + data->fh = fh; + data->adap = adap; + data->blocking = block; + + /* + * Determine if this message follows a message from the same + * initiator. Needed to determine the free signal time later on. + */ + if (msg->len > 1) { + if (!(list_empty(&adap->transmit_queue))) { + const struct cec_data *last; + + last = list_last_entry(&adap->transmit_queue, + const struct cec_data, list); + last_initiator = cec_msg_initiator(&last->msg); + } else if (adap->transmitting) { + last_initiator = + cec_msg_initiator(&adap->transmitting->msg); + } + } + data->new_initiator = last_initiator != cec_msg_initiator(msg); + init_completion(&data->c); + INIT_DELAYED_WORK(&data->work, cec_wait_timeout); + + if (fh) + list_add_tail(&data->xfer_list, &fh->xfer_list); + list_add_tail(&data->list, &adap->transmit_queue); + adap->transmit_queue_sz++; + if (!adap->transmitting) + wake_up_interruptible(&adap->kthread_waitq); + + /* All done if we don't need to block waiting for completion */ + if (!block) + return 0; + + /* + * If we don't get a completion before this time something is really + * wrong and we time out. + */ + timeout = CEC_XFER_TIMEOUT_MS; + /* Add the requested timeout if we have to wait for a reply as well */ + if (msg->timeout) + timeout += msg->timeout; + + /* + * Release the lock and wait, retake the lock afterwards. + */ + mutex_unlock(&adap->lock); + res = wait_for_completion_killable_timeout(&data->c, + msecs_to_jiffies(timeout)); + mutex_lock(&adap->lock); + + if (data->completed) { + /* The transmit completed (possibly with an error) */ + *msg = data->msg; + kfree(data); + return 0; + } + /* + * The wait for completion timed out or was interrupted, so mark this + * as non-blocking and disconnect from the filehandle since it is + * still 'in flight'. When it finally completes it will just drop the + * result silently. + */ + data->blocking = false; + if (data->fh) + list_del(&data->xfer_list); + data->fh = NULL; + + if (res == 0) { /* timed out */ + /* Check if the reply or the transmit failed */ + if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK)) + msg->rx_status = CEC_RX_STATUS_TIMEOUT; + else + msg->tx_status = CEC_TX_STATUS_MAX_RETRIES; + } + return res > 0 ? 0 : res; +} + +/* Helper function to be used by drivers and this framework. */ +int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, + bool block) +{ + int ret; + + mutex_lock(&adap->lock); + ret = cec_transmit_msg_fh(adap, msg, NULL, block); + mutex_unlock(&adap->lock); + return ret; +} +EXPORT_SYMBOL_GPL(cec_transmit_msg); + +/* + * I don't like forward references but without this the low-level + * cec_received_msg() function would come after a bunch of high-level + * CEC protocol handling functions. That was very confusing. + */ +static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + bool is_reply); + +#define DIRECTED 0x80 +#define BCAST1_4 0x40 +#define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */ +#define BCAST (BCAST1_4 | BCAST2_0) +#define BOTH (BCAST | DIRECTED) + +/* + * Specify minimum length and whether the message is directed, broadcast + * or both. Messages that do not match the criteria are ignored as per + * the CEC specification. + */ +static const u8 cec_msg_size[256] = { + [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST, + [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED, + [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED, + [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED, + [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST, + [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST, + [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST, + [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST, + [CEC_MSG_STANDBY] = 2 | BOTH, + [CEC_MSG_RECORD_OFF] = 2 | DIRECTED, + [CEC_MSG_RECORD_ON] = 3 | DIRECTED, + [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED, + [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED, + [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED, + [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED, + [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED, + [CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED, + [CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED, + [CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED, + [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED, + [CEC_MSG_CEC_VERSION] = 3 | DIRECTED, + [CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED, + [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED, + [CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED, + [CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST, + [CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST, + [CEC_MSG_REPORT_FEATURES] = 6 | BCAST, + [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED, + [CEC_MSG_DECK_CONTROL] = 3 | DIRECTED, + [CEC_MSG_DECK_STATUS] = 3 | DIRECTED, + [CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED, + [CEC_MSG_PLAY] = 3 | DIRECTED, + [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED, + [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED, + [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED, + [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED, + [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED, + [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED, + [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST, + [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED, + [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED, + [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH, + [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH, + [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH, + [CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED, + [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED, + [CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED, + [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED, + [CEC_MSG_MENU_STATUS] = 3 | DIRECTED, + [CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED, + [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED, + [CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED, + [CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0, + [CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED, + [CEC_MSG_ABORT] = 2 | DIRECTED, + [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED, + [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED, + [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED, + [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, + [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, + [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, + [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, + [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, + [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED, + [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED, + [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED, + [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED, + [CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED, + [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, + [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, + [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, + [CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST, + [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, +}; + +/* Called by the CEC adapter if a message is received */ +void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) +{ + struct cec_data *data; + u8 msg_init = cec_msg_initiator(msg); + u8 msg_dest = cec_msg_destination(msg); + u8 cmd = msg->msg[1]; + bool is_reply = false; + bool valid_la = true; + u8 min_len = 0; + + if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) + return; + + msg->rx_ts = ktime_get_ns(); + msg->rx_status = CEC_RX_STATUS_OK; + msg->sequence = msg->reply = msg->timeout = 0; + msg->tx_status = 0; + msg->tx_ts = 0; + msg->flags = 0; + memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); + + mutex_lock(&adap->lock); + dprintk(2, "cec_received_msg: %*ph\n", msg->len, msg->msg); + + /* Check if this message was for us (directed or broadcast). */ + if (!cec_msg_is_broadcast(msg)) + valid_la = cec_has_log_addr(adap, msg_dest); + + /* + * Check if the length is not too short or if the message is a + * broadcast message where a directed message was expected or + * vice versa. If so, then the message has to be ignored (according + * to section CEC 7.3 and CEC 12.2). + */ + if (valid_la && msg->len > 1 && cec_msg_size[cmd]) { + u8 dir_fl = cec_msg_size[cmd] & BOTH; + + min_len = cec_msg_size[cmd] & 0x1f; + if (msg->len < min_len) + valid_la = false; + else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) + valid_la = false; + else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) + valid_la = false; + else if (cec_msg_is_broadcast(msg) && + adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && + !(dir_fl & BCAST2_0)) + valid_la = false; + } + if (valid_la && min_len) { + /* These messages have special length requirements */ + switch (cmd) { + case CEC_MSG_TIMER_STATUS: + if (msg->msg[2] & 0x10) { + switch (msg->msg[2] & 0xf) { + case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: + case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: + if (msg->len < 5) + valid_la = false; + break; + } + } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { + if (msg->len < 5) + valid_la = false; + } + break; + case CEC_MSG_RECORD_ON: + switch (msg->msg[2]) { + case CEC_OP_RECORD_SRC_OWN: + break; + case CEC_OP_RECORD_SRC_DIGITAL: + if (msg->len < 10) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_ANALOG: + if (msg->len < 7) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_EXT_PLUG: + if (msg->len < 4) + valid_la = false; + break; + case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: + if (msg->len < 5) + valid_la = false; + break; + } + break; + } + } + + /* It's a valid message and not a poll or CDC message */ + if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) { + bool abort = cmd == CEC_MSG_FEATURE_ABORT; + + /* The aborted command is in msg[2] */ + if (abort) + cmd = msg->msg[2]; + + /* + * Walk over all transmitted messages that are waiting for a + * reply. + */ + list_for_each_entry(data, &adap->wait_queue, list) { + struct cec_msg *dst = &data->msg; + + /* + * The *only* CEC message that has two possible replies + * is CEC_MSG_INITIATE_ARC. + * In this case allow either of the two replies. + */ + if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && + (cmd == CEC_MSG_REPORT_ARC_INITIATED || + cmd == CEC_MSG_REPORT_ARC_TERMINATED) && + (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || + dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) + dst->reply = cmd; + + /* Does the command match? */ + if ((abort && cmd != dst->msg[1]) || + (!abort && cmd != dst->reply)) + continue; + + /* Does the addressing match? */ + if (msg_init != cec_msg_destination(dst) && + !cec_msg_is_broadcast(dst)) + continue; + + /* We got a reply */ + memcpy(dst->msg, msg->msg, msg->len); + dst->len = msg->len; + dst->rx_ts = msg->rx_ts; + dst->rx_status = msg->rx_status; + if (abort) + dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; + msg->flags = dst->flags; + /* Remove it from the wait_queue */ + list_del_init(&data->list); + + /* Cancel the pending timeout work */ + if (!cancel_delayed_work(&data->work)) { + mutex_unlock(&adap->lock); + flush_scheduled_work(); + mutex_lock(&adap->lock); + } + /* + * Mark this as a reply, provided someone is still + * waiting for the answer. + */ + if (data->fh) + is_reply = true; + cec_data_completed(data); + break; + } + } + mutex_unlock(&adap->lock); + + /* Pass the message on to any monitoring filehandles */ + cec_queue_msg_monitor(adap, msg, valid_la); + + /* We're done if it is not for us or a poll message */ + if (!valid_la || msg->len <= 1) + return; + + if (adap->log_addrs.log_addr_mask == 0) + return; + + /* + * Process the message on the protocol level. If is_reply is true, + * then cec_receive_notify() won't pass on the reply to the listener(s) + * since that was already done by cec_data_completed() above. + */ + cec_receive_notify(adap, msg, is_reply); +} +EXPORT_SYMBOL_GPL(cec_received_msg); + +/* Logical Address Handling */ + +/* + * Attempt to claim a specific logical address. + * + * This function is called with adap->lock held. + */ +static int cec_config_log_addr(struct cec_adapter *adap, + unsigned int idx, + unsigned int log_addr) +{ + struct cec_log_addrs *las = &adap->log_addrs; + struct cec_msg msg = { }; + int err; + + if (cec_has_log_addr(adap, log_addr)) + return 0; + + /* Send poll message */ + msg.len = 1; + msg.msg[0] = 0xf0 | log_addr; + err = cec_transmit_msg_fh(adap, &msg, NULL, true); + + /* + * While trying to poll the physical address was reset + * and the adapter was unconfigured, so bail out. + */ + if (!adap->is_configuring) + return -EINTR; + + if (err) + return err; + + if (msg.tx_status & CEC_TX_STATUS_OK) + return 0; + + /* + * Message not acknowledged, so this logical + * address is free to use. + */ + err = adap->ops->adap_log_addr(adap, log_addr); + if (err) + return err; + + las->log_addr[idx] = log_addr; + las->log_addr_mask |= 1 << log_addr; + adap->phys_addrs[log_addr] = adap->phys_addr; + + dprintk(2, "claimed addr %d (%d)\n", log_addr, + las->primary_device_type[idx]); + return 1; +} + +/* + * Unconfigure the adapter: clear all logical addresses and send + * the state changed event. + * + * This function is called with adap->lock held. + */ +static void cec_adap_unconfigure(struct cec_adapter *adap) +{ + WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); + adap->log_addrs.log_addr_mask = 0; + adap->is_configuring = false; + adap->is_configured = false; + memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); + wake_up_interruptible(&adap->kthread_waitq); + cec_post_state_event(adap); +} + +/* + * Attempt to claim the required logical addresses. + */ +static int cec_config_thread_func(void *arg) +{ + /* The various LAs for each type of device */ + static const u8 tv_log_addrs[] = { + CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC, + CEC_LOG_ADDR_INVALID + }; + static const u8 record_log_addrs[] = { + CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2, + CEC_LOG_ADDR_RECORD_3, + CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, + CEC_LOG_ADDR_INVALID + }; + static const u8 tuner_log_addrs[] = { + CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2, + CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4, + CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, + CEC_LOG_ADDR_INVALID + }; + static const u8 playback_log_addrs[] = { + CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2, + CEC_LOG_ADDR_PLAYBACK_3, + CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, + CEC_LOG_ADDR_INVALID + }; + static const u8 audiosystem_log_addrs[] = { + CEC_LOG_ADDR_AUDIOSYSTEM, + CEC_LOG_ADDR_INVALID + }; + static const u8 specific_use_log_addrs[] = { + CEC_LOG_ADDR_SPECIFIC, + CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, + CEC_LOG_ADDR_INVALID + }; + static const u8 *type2addrs[6] = { + [CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs, + [CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs, + [CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs, + [CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs, + [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs, + [CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs, + }; + static const u16 type2mask[] = { + [CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV, + [CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD, + [CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER, + [CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK, + [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM, + [CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC, + }; + struct cec_adapter *adap = arg; + struct cec_log_addrs *las = &adap->log_addrs; + int err; + int i, j; + + mutex_lock(&adap->lock); + dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n", + cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs); + las->log_addr_mask = 0; + + if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED) + goto configured; + + for (i = 0; i < las->num_log_addrs; i++) { + unsigned int type = las->log_addr_type[i]; + const u8 *la_list; + u8 last_la; + + /* + * The TV functionality can only map to physical address 0. + * For any other address, try the Specific functionality + * instead as per the spec. + */ + if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV) + type = CEC_LOG_ADDR_TYPE_SPECIFIC; + + la_list = type2addrs[type]; + last_la = las->log_addr[i]; + las->log_addr[i] = CEC_LOG_ADDR_INVALID; + if (last_la == CEC_LOG_ADDR_INVALID || + last_la == CEC_LOG_ADDR_UNREGISTERED || + !(last_la & type2mask[type])) + last_la = la_list[0]; + + err = cec_config_log_addr(adap, i, last_la); + if (err > 0) /* Reused last LA */ + continue; + + if (err < 0) + goto unconfigure; + + for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) { + /* Tried this one already, skip it */ + if (la_list[j] == last_la) + continue; + /* The backup addresses are CEC 2.0 specific */ + if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 || + la_list[j] == CEC_LOG_ADDR_BACKUP_2) && + las->cec_version < CEC_OP_CEC_VERSION_2_0) + continue; + + err = cec_config_log_addr(adap, i, la_list[j]); + if (err == 0) /* LA is in use */ + continue; + if (err < 0) + goto unconfigure; + /* Done, claimed an LA */ + break; + } + + if (la_list[j] == CEC_LOG_ADDR_INVALID) + dprintk(1, "could not claim LA %d\n", i); + } + + if (adap->log_addrs.log_addr_mask == 0 && + !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) + goto unconfigure; + +configured: + if (adap->log_addrs.log_addr_mask == 0) { + /* Fall back to unregistered */ + las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; + las->log_addr_mask = 1 << las->log_addr[0]; + for (i = 1; i < las->num_log_addrs; i++) + las->log_addr[i] = CEC_LOG_ADDR_INVALID; + } + adap->is_configured = true; + adap->is_configuring = false; + cec_post_state_event(adap); + mutex_unlock(&adap->lock); + + for (i = 0; i < las->num_log_addrs; i++) { + if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || + (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) + continue; + + /* + * Report Features must come first according + * to CEC 2.0 + */ + if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED) + cec_report_features(adap, i); + cec_report_phys_addr(adap, i); + } + for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) + las->log_addr[i] = CEC_LOG_ADDR_INVALID; + mutex_lock(&adap->lock); + adap->kthread_config = NULL; + mutex_unlock(&adap->lock); + complete(&adap->config_completion); + return 0; + +unconfigure: + for (i = 0; i < las->num_log_addrs; i++) + las->log_addr[i] = CEC_LOG_ADDR_INVALID; + cec_adap_unconfigure(adap); + adap->kthread_config = NULL; + mutex_unlock(&adap->lock); + complete(&adap->config_completion); + return 0; +} + +/* + * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the + * logical addresses. + * + * This function is called with adap->lock held. + */ +static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) +{ + if (WARN_ON(adap->is_configuring || adap->is_configured)) + return; + + init_completion(&adap->config_completion); + + /* Ready to kick off the thread */ + adap->is_configuring = true; + adap->kthread_config = kthread_run(cec_config_thread_func, adap, + "ceccfg-%s", adap->name); + if (IS_ERR(adap->kthread_config)) { + adap->kthread_config = NULL; + } else if (block) { + mutex_unlock(&adap->lock); + wait_for_completion(&adap->config_completion); + mutex_lock(&adap->lock); + } +} + +/* Set a new physical address and send an event notifying userspace of this. + * + * This function is called with adap->lock held. + */ +void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) +{ + if (phys_addr == adap->phys_addr || adap->devnode.unregistered) + return; + + if (phys_addr == CEC_PHYS_ADDR_INVALID || + adap->phys_addr != CEC_PHYS_ADDR_INVALID) { + adap->phys_addr = CEC_PHYS_ADDR_INVALID; + cec_post_state_event(adap); + cec_adap_unconfigure(adap); + /* Disabling monitor all mode should always succeed */ + if (adap->monitor_all_cnt) + WARN_ON(call_op(adap, adap_monitor_all_enable, false)); + WARN_ON(adap->ops->adap_enable(adap, false)); + if (phys_addr == CEC_PHYS_ADDR_INVALID) + return; + } + + if (adap->ops->adap_enable(adap, true)) + return; + + if (adap->monitor_all_cnt && + call_op(adap, adap_monitor_all_enable, true)) { + WARN_ON(adap->ops->adap_enable(adap, false)); + return; + } + adap->phys_addr = phys_addr; + cec_post_state_event(adap); + if (adap->log_addrs.num_log_addrs) + cec_claim_log_addrs(adap, block); +} + +void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) +{ + if (IS_ERR_OR_NULL(adap)) + return; + + mutex_lock(&adap->lock); + __cec_s_phys_addr(adap, phys_addr, block); + mutex_unlock(&adap->lock); +} +EXPORT_SYMBOL_GPL(cec_s_phys_addr); + +/* + * Called from either the ioctl or a driver to set the logical addresses. + * + * This function is called with adap->lock held. + */ +int __cec_s_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs *log_addrs, bool block) +{ + u16 type_mask = 0; + int i; + + if (adap->devnode.unregistered) + return -ENODEV; + + if (!log_addrs || log_addrs->num_log_addrs == 0) { + adap->log_addrs.num_log_addrs = 0; + cec_adap_unconfigure(adap); + return 0; + } + + if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) { + /* + * Sanitize log_addrs fields if a CDC-Only device is + * requested. + */ + log_addrs->num_log_addrs = 1; + log_addrs->osd_name[0] = '\0'; + log_addrs->vendor_id = CEC_VENDOR_ID_NONE; + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + /* + * This is just an internal convention since a CDC-Only device + * doesn't have to be a switch. But switches already use + * unregistered, so it makes some kind of sense to pick this + * as the primary device. Since a CDC-Only device never sends + * any 'normal' CEC messages this primary device type is never + * sent over the CEC bus. + */ + log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; + log_addrs->all_device_types[0] = 0; + log_addrs->features[0][0] = 0; + log_addrs->features[0][1] = 0; + } + + /* Ensure the osd name is 0-terminated */ + log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0'; + + /* Sanity checks */ + if (log_addrs->num_log_addrs > adap->available_log_addrs) { + dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs); + return -EINVAL; + } + + /* + * Vendor ID is a 24 bit number, so check if the value is + * within the correct range. + */ + if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE && + (log_addrs->vendor_id & 0xff000000) != 0) + return -EINVAL; + + if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 && + log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) + return -EINVAL; + + if (log_addrs->num_log_addrs > 1) + for (i = 0; i < log_addrs->num_log_addrs; i++) + if (log_addrs->log_addr_type[i] == + CEC_LOG_ADDR_TYPE_UNREGISTERED) { + dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n"); + return -EINVAL; + } + + for (i = 0; i < log_addrs->num_log_addrs; i++) { + const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]); + u8 *features = log_addrs->features[i]; + bool op_is_dev_features = false; + + log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; + if (type_mask & (1 << log_addrs->log_addr_type[i])) { + dprintk(1, "duplicate logical address type\n"); + return -EINVAL; + } + type_mask |= 1 << log_addrs->log_addr_type[i]; + if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) && + (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) { + /* Record already contains the playback functionality */ + dprintk(1, "invalid record + playback combination\n"); + return -EINVAL; + } + if (log_addrs->primary_device_type[i] > + CEC_OP_PRIM_DEVTYPE_PROCESSOR) { + dprintk(1, "unknown primary device type\n"); + return -EINVAL; + } + if (log_addrs->primary_device_type[i] == 2) { + dprintk(1, "invalid primary device type\n"); + return -EINVAL; + } + if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { + dprintk(1, "unknown logical address type\n"); + return -EINVAL; + } + for (i = 0; i < feature_sz; i++) { + if ((features[i] & 0x80) == 0) { + if (op_is_dev_features) + break; + op_is_dev_features = true; + } + } + if (!op_is_dev_features || i == feature_sz) { + dprintk(1, "malformed features\n"); + return -EINVAL; + } + /* Zero unused part of the feature array */ + memset(features + i + 1, 0, feature_sz - i - 1); + } + + if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) { + if (log_addrs->num_log_addrs > 2) { + dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n"); + return -EINVAL; + } + if (log_addrs->num_log_addrs == 2) { + if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) | + (1 << CEC_LOG_ADDR_TYPE_TV)))) { + dprintk(1, "Two LAs is only allowed for audiosystem and TV\n"); + return -EINVAL; + } + if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) | + (1 << CEC_LOG_ADDR_TYPE_RECORD)))) { + dprintk(1, "An audiosystem/TV can only be combined with record or playback\n"); + return -EINVAL; + } + } + } + + /* Zero unused LAs */ + for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) { + log_addrs->primary_device_type[i] = 0; + log_addrs->log_addr_type[i] = 0; + log_addrs->all_device_types[i] = 0; + memset(log_addrs->features[i], 0, + sizeof(log_addrs->features[i])); + } + + log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask; + adap->log_addrs = *log_addrs; + if (adap->phys_addr != CEC_PHYS_ADDR_INVALID) + cec_claim_log_addrs(adap, block); + return 0; +} + +int cec_s_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs *log_addrs, bool block) +{ + int err; + + mutex_lock(&adap->lock); + err = __cec_s_log_addrs(adap, log_addrs, block); + mutex_unlock(&adap->lock); + return err; +} +EXPORT_SYMBOL_GPL(cec_s_log_addrs); + +/* High-level core CEC message handling */ + +/* Transmit the Report Features message */ +static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx) +{ + struct cec_msg msg = { }; + const struct cec_log_addrs *las = &adap->log_addrs; + const u8 *features = las->features[la_idx]; + bool op_is_dev_features = false; + unsigned int idx; + + /* This is 2.0 and up only */ + if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) + return 0; + + /* Report Features */ + msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; + msg.len = 4; + msg.msg[1] = CEC_MSG_REPORT_FEATURES; + msg.msg[2] = adap->log_addrs.cec_version; + msg.msg[3] = las->all_device_types[la_idx]; + + /* Write RC Profiles first, then Device Features */ + for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { + msg.msg[msg.len++] = features[idx]; + if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { + if (op_is_dev_features) + break; + op_is_dev_features = true; + } + } + return cec_transmit_msg(adap, &msg, false); +} + +/* Transmit the Report Physical Address message */ +static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx) +{ + const struct cec_log_addrs *las = &adap->log_addrs; + struct cec_msg msg = { }; + + /* Report Physical Address */ + msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; + cec_msg_report_physical_addr(&msg, adap->phys_addr, + las->primary_device_type[la_idx]); + dprintk(2, "config: la %d pa %x.%x.%x.%x\n", + las->log_addr[la_idx], + cec_phys_addr_exp(adap->phys_addr)); + return cec_transmit_msg(adap, &msg, false); +} + +/* Transmit the Feature Abort message */ +static int cec_feature_abort_reason(struct cec_adapter *adap, + struct cec_msg *msg, u8 reason) +{ + struct cec_msg tx_msg = { }; + + /* + * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT + * message! + */ + if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) + return 0; + cec_msg_set_reply_to(&tx_msg, msg); + cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); + return cec_transmit_msg(adap, &tx_msg, false); +} + +static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg) +{ + return cec_feature_abort_reason(adap, msg, + CEC_OP_ABORT_UNRECOGNIZED_OP); +} + +static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg) +{ + return cec_feature_abort_reason(adap, msg, + CEC_OP_ABORT_REFUSED); +} + +/* + * Called when a CEC message is received. This function will do any + * necessary core processing. The is_reply bool is true if this message + * is a reply to an earlier transmit. + * + * The message is either a broadcast message or a valid directed message. + */ +static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + bool is_reply) +{ + bool is_broadcast = cec_msg_is_broadcast(msg); + u8 dest_laddr = cec_msg_destination(msg); + u8 init_laddr = cec_msg_initiator(msg); + u8 devtype = cec_log_addr2dev(adap, dest_laddr); + int la_idx = cec_log_addr2idx(adap, dest_laddr); + bool from_unregistered = init_laddr == 0xf; + struct cec_msg tx_cec_msg = { }; + + dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg); + + /* If this is a CDC-Only device, then ignore any non-CDC messages */ + if (cec_is_cdc_only(&adap->log_addrs) && + msg->msg[1] != CEC_MSG_CDC_MESSAGE) + return 0; + + if (adap->ops->received) { + /* Allow drivers to process the message first */ + if (adap->ops->received(adap, msg) != -ENOMSG) + return 0; + } + + /* + * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and + * CEC_MSG_USER_CONTROL_RELEASED messages always have to be + * handled by the CEC core, even if the passthrough mode is on. + * The others are just ignored if passthrough mode is on. + */ + switch (msg->msg[1]) { + case CEC_MSG_GET_CEC_VERSION: + case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + case CEC_MSG_ABORT: + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: + case CEC_MSG_GIVE_PHYSICAL_ADDR: + case CEC_MSG_GIVE_OSD_NAME: + case CEC_MSG_GIVE_FEATURES: + /* + * Skip processing these messages if the passthrough mode + * is on. + */ + if (adap->passthrough) + goto skip_processing; + /* Ignore if addressing is wrong */ + if (is_broadcast || from_unregistered) + return 0; + break; + + case CEC_MSG_USER_CONTROL_PRESSED: + case CEC_MSG_USER_CONTROL_RELEASED: + /* Wrong addressing mode: don't process */ + if (is_broadcast || from_unregistered) + goto skip_processing; + break; + + case CEC_MSG_REPORT_PHYSICAL_ADDR: + /* + * This message is always processed, regardless of the + * passthrough setting. + * + * Exception: don't process if wrong addressing mode. + */ + if (!is_broadcast) + goto skip_processing; + break; + + default: + break; + } + + cec_msg_set_reply_to(&tx_cec_msg, msg); + + switch (msg->msg[1]) { + /* The following messages are processed but still passed through */ + case CEC_MSG_REPORT_PHYSICAL_ADDR: { + u16 pa = (msg->msg[2] << 8) | msg->msg[3]; + + if (!from_unregistered) + adap->phys_addrs[init_laddr] = pa; + dprintk(1, "Reported physical address %x.%x.%x.%x for logical address %d\n", + cec_phys_addr_exp(pa), init_laddr); + break; + } + + case CEC_MSG_USER_CONTROL_PRESSED: + if (!(adap->capabilities & CEC_CAP_RC) || + !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) + break; + +#if IS_REACHABLE(CONFIG_RC_CORE) + switch (msg->msg[2]) { + /* + * Play function, this message can have variable length + * depending on the specific play function that is used. + */ + case 0x60: + if (msg->len == 2) + rc_keydown(adap->rc, RC_TYPE_CEC, + msg->msg[2], 0); + else + rc_keydown(adap->rc, RC_TYPE_CEC, + msg->msg[2] << 8 | msg->msg[3], 0); + break; + /* + * Other function messages that are not handled. + * Currently the RC framework does not allow to supply an + * additional parameter to a keypress. These "keys" contain + * other information such as channel number, an input number + * etc. + * For the time being these messages are not processed by the + * framework and are simply forwarded to the user space. + */ + case 0x56: case 0x57: + case 0x67: case 0x68: case 0x69: case 0x6a: + break; + default: + rc_keydown(adap->rc, RC_TYPE_CEC, msg->msg[2], 0); + break; + } +#endif + break; + + case CEC_MSG_USER_CONTROL_RELEASED: + if (!(adap->capabilities & CEC_CAP_RC) || + !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) + break; +#if IS_REACHABLE(CONFIG_RC_CORE) + rc_keyup(adap->rc); +#endif + break; + + /* + * The remaining messages are only processed if the passthrough mode + * is off. + */ + case CEC_MSG_GET_CEC_VERSION: + cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version); + return cec_transmit_msg(adap, &tx_cec_msg, false); + + case CEC_MSG_GIVE_PHYSICAL_ADDR: + /* Do nothing for CEC switches using addr 15 */ + if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15) + return 0; + cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype); + return cec_transmit_msg(adap, &tx_cec_msg, false); + + case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE) + return cec_feature_abort(adap, msg); + cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id); + return cec_transmit_msg(adap, &tx_cec_msg, false); + + case CEC_MSG_ABORT: + /* Do nothing for CEC switches */ + if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH) + return 0; + return cec_feature_refused(adap, msg); + + case CEC_MSG_GIVE_OSD_NAME: { + if (adap->log_addrs.osd_name[0] == 0) + return cec_feature_abort(adap, msg); + cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name); + return cec_transmit_msg(adap, &tx_cec_msg, false); + } + + case CEC_MSG_GIVE_FEATURES: + if (adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) + return cec_report_features(adap, la_idx); + return 0; + + default: + /* + * Unprocessed messages are aborted if userspace isn't doing + * any processing either. + */ + if (!is_broadcast && !is_reply && !adap->follower_cnt && + !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) + return cec_feature_abort(adap, msg); + break; + } + +skip_processing: + /* If this was a reply, then we're done, unless otherwise specified */ + if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS)) + return 0; + + /* + * Send to the exclusive follower if there is one, otherwise send + * to all followers. + */ + if (adap->cec_follower) + cec_queue_msg_fh(adap->cec_follower, msg); + else + cec_queue_msg_followers(adap, msg); + return 0; +} + +/* + * Helper functions to keep track of the 'monitor all' use count. + * + * These functions are called with adap->lock held. + */ +int cec_monitor_all_cnt_inc(struct cec_adapter *adap) +{ + int ret = 0; + + if (adap->monitor_all_cnt == 0) + ret = call_op(adap, adap_monitor_all_enable, 1); + if (ret == 0) + adap->monitor_all_cnt++; + return ret; +} + +void cec_monitor_all_cnt_dec(struct cec_adapter *adap) +{ + adap->monitor_all_cnt--; + if (adap->monitor_all_cnt == 0) + WARN_ON(call_op(adap, adap_monitor_all_enable, 0)); +} + +#ifdef CONFIG_MEDIA_CEC_DEBUG +/* + * Log the current state of the CEC adapter. + * Very useful for debugging. + */ +int cec_adap_status(struct seq_file *file, void *priv) +{ + struct cec_adapter *adap = dev_get_drvdata(file->private); + struct cec_data *data; + + mutex_lock(&adap->lock); + seq_printf(file, "configured: %d\n", adap->is_configured); + seq_printf(file, "configuring: %d\n", adap->is_configuring); + seq_printf(file, "phys_addr: %x.%x.%x.%x\n", + cec_phys_addr_exp(adap->phys_addr)); + seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs); + seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask); + if (adap->cec_follower) + seq_printf(file, "has CEC follower%s\n", + adap->passthrough ? " (in passthrough mode)" : ""); + if (adap->cec_initiator) + seq_puts(file, "has CEC initiator\n"); + if (adap->monitor_all_cnt) + seq_printf(file, "file handles in Monitor All mode: %u\n", + adap->monitor_all_cnt); + data = adap->transmitting; + if (data) + seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", + data->msg.len, data->msg.msg, data->msg.reply, + data->msg.timeout); + seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz); + list_for_each_entry(data, &adap->transmit_queue, list) { + seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n", + data->msg.len, data->msg.msg, data->msg.reply, + data->msg.timeout); + } + list_for_each_entry(data, &adap->wait_queue, list) { + seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n", + data->msg.len, data->msg.msg, data->msg.reply, + data->msg.timeout); + } + + call_void_op(adap, adap_status, file); + mutex_unlock(&adap->lock); + return 0; +} +#endif diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c new file mode 100644 index 000000000000..d4bc4ee2c6e5 --- /dev/null +++ b/drivers/media/cec/cec-api.c @@ -0,0 +1,588 @@ +/* + * cec-api.c - HDMI Consumer Electronics Control framework - API + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cec-priv.h" + +static inline struct cec_devnode *cec_devnode_data(struct file *filp) +{ + struct cec_fh *fh = filp->private_data; + + return &fh->adap->devnode; +} + +/* CEC file operations */ + +static unsigned int cec_poll(struct file *filp, + struct poll_table_struct *poll) +{ + struct cec_devnode *devnode = cec_devnode_data(filp); + struct cec_fh *fh = filp->private_data; + struct cec_adapter *adap = fh->adap; + unsigned int res = 0; + + if (!devnode->registered) + return POLLERR | POLLHUP; + mutex_lock(&adap->lock); + if (adap->is_configured && + adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ) + res |= POLLOUT | POLLWRNORM; + if (fh->queued_msgs) + res |= POLLIN | POLLRDNORM; + if (fh->pending_events) + res |= POLLPRI; + poll_wait(filp, &fh->wait, poll); + mutex_unlock(&adap->lock); + return res; +} + +static bool cec_is_busy(const struct cec_adapter *adap, + const struct cec_fh *fh) +{ + bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh; + bool valid_follower = adap->cec_follower && adap->cec_follower == fh; + + /* + * Exclusive initiators and followers can always access the CEC adapter + */ + if (valid_initiator || valid_follower) + return false; + /* + * All others can only access the CEC adapter if there is no + * exclusive initiator and they are in INITIATOR mode. + */ + return adap->cec_initiator || + fh->mode_initiator == CEC_MODE_NO_INITIATOR; +} + +static long cec_adap_g_caps(struct cec_adapter *adap, + struct cec_caps __user *parg) +{ + struct cec_caps caps = {}; + + strlcpy(caps.driver, adap->devnode.parent->driver->name, + sizeof(caps.driver)); + strlcpy(caps.name, adap->name, sizeof(caps.name)); + caps.available_log_addrs = adap->available_log_addrs; + caps.capabilities = adap->capabilities; + caps.version = LINUX_VERSION_CODE; + if (copy_to_user(parg, &caps, sizeof(caps))) + return -EFAULT; + return 0; +} + +static long cec_adap_g_phys_addr(struct cec_adapter *adap, + __u16 __user *parg) +{ + u16 phys_addr; + + mutex_lock(&adap->lock); + phys_addr = adap->phys_addr; + mutex_unlock(&adap->lock); + if (copy_to_user(parg, &phys_addr, sizeof(phys_addr))) + return -EFAULT; + return 0; +} + +static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh, + bool block, __u16 __user *parg) +{ + u16 phys_addr; + long err; + + if (!(adap->capabilities & CEC_CAP_PHYS_ADDR)) + return -ENOTTY; + if (copy_from_user(&phys_addr, parg, sizeof(phys_addr))) + return -EFAULT; + + err = cec_phys_addr_validate(phys_addr, NULL, NULL); + if (err) + return err; + mutex_lock(&adap->lock); + if (cec_is_busy(adap, fh)) + err = -EBUSY; + else + __cec_s_phys_addr(adap, phys_addr, block); + mutex_unlock(&adap->lock); + return err; +} + +static long cec_adap_g_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs __user *parg) +{ + struct cec_log_addrs log_addrs; + + mutex_lock(&adap->lock); + log_addrs = adap->log_addrs; + if (!adap->is_configured) + memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID, + sizeof(log_addrs.log_addr)); + mutex_unlock(&adap->lock); + + if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) + return -EFAULT; + return 0; +} + +static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, + bool block, struct cec_log_addrs __user *parg) +{ + struct cec_log_addrs log_addrs; + long err = -EBUSY; + + if (!(adap->capabilities & CEC_CAP_LOG_ADDRS)) + return -ENOTTY; + if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) + return -EFAULT; + log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK | + CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU | + CEC_LOG_ADDRS_FL_CDC_ONLY; + mutex_lock(&adap->lock); + if (!adap->is_configuring && + (!log_addrs.num_log_addrs || !adap->is_configured) && + !cec_is_busy(adap, fh)) { + err = __cec_s_log_addrs(adap, &log_addrs, block); + if (!err) + log_addrs = adap->log_addrs; + } + mutex_unlock(&adap->lock); + if (err) + return err; + if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) + return -EFAULT; + return 0; +} + +static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, + bool block, struct cec_msg __user *parg) +{ + struct cec_msg msg = {}; + long err = 0; + + if (!(adap->capabilities & CEC_CAP_TRANSMIT)) + return -ENOTTY; + if (copy_from_user(&msg, parg, sizeof(msg))) + return -EFAULT; + + /* A CDC-Only device can only send CDC messages */ + if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) && + (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE)) + return -EINVAL; + + msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; + mutex_lock(&adap->lock); + if (!adap->is_configured) + err = -ENONET; + else if (cec_is_busy(adap, fh)) + err = -EBUSY; + else + err = cec_transmit_msg_fh(adap, &msg, fh, block); + mutex_unlock(&adap->lock); + if (err) + return err; + if (copy_to_user(parg, &msg, sizeof(msg))) + return -EFAULT; + return 0; +} + +/* Called by CEC_RECEIVE: wait for a message to arrive */ +static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block) +{ + u32 timeout = msg->timeout; + int res; + + do { + mutex_lock(&fh->lock); + /* Are there received messages queued up? */ + if (fh->queued_msgs) { + /* Yes, return the first one */ + struct cec_msg_entry *entry = + list_first_entry(&fh->msgs, + struct cec_msg_entry, list); + + list_del(&entry->list); + *msg = entry->msg; + kfree(entry); + fh->queued_msgs--; + mutex_unlock(&fh->lock); + /* restore original timeout value */ + msg->timeout = timeout; + return 0; + } + + /* No, return EAGAIN in non-blocking mode or wait */ + mutex_unlock(&fh->lock); + + /* Return when in non-blocking mode */ + if (!block) + return -EAGAIN; + + if (msg->timeout) { + /* The user specified a timeout */ + res = wait_event_interruptible_timeout(fh->wait, + fh->queued_msgs, + msecs_to_jiffies(msg->timeout)); + if (res == 0) + res = -ETIMEDOUT; + else if (res > 0) + res = 0; + } else { + /* Wait indefinitely */ + res = wait_event_interruptible(fh->wait, + fh->queued_msgs); + } + /* Exit on error, otherwise loop to get the new message */ + } while (!res); + return res; +} + +static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh, + bool block, struct cec_msg __user *parg) +{ + struct cec_msg msg = {}; + long err = 0; + + if (copy_from_user(&msg, parg, sizeof(msg))) + return -EFAULT; + mutex_lock(&adap->lock); + if (!adap->is_configured && fh->mode_follower < CEC_MODE_MONITOR) + err = -ENONET; + mutex_unlock(&adap->lock); + if (err) + return err; + + err = cec_receive_msg(fh, &msg, block); + if (err) + return err; + if (copy_to_user(parg, &msg, sizeof(msg))) + return -EFAULT; + return 0; +} + +static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, + bool block, struct cec_event __user *parg) +{ + struct cec_event *ev = NULL; + u64 ts = ~0ULL; + unsigned int i; + long err = 0; + + mutex_lock(&fh->lock); + while (!fh->pending_events && block) { + mutex_unlock(&fh->lock); + err = wait_event_interruptible(fh->wait, fh->pending_events); + if (err) + return err; + mutex_lock(&fh->lock); + } + + /* Find the oldest event */ + for (i = 0; i < CEC_NUM_EVENTS; i++) { + if (fh->pending_events & (1 << (i + 1)) && + fh->events[i].ts <= ts) { + ev = &fh->events[i]; + ts = ev->ts; + } + } + if (!ev) { + err = -EAGAIN; + goto unlock; + } + + if (copy_to_user(parg, ev, sizeof(*ev))) { + err = -EFAULT; + goto unlock; + } + + fh->pending_events &= ~(1 << ev->event); + +unlock: + mutex_unlock(&fh->lock); + return err; +} + +static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh, + u32 __user *parg) +{ + u32 mode = fh->mode_initiator | fh->mode_follower; + + if (copy_to_user(parg, &mode, sizeof(mode))) + return -EFAULT; + return 0; +} + +static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, + u32 __user *parg) +{ + u32 mode; + u8 mode_initiator; + u8 mode_follower; + long err = 0; + + if (copy_from_user(&mode, parg, sizeof(mode))) + return -EFAULT; + if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) + return -EINVAL; + + mode_initiator = mode & CEC_MODE_INITIATOR_MSK; + mode_follower = mode & CEC_MODE_FOLLOWER_MSK; + + if (mode_initiator > CEC_MODE_EXCL_INITIATOR || + mode_follower > CEC_MODE_MONITOR_ALL) + return -EINVAL; + + if (mode_follower == CEC_MODE_MONITOR_ALL && + !(adap->capabilities & CEC_CAP_MONITOR_ALL)) + return -EINVAL; + + /* Follower modes should always be able to send CEC messages */ + if ((mode_initiator == CEC_MODE_NO_INITIATOR || + !(adap->capabilities & CEC_CAP_TRANSMIT)) && + mode_follower >= CEC_MODE_FOLLOWER && + mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) + return -EINVAL; + + /* Monitor modes require CEC_MODE_NO_INITIATOR */ + if (mode_initiator && mode_follower >= CEC_MODE_MONITOR) + return -EINVAL; + + /* Monitor modes require CAP_NET_ADMIN */ + if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN)) + return -EPERM; + + mutex_lock(&adap->lock); + /* + * You can't become exclusive follower if someone else already + * has that job. + */ + if ((mode_follower == CEC_MODE_EXCL_FOLLOWER || + mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) && + adap->cec_follower && adap->cec_follower != fh) + err = -EBUSY; + /* + * You can't become exclusive initiator if someone else already + * has that job. + */ + if (mode_initiator == CEC_MODE_EXCL_INITIATOR && + adap->cec_initiator && adap->cec_initiator != fh) + err = -EBUSY; + + if (!err) { + bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL; + bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL; + + if (old_mon_all != new_mon_all) { + if (new_mon_all) + err = cec_monitor_all_cnt_inc(adap); + else + cec_monitor_all_cnt_dec(adap); + } + } + + if (err) { + mutex_unlock(&adap->lock); + return err; + } + + if (fh->mode_follower == CEC_MODE_FOLLOWER) + adap->follower_cnt--; + if (mode_follower == CEC_MODE_FOLLOWER) + adap->follower_cnt++; + if (mode_follower == CEC_MODE_EXCL_FOLLOWER || + mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { + adap->passthrough = + mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU; + adap->cec_follower = fh; + } else if (adap->cec_follower == fh) { + adap->passthrough = false; + adap->cec_follower = NULL; + } + if (mode_initiator == CEC_MODE_EXCL_INITIATOR) + adap->cec_initiator = fh; + else if (adap->cec_initiator == fh) + adap->cec_initiator = NULL; + fh->mode_initiator = mode_initiator; + fh->mode_follower = mode_follower; + mutex_unlock(&adap->lock); + return 0; +} + +static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct cec_devnode *devnode = cec_devnode_data(filp); + struct cec_fh *fh = filp->private_data; + struct cec_adapter *adap = fh->adap; + bool block = !(filp->f_flags & O_NONBLOCK); + void __user *parg = (void __user *)arg; + + if (!devnode->registered) + return -ENODEV; + + switch (cmd) { + case CEC_ADAP_G_CAPS: + return cec_adap_g_caps(adap, parg); + + case CEC_ADAP_G_PHYS_ADDR: + return cec_adap_g_phys_addr(adap, parg); + + case CEC_ADAP_S_PHYS_ADDR: + return cec_adap_s_phys_addr(adap, fh, block, parg); + + case CEC_ADAP_G_LOG_ADDRS: + return cec_adap_g_log_addrs(adap, parg); + + case CEC_ADAP_S_LOG_ADDRS: + return cec_adap_s_log_addrs(adap, fh, block, parg); + + case CEC_TRANSMIT: + return cec_transmit(adap, fh, block, parg); + + case CEC_RECEIVE: + return cec_receive(adap, fh, block, parg); + + case CEC_DQEVENT: + return cec_dqevent(adap, fh, block, parg); + + case CEC_G_MODE: + return cec_g_mode(adap, fh, parg); + + case CEC_S_MODE: + return cec_s_mode(adap, fh, parg); + + default: + return -ENOTTY; + } +} + +static int cec_open(struct inode *inode, struct file *filp) +{ + struct cec_devnode *devnode = + container_of(inode->i_cdev, struct cec_devnode, cdev); + struct cec_adapter *adap = to_cec_adapter(devnode); + struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + /* + * Initial events that are automatically sent when the cec device is + * opened. + */ + struct cec_event ev_state = { + .event = CEC_EVENT_STATE_CHANGE, + .flags = CEC_EVENT_FL_INITIAL_STATE, + }; + int err; + + if (!fh) + return -ENOMEM; + + INIT_LIST_HEAD(&fh->msgs); + INIT_LIST_HEAD(&fh->xfer_list); + mutex_init(&fh->lock); + init_waitqueue_head(&fh->wait); + + fh->mode_initiator = CEC_MODE_INITIATOR; + fh->adap = adap; + + err = cec_get_device(devnode); + if (err) { + kfree(fh); + return err; + } + + filp->private_data = fh; + + mutex_lock(&devnode->lock); + /* Queue up initial state events */ + ev_state.state_change.phys_addr = adap->phys_addr; + ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; + cec_queue_event_fh(fh, &ev_state, 0); + + list_add(&fh->list, &devnode->fhs); + mutex_unlock(&devnode->lock); + + return 0; +} + +/* Override for the release function */ +static int cec_release(struct inode *inode, struct file *filp) +{ + struct cec_devnode *devnode = cec_devnode_data(filp); + struct cec_adapter *adap = to_cec_adapter(devnode); + struct cec_fh *fh = filp->private_data; + + mutex_lock(&adap->lock); + if (adap->cec_initiator == fh) + adap->cec_initiator = NULL; + if (adap->cec_follower == fh) { + adap->cec_follower = NULL; + adap->passthrough = false; + } + if (fh->mode_follower == CEC_MODE_FOLLOWER) + adap->follower_cnt--; + if (fh->mode_follower == CEC_MODE_MONITOR_ALL) + cec_monitor_all_cnt_dec(adap); + mutex_unlock(&adap->lock); + + mutex_lock(&devnode->lock); + list_del(&fh->list); + mutex_unlock(&devnode->lock); + + /* Unhook pending transmits from this filehandle. */ + mutex_lock(&adap->lock); + while (!list_empty(&fh->xfer_list)) { + struct cec_data *data = + list_first_entry(&fh->xfer_list, struct cec_data, xfer_list); + + data->blocking = false; + data->fh = NULL; + list_del(&data->xfer_list); + } + mutex_unlock(&adap->lock); + while (!list_empty(&fh->msgs)) { + struct cec_msg_entry *entry = + list_first_entry(&fh->msgs, struct cec_msg_entry, list); + + list_del(&entry->list); + kfree(entry); + } + kfree(fh); + + cec_put_device(devnode); + filp->private_data = NULL; + return 0; +} + +const struct file_operations cec_devnode_fops = { + .owner = THIS_MODULE, + .open = cec_open, + .unlocked_ioctl = cec_ioctl, + .release = cec_release, + .poll = cec_poll, + .llseek = no_llseek, +}; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c new file mode 100644 index 000000000000..b0137e247dc9 --- /dev/null +++ b/drivers/media/cec/cec-core.c @@ -0,0 +1,411 @@ +/* + * cec-core.c - HDMI Consumer Electronics Control framework - Core + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cec-priv.h" + +#define CEC_NUM_DEVICES 256 +#define CEC_NAME "cec" + +int cec_debug; +module_param_named(debug, cec_debug, int, 0644); +MODULE_PARM_DESC(debug, "debug level (0-2)"); + +static dev_t cec_dev_t; + +/* Active devices */ +static DEFINE_MUTEX(cec_devnode_lock); +static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES); + +static struct dentry *top_cec_dir; + +/* dev to cec_devnode */ +#define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev) + +int cec_get_device(struct cec_devnode *devnode) +{ + /* + * Check if the cec device is available. This needs to be done with + * the devnode->lock held to prevent an open/unregister race: + * without the lock, the device could be unregistered and freed between + * the devnode->registered check and get_device() calls, leading to + * a crash. + */ + mutex_lock(&devnode->lock); + /* + * return ENXIO if the cec device has been removed + * already or if it is not registered anymore. + */ + if (!devnode->registered) { + mutex_unlock(&devnode->lock); + return -ENXIO; + } + /* and increase the device refcount */ + get_device(&devnode->dev); + mutex_unlock(&devnode->lock); + return 0; +} + +void cec_put_device(struct cec_devnode *devnode) +{ + put_device(&devnode->dev); +} + +/* Called when the last user of the cec device exits. */ +static void cec_devnode_release(struct device *cd) +{ + struct cec_devnode *devnode = to_cec_devnode(cd); + + mutex_lock(&cec_devnode_lock); + /* Mark device node number as free */ + clear_bit(devnode->minor, cec_devnode_nums); + mutex_unlock(&cec_devnode_lock); + + cec_delete_adapter(to_cec_adapter(devnode)); +} + +static struct bus_type cec_bus_type = { + .name = CEC_NAME, +}; + +/* + * Register a cec device node + * + * The registration code assigns minor numbers and registers the new device node + * with the kernel. An error is returned if no free minor number can be found, + * or if the registration of the device node fails. + * + * Zero is returned on success. + * + * Note that if the cec_devnode_register call fails, the release() callback of + * the cec_devnode structure is *not* called, so the caller is responsible for + * freeing any data. + */ +static int __must_check cec_devnode_register(struct cec_devnode *devnode, + struct module *owner) +{ + int minor; + int ret; + + /* Initialization */ + INIT_LIST_HEAD(&devnode->fhs); + mutex_init(&devnode->lock); + + /* Part 1: Find a free minor number */ + mutex_lock(&cec_devnode_lock); + minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0); + if (minor == CEC_NUM_DEVICES) { + mutex_unlock(&cec_devnode_lock); + pr_err("could not get a free minor\n"); + return -ENFILE; + } + + set_bit(minor, cec_devnode_nums); + mutex_unlock(&cec_devnode_lock); + + devnode->minor = minor; + devnode->dev.bus = &cec_bus_type; + devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor); + devnode->dev.release = cec_devnode_release; + devnode->dev.parent = devnode->parent; + dev_set_name(&devnode->dev, "cec%d", devnode->minor); + device_initialize(&devnode->dev); + + /* Part 2: Initialize and register the character device */ + cdev_init(&devnode->cdev, &cec_devnode_fops); + devnode->cdev.kobj.parent = &devnode->dev.kobj; + devnode->cdev.owner = owner; + + ret = cdev_add(&devnode->cdev, devnode->dev.devt, 1); + if (ret < 0) { + pr_err("%s: cdev_add failed\n", __func__); + goto clr_bit; + } + + ret = device_add(&devnode->dev); + if (ret) + goto cdev_del; + + devnode->registered = true; + return 0; + +cdev_del: + cdev_del(&devnode->cdev); +clr_bit: + mutex_lock(&cec_devnode_lock); + clear_bit(devnode->minor, cec_devnode_nums); + mutex_unlock(&cec_devnode_lock); + return ret; +} + +/* + * Unregister a cec device node + * + * This unregisters the passed device. Future open calls will be met with + * errors. + * + * This function can safely be called if the device node has never been + * registered or has already been unregistered. + */ +static void cec_devnode_unregister(struct cec_devnode *devnode) +{ + struct cec_fh *fh; + + mutex_lock(&devnode->lock); + + /* Check if devnode was never registered or already unregistered */ + if (!devnode->registered || devnode->unregistered) { + mutex_unlock(&devnode->lock); + return; + } + + list_for_each_entry(fh, &devnode->fhs, list) + wake_up_interruptible(&fh->wait); + + devnode->registered = false; + devnode->unregistered = true; + mutex_unlock(&devnode->lock); + + device_del(&devnode->dev); + cdev_del(&devnode->cdev); + put_device(&devnode->dev); +} + +struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, + u8 available_las, struct device *parent) +{ + struct cec_adapter *adap; + int res; + + if (WARN_ON(!parent)) + return ERR_PTR(-EINVAL); + if (WARN_ON(!caps)) + return ERR_PTR(-EINVAL); + if (WARN_ON(!ops)) + return ERR_PTR(-EINVAL); + if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS)) + return ERR_PTR(-EINVAL); + adap = kzalloc(sizeof(*adap), GFP_KERNEL); + if (!adap) + return ERR_PTR(-ENOMEM); + adap->owner = parent->driver->owner; + adap->devnode.parent = parent; + strlcpy(adap->name, name, sizeof(adap->name)); + adap->phys_addr = CEC_PHYS_ADDR_INVALID; + adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; + adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; + adap->capabilities = caps; + adap->available_log_addrs = available_las; + adap->sequence = 0; + adap->ops = ops; + adap->priv = priv; + memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); + mutex_init(&adap->lock); + INIT_LIST_HEAD(&adap->transmit_queue); + INIT_LIST_HEAD(&adap->wait_queue); + init_waitqueue_head(&adap->kthread_waitq); + + adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name); + if (IS_ERR(adap->kthread)) { + pr_err("cec-%s: kernel_thread() failed\n", name); + res = PTR_ERR(adap->kthread); + kfree(adap); + return ERR_PTR(res); + } + + if (!(caps & CEC_CAP_RC)) + return adap; + +#if IS_REACHABLE(CONFIG_RC_CORE) + /* Prepare the RC input device */ + adap->rc = rc_allocate_device(); + if (!adap->rc) { + pr_err("cec-%s: failed to allocate memory for rc_dev\n", + name); + kthread_stop(adap->kthread); + kfree(adap); + return ERR_PTR(-ENOMEM); + } + + snprintf(adap->input_name, sizeof(adap->input_name), + "RC for %s", name); + snprintf(adap->input_phys, sizeof(adap->input_phys), + "%s/input0", name); + + adap->rc->input_name = adap->input_name; + adap->rc->input_phys = adap->input_phys; + adap->rc->input_id.bustype = BUS_CEC; + adap->rc->input_id.vendor = 0; + adap->rc->input_id.product = 0; + adap->rc->input_id.version = 1; + adap->rc->dev.parent = parent; + adap->rc->driver_type = RC_DRIVER_SCANCODE; + adap->rc->driver_name = CEC_NAME; + adap->rc->allowed_protocols = RC_BIT_CEC; + adap->rc->priv = adap; + adap->rc->map_name = RC_MAP_CEC; + adap->rc->timeout = MS_TO_NS(100); +#else + adap->capabilities &= ~CEC_CAP_RC; +#endif + return adap; +} +EXPORT_SYMBOL_GPL(cec_allocate_adapter); + +int cec_register_adapter(struct cec_adapter *adap) +{ + int res; + + if (IS_ERR_OR_NULL(adap)) + return 0; + +#if IS_REACHABLE(CONFIG_RC_CORE) + if (adap->capabilities & CEC_CAP_RC) { + res = rc_register_device(adap->rc); + + if (res) { + pr_err("cec-%s: failed to prepare input device\n", + adap->name); + rc_free_device(adap->rc); + adap->rc = NULL; + return res; + } + } +#endif + + res = cec_devnode_register(&adap->devnode, adap->owner); + if (res) { +#if IS_REACHABLE(CONFIG_RC_CORE) + /* Note: rc_unregister also calls rc_free */ + rc_unregister_device(adap->rc); + adap->rc = NULL; +#endif + return res; + } + + dev_set_drvdata(&adap->devnode.dev, adap); +#ifdef CONFIG_MEDIA_CEC_DEBUG + if (!top_cec_dir) + return 0; + + adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir); + if (IS_ERR_OR_NULL(adap->cec_dir)) { + pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name); + return 0; + } + adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev, + "status", adap->cec_dir, cec_adap_status); + if (IS_ERR_OR_NULL(adap->status_file)) { + pr_warn("cec-%s: Failed to create status file\n", adap->name); + debugfs_remove_recursive(adap->cec_dir); + adap->cec_dir = NULL; + } +#endif + return 0; +} +EXPORT_SYMBOL_GPL(cec_register_adapter); + +void cec_unregister_adapter(struct cec_adapter *adap) +{ + if (IS_ERR_OR_NULL(adap)) + return; + +#if IS_REACHABLE(CONFIG_RC_CORE) + /* Note: rc_unregister also calls rc_free */ + rc_unregister_device(adap->rc); + adap->rc = NULL; +#endif + debugfs_remove_recursive(adap->cec_dir); + cec_devnode_unregister(&adap->devnode); +} +EXPORT_SYMBOL_GPL(cec_unregister_adapter); + +void cec_delete_adapter(struct cec_adapter *adap) +{ + if (IS_ERR_OR_NULL(adap)) + return; + mutex_lock(&adap->lock); + __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); + mutex_unlock(&adap->lock); + kthread_stop(adap->kthread); + if (adap->kthread_config) + kthread_stop(adap->kthread_config); +#if IS_REACHABLE(CONFIG_RC_CORE) + rc_free_device(adap->rc); +#endif + kfree(adap); +} +EXPORT_SYMBOL_GPL(cec_delete_adapter); + +/* + * Initialise cec for linux + */ +static int __init cec_devnode_init(void) +{ + int ret; + + pr_info("Linux cec interface: v0.10\n"); + ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, + CEC_NAME); + if (ret < 0) { + pr_warn("cec: unable to allocate major\n"); + return ret; + } + +#ifdef CONFIG_MEDIA_CEC_DEBUG + top_cec_dir = debugfs_create_dir("cec", NULL); + if (IS_ERR_OR_NULL(top_cec_dir)) { + pr_warn("cec: Failed to create debugfs cec dir\n"); + top_cec_dir = NULL; + } +#endif + + ret = bus_register(&cec_bus_type); + if (ret < 0) { + unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); + pr_warn("cec: bus_register failed\n"); + return -EIO; + } + + return 0; +} + +static void __exit cec_devnode_exit(void) +{ + debugfs_remove_recursive(top_cec_dir); + bus_unregister(&cec_bus_type); + unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); +} + +subsys_initcall(cec_devnode_init); +module_exit(cec_devnode_exit) + +MODULE_AUTHOR("Hans Verkuil "); +MODULE_DESCRIPTION("Device node registration for cec drivers"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h new file mode 100644 index 000000000000..70767a7900f2 --- /dev/null +++ b/drivers/media/cec/cec-priv.h @@ -0,0 +1,56 @@ +/* + * cec-priv.h - HDMI Consumer Electronics Control internal header + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _CEC_PRIV_H +#define _CEC_PRIV_H + +#include +#include + +#define dprintk(lvl, fmt, arg...) \ + do { \ + if (lvl <= cec_debug) \ + pr_info("cec-%s: " fmt, adap->name, ## arg); \ + } while (0) + +/* devnode to cec_adapter */ +#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode) + +/* cec-core.c */ +extern int cec_debug; +int cec_get_device(struct cec_devnode *devnode); +void cec_put_device(struct cec_devnode *devnode); + +/* cec-adap.c */ +int cec_monitor_all_cnt_inc(struct cec_adapter *adap); +void cec_monitor_all_cnt_dec(struct cec_adapter *adap); +int cec_adap_status(struct seq_file *file, void *priv); +int cec_thread_func(void *_adap); +void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block); +int __cec_s_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs *log_addrs, bool block); +int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, + struct cec_fh *fh, bool block); +void cec_queue_event_fh(struct cec_fh *fh, + const struct cec_event *new_ev, u64 ts); + +/* cec-api.c */ +extern const struct file_operations cec_devnode_fops; + +#endif diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 2669b4bad910..b31fa6fae009 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -221,7 +221,7 @@ config VIDEO_ADV7604 config VIDEO_ADV7604_CEC bool "Enable Analog Devices ADV7604 CEC support" - depends on VIDEO_ADV7604 && MEDIA_CEC + depends on VIDEO_ADV7604 && MEDIA_CEC_SUPPORT ---help--- When selected the adv7604 will support the optional HDMI CEC feature. @@ -242,7 +242,7 @@ config VIDEO_ADV7842 config VIDEO_ADV7842_CEC bool "Enable Analog Devices ADV7842 CEC support" - depends on VIDEO_ADV7842 && MEDIA_CEC + depends on VIDEO_ADV7842 && MEDIA_CEC_SUPPORT ---help--- When selected the adv7842 will support the optional HDMI CEC feature. @@ -481,7 +481,7 @@ config VIDEO_ADV7511 config VIDEO_ADV7511_CEC bool "Enable Analog Devices ADV7511 CEC support" - depends on VIDEO_ADV7511 && MEDIA_CEC + depends on VIDEO_ADV7511 && MEDIA_CEC_SUPPORT ---help--- When selected the adv7511 will support the optional HDMI CEC feature. diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig index 8e6918c5c87c..db0dd19d227a 100644 --- a/drivers/media/platform/vivid/Kconfig +++ b/drivers/media/platform/vivid/Kconfig @@ -25,7 +25,7 @@ config VIDEO_VIVID config VIDEO_VIVID_CEC bool "Enable CEC emulation support" - depends on VIDEO_VIVID && MEDIA_CEC + depends on VIDEO_VIVID && MEDIA_CEC_SUPPORT ---help--- When selected the vivid module will emulate the optional HDMI CEC feature. diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 6620d96ee44d..0abe5ffb4934 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -21,8 +21,6 @@ if STAGING_MEDIA && MEDIA_SUPPORT # Please keep them in alphabetic order source "drivers/staging/media/bcm2048/Kconfig" -source "drivers/staging/media/cec/Kconfig" - source "drivers/staging/media/cxd2099/Kconfig" source "drivers/staging/media/davinci_vpfe/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 906257e94dda..246299eff80d 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/ -obj-$(CONFIG_MEDIA_CEC) += cec/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ diff --git a/drivers/staging/media/cec/Kconfig b/drivers/staging/media/cec/Kconfig deleted file mode 100644 index 6e12d41b1f86..000000000000 --- a/drivers/staging/media/cec/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config MEDIA_CEC - bool "CEC API (EXPERIMENTAL)" - depends on MEDIA_SUPPORT - select MEDIA_CEC_EDID - ---help--- - Enable the CEC API. - -config MEDIA_CEC_DEBUG - bool "CEC debugfs interface (EXPERIMENTAL)" - depends on MEDIA_CEC && DEBUG_FS - ---help--- - Turns on the DebugFS interface for CEC devices. diff --git a/drivers/staging/media/cec/Makefile b/drivers/staging/media/cec/Makefile deleted file mode 100644 index bd7f3c593468..000000000000 --- a/drivers/staging/media/cec/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -cec-objs := cec-core.o cec-adap.o cec-api.o - -ifeq ($(CONFIG_MEDIA_CEC),y) - obj-$(CONFIG_MEDIA_SUPPORT) += cec.o -endif diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO deleted file mode 100644 index 504d35c7ae95..000000000000 --- a/drivers/staging/media/cec/TODO +++ /dev/null @@ -1,9 +0,0 @@ -TODOs: - -- Once this is out of staging this should no longer be a separate - config option, instead it should be selected by drivers that want it. -- Revisit the IS_REACHABLE(RC_CORE): perhaps the RC_CORE support should - be enabled through a separate config option in drivers/media/Kconfig - or rc/Kconfig? - -Hans Verkuil diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c deleted file mode 100644 index 054cd06e2247..000000000000 --- a/drivers/staging/media/cec/cec-adap.c +++ /dev/null @@ -1,1856 +0,0 @@ -/* - * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cec-priv.h" - -static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx); -static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx); - -/* - * 400 ms is the time it takes for one 16 byte message to be - * transferred and 5 is the maximum number of retries. Add - * another 100 ms as a margin. So if the transmit doesn't - * finish before that time something is really wrong and we - * have to time out. - * - * This is a sign that something it really wrong and a warning - * will be issued. - */ -#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100) - -#define call_op(adap, op, arg...) \ - (adap->ops->op ? adap->ops->op(adap, ## arg) : 0) - -#define call_void_op(adap, op, arg...) \ - do { \ - if (adap->ops->op) \ - adap->ops->op(adap, ## arg); \ - } while (0) - -static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr) -{ - int i; - - for (i = 0; i < adap->log_addrs.num_log_addrs; i++) - if (adap->log_addrs.log_addr[i] == log_addr) - return i; - return -1; -} - -static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr) -{ - int i = cec_log_addr2idx(adap, log_addr); - - return adap->log_addrs.primary_device_type[i < 0 ? 0 : i]; -} - -/* - * Queue a new event for this filehandle. If ts == 0, then set it - * to the current time. - * - * The two events that are currently defined do not need to keep track - * of intermediate events, so no actual queue of events is needed, - * instead just store the latest state and the total number of lost - * messages. - * - * Should new events be added in the future that require intermediate - * results to be queued as well, then a proper queue data structure is - * required. But until then, just keep it simple. - */ -void cec_queue_event_fh(struct cec_fh *fh, - const struct cec_event *new_ev, u64 ts) -{ - struct cec_event *ev = &fh->events[new_ev->event - 1]; - - if (ts == 0) - ts = ktime_get_ns(); - - mutex_lock(&fh->lock); - if (new_ev->event == CEC_EVENT_LOST_MSGS && - fh->pending_events & (1 << new_ev->event)) { - /* - * If there is already a lost_msgs event, then just - * update the lost_msgs count. This effectively - * merges the old and new events into one. - */ - ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; - goto unlock; - } - - /* - * Intermediate states are not interesting, so just - * overwrite any older event. - */ - *ev = *new_ev; - ev->ts = ts; - fh->pending_events |= 1 << new_ev->event; - -unlock: - mutex_unlock(&fh->lock); - wake_up_interruptible(&fh->wait); -} - -/* Queue a new event for all open filehandles. */ -static void cec_queue_event(struct cec_adapter *adap, - const struct cec_event *ev) -{ - u64 ts = ktime_get_ns(); - struct cec_fh *fh; - - mutex_lock(&adap->devnode.lock); - list_for_each_entry(fh, &adap->devnode.fhs, list) - cec_queue_event_fh(fh, ev, ts); - mutex_unlock(&adap->devnode.lock); -} - -/* - * Queue a new message for this filehandle. If there is no more room - * in the queue, then send the LOST_MSGS event instead. - */ -static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) -{ - static const struct cec_event ev_lost_msg = { - .ts = 0, - .event = CEC_EVENT_LOST_MSGS, - .flags = 0, - { - .lost_msgs.lost_msgs = 1, - }, - }; - struct cec_msg_entry *entry; - - mutex_lock(&fh->lock); - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto lost_msgs; - - entry->msg = *msg; - /* Add new msg at the end of the queue */ - list_add_tail(&entry->list, &fh->msgs); - - /* - * if the queue now has more than CEC_MAX_MSG_RX_QUEUE_SZ - * messages, drop the oldest one and send a lost message event. - */ - if (fh->queued_msgs == CEC_MAX_MSG_RX_QUEUE_SZ) { - list_del(&entry->list); - goto lost_msgs; - } - fh->queued_msgs++; - mutex_unlock(&fh->lock); - wake_up_interruptible(&fh->wait); - return; - -lost_msgs: - mutex_unlock(&fh->lock); - cec_queue_event_fh(fh, &ev_lost_msg, 0); -} - -/* - * Queue the message for those filehandles that are in monitor mode. - * If valid_la is true (this message is for us or was sent by us), - * then pass it on to any monitoring filehandle. If this message - * isn't for us or from us, then only give it to filehandles that - * are in MONITOR_ALL mode. - * - * This can only happen if the CEC_CAP_MONITOR_ALL capability is - * set and the CEC adapter was placed in 'monitor all' mode. - */ -static void cec_queue_msg_monitor(struct cec_adapter *adap, - const struct cec_msg *msg, - bool valid_la) -{ - struct cec_fh *fh; - u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : - CEC_MODE_MONITOR_ALL; - - mutex_lock(&adap->devnode.lock); - list_for_each_entry(fh, &adap->devnode.fhs, list) { - if (fh->mode_follower >= monitor_mode) - cec_queue_msg_fh(fh, msg); - } - mutex_unlock(&adap->devnode.lock); -} - -/* - * Queue the message for follower filehandles. - */ -static void cec_queue_msg_followers(struct cec_adapter *adap, - const struct cec_msg *msg) -{ - struct cec_fh *fh; - - mutex_lock(&adap->devnode.lock); - list_for_each_entry(fh, &adap->devnode.fhs, list) { - if (fh->mode_follower == CEC_MODE_FOLLOWER) - cec_queue_msg_fh(fh, msg); - } - mutex_unlock(&adap->devnode.lock); -} - -/* Notify userspace of an adapter state change. */ -static void cec_post_state_event(struct cec_adapter *adap) -{ - struct cec_event ev = { - .event = CEC_EVENT_STATE_CHANGE, - }; - - ev.state_change.phys_addr = adap->phys_addr; - ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; - cec_queue_event(adap, &ev); -} - -/* - * A CEC transmit (and a possible wait for reply) completed. - * If this was in blocking mode, then complete it, otherwise - * queue the message for userspace to dequeue later. - * - * This function is called with adap->lock held. - */ -static void cec_data_completed(struct cec_data *data) -{ - /* - * Delete this transmit from the filehandle's xfer_list since - * we're done with it. - * - * Note that if the filehandle is closed before this transmit - * finished, then the release() function will set data->fh to NULL. - * Without that we would be referring to a closed filehandle. - */ - if (data->fh) - list_del(&data->xfer_list); - - if (data->blocking) { - /* - * Someone is blocking so mark the message as completed - * and call complete. - */ - data->completed = true; - complete(&data->c); - } else { - /* - * No blocking, so just queue the message if needed and - * free the memory. - */ - if (data->fh) - cec_queue_msg_fh(data->fh, &data->msg); - kfree(data); - } -} - -/* - * A pending CEC transmit needs to be cancelled, either because the CEC - * adapter is disabled or the transmit takes an impossibly long time to - * finish. - * - * This function is called with adap->lock held. - */ -static void cec_data_cancel(struct cec_data *data) -{ - /* - * It's either the current transmit, or it is a pending - * transmit. Take the appropriate action to clear it. - */ - if (data->adap->transmitting == data) { - data->adap->transmitting = NULL; - } else { - list_del_init(&data->list); - if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) - data->adap->transmit_queue_sz--; - } - - /* Mark it as an error */ - data->msg.tx_ts = ktime_get_ns(); - data->msg.tx_status = CEC_TX_STATUS_ERROR | - CEC_TX_STATUS_MAX_RETRIES; - data->attempts = 0; - data->msg.tx_error_cnt = 1; - /* Queue transmitted message for monitoring purposes */ - cec_queue_msg_monitor(data->adap, &data->msg, 1); - - cec_data_completed(data); -} - -/* - * Main CEC state machine - * - * Wait until the thread should be stopped, or we are not transmitting and - * a new transmit message is queued up, in which case we start transmitting - * that message. When the adapter finished transmitting the message it will - * call cec_transmit_done(). - * - * If the adapter is disabled, then remove all queued messages instead. - * - * If the current transmit times out, then cancel that transmit. - */ -int cec_thread_func(void *_adap) -{ - struct cec_adapter *adap = _adap; - - for (;;) { - unsigned int signal_free_time; - struct cec_data *data; - bool timeout = false; - u8 attempts; - - if (adap->transmitting) { - int err; - - /* - * We are transmitting a message, so add a timeout - * to prevent the state machine to get stuck waiting - * for this message to finalize and add a check to - * see if the adapter is disabled in which case the - * transmit should be canceled. - */ - err = wait_event_interruptible_timeout(adap->kthread_waitq, - kthread_should_stop() || - (!adap->is_configured && !adap->is_configuring) || - (!adap->transmitting && - !list_empty(&adap->transmit_queue)), - msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); - timeout = err == 0; - } else { - /* Otherwise we just wait for something to happen. */ - wait_event_interruptible(adap->kthread_waitq, - kthread_should_stop() || - (!adap->transmitting && - !list_empty(&adap->transmit_queue))); - } - - mutex_lock(&adap->lock); - - if ((!adap->is_configured && !adap->is_configuring) || - kthread_should_stop()) { - /* - * If the adapter is disabled, or we're asked to stop, - * then cancel any pending transmits. - */ - while (!list_empty(&adap->transmit_queue)) { - data = list_first_entry(&adap->transmit_queue, - struct cec_data, list); - cec_data_cancel(data); - } - if (adap->transmitting) - cec_data_cancel(adap->transmitting); - - /* - * Cancel the pending timeout work. We have to unlock - * the mutex when flushing the work since - * cec_wait_timeout() will take it. This is OK since - * no new entries can be added to wait_queue as long - * as adap->transmitting is NULL, which it is due to - * the cec_data_cancel() above. - */ - while (!list_empty(&adap->wait_queue)) { - data = list_first_entry(&adap->wait_queue, - struct cec_data, list); - - if (!cancel_delayed_work(&data->work)) { - mutex_unlock(&adap->lock); - flush_scheduled_work(); - mutex_lock(&adap->lock); - } - cec_data_cancel(data); - } - goto unlock; - } - - if (adap->transmitting && timeout) { - /* - * If we timeout, then log that. This really shouldn't - * happen and is an indication of a faulty CEC adapter - * driver, or the CEC bus is in some weird state. - */ - dprintk(0, "message %*ph timed out!\n", - adap->transmitting->msg.len, - adap->transmitting->msg.msg); - /* Just give up on this. */ - cec_data_cancel(adap->transmitting); - goto unlock; - } - - /* - * If we are still transmitting, or there is nothing new to - * transmit, then just continue waiting. - */ - if (adap->transmitting || list_empty(&adap->transmit_queue)) - goto unlock; - - /* Get a new message to transmit */ - data = list_first_entry(&adap->transmit_queue, - struct cec_data, list); - list_del_init(&data->list); - adap->transmit_queue_sz--; - /* Make this the current transmitting message */ - adap->transmitting = data; - - /* - * Suggested number of attempts as per the CEC 2.0 spec: - * 4 attempts is the default, except for 'secondary poll - * messages', i.e. poll messages not sent during the adapter - * configuration phase when it allocates logical addresses. - */ - if (data->msg.len == 1 && adap->is_configured) - attempts = 2; - else - attempts = 4; - - /* Set the suggested signal free time */ - if (data->attempts) { - /* should be >= 3 data bit periods for a retry */ - signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY; - } else if (data->new_initiator) { - /* should be >= 5 data bit periods for new initiator */ - signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; - } else { - /* - * should be >= 7 data bit periods for sending another - * frame immediately after another. - */ - signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER; - } - if (data->attempts == 0) - data->attempts = attempts; - - /* Tell the adapter to transmit, cancel on error */ - if (adap->ops->adap_transmit(adap, data->attempts, - signal_free_time, &data->msg)) - cec_data_cancel(data); - -unlock: - mutex_unlock(&adap->lock); - - if (kthread_should_stop()) - break; - } - return 0; -} - -/* - * Called by the CEC adapter if a transmit finished. - */ -void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, - u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt) -{ - struct cec_data *data; - struct cec_msg *msg; - u64 ts = ktime_get_ns(); - - dprintk(2, "cec_transmit_done %02x\n", status); - mutex_lock(&adap->lock); - data = adap->transmitting; - if (!data) { - /* - * This can happen if a transmit was issued and the cable is - * unplugged while the transmit is ongoing. Ignore this - * transmit in that case. - */ - dprintk(1, "cec_transmit_done without an ongoing transmit!\n"); - goto unlock; - } - - msg = &data->msg; - - /* Drivers must fill in the status! */ - WARN_ON(status == 0); - msg->tx_ts = ts; - msg->tx_status |= status; - msg->tx_arb_lost_cnt += arb_lost_cnt; - msg->tx_nack_cnt += nack_cnt; - msg->tx_low_drive_cnt += low_drive_cnt; - msg->tx_error_cnt += error_cnt; - - /* Mark that we're done with this transmit */ - adap->transmitting = NULL; - - /* - * If there are still retry attempts left and there was an error and - * the hardware didn't signal that it retried itself (by setting - * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. - */ - if (data->attempts > 1 && - !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { - /* Retry this message */ - data->attempts--; - /* Add the message in front of the transmit queue */ - list_add(&data->list, &adap->transmit_queue); - adap->transmit_queue_sz++; - goto wake_thread; - } - - data->attempts = 0; - - /* Always set CEC_TX_STATUS_MAX_RETRIES on error */ - if (!(status & CEC_TX_STATUS_OK)) - msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES; - - /* Queue transmitted message for monitoring purposes */ - cec_queue_msg_monitor(adap, msg, 1); - - if ((status & CEC_TX_STATUS_OK) && adap->is_configured && - msg->timeout) { - /* - * Queue the message into the wait queue if we want to wait - * for a reply. - */ - list_add_tail(&data->list, &adap->wait_queue); - schedule_delayed_work(&data->work, - msecs_to_jiffies(msg->timeout)); - } else { - /* Otherwise we're done */ - cec_data_completed(data); - } - -wake_thread: - /* - * Wake up the main thread to see if another message is ready - * for transmitting or to retry the current message. - */ - wake_up_interruptible(&adap->kthread_waitq); -unlock: - mutex_unlock(&adap->lock); -} -EXPORT_SYMBOL_GPL(cec_transmit_done); - -/* - * Called when waiting for a reply times out. - */ -static void cec_wait_timeout(struct work_struct *work) -{ - struct cec_data *data = container_of(work, struct cec_data, work.work); - struct cec_adapter *adap = data->adap; - - mutex_lock(&adap->lock); - /* - * Sanity check in case the timeout and the arrival of the message - * happened at the same time. - */ - if (list_empty(&data->list)) - goto unlock; - - /* Mark the message as timed out */ - list_del_init(&data->list); - data->msg.rx_ts = ktime_get_ns(); - data->msg.rx_status = CEC_RX_STATUS_TIMEOUT; - cec_data_completed(data); -unlock: - mutex_unlock(&adap->lock); -} - -/* - * Transmit a message. The fh argument may be NULL if the transmit is not - * associated with a specific filehandle. - * - * This function is called with adap->lock held. - */ -int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, - struct cec_fh *fh, bool block) -{ - struct cec_data *data; - u8 last_initiator = 0xff; - unsigned int timeout; - int res = 0; - - msg->rx_ts = 0; - msg->tx_ts = 0; - msg->rx_status = 0; - msg->tx_status = 0; - msg->tx_arb_lost_cnt = 0; - msg->tx_nack_cnt = 0; - msg->tx_low_drive_cnt = 0; - msg->tx_error_cnt = 0; - msg->sequence = ++adap->sequence; - if (!msg->sequence) - msg->sequence = ++adap->sequence; - - if (msg->reply && msg->timeout == 0) { - /* Make sure the timeout isn't 0. */ - msg->timeout = 1000; - } - - /* Sanity checks */ - if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { - dprintk(1, "cec_transmit_msg: invalid length %d\n", msg->len); - return -EINVAL; - } - if (msg->timeout && msg->len == 1) { - dprintk(1, "cec_transmit_msg: can't reply for poll msg\n"); - return -EINVAL; - } - memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); - if (msg->len == 1) { - if (cec_msg_initiator(msg) != 0xf || - cec_msg_destination(msg) == 0xf) { - dprintk(1, "cec_transmit_msg: invalid poll message\n"); - return -EINVAL; - } - if (cec_has_log_addr(adap, cec_msg_destination(msg))) { - /* - * If the destination is a logical address our adapter - * has already claimed, then just NACK this. - * It depends on the hardware what it will do with a - * POLL to itself (some OK this), so it is just as - * easy to handle it here so the behavior will be - * consistent. - */ - msg->tx_ts = ktime_get_ns(); - msg->tx_status = CEC_TX_STATUS_NACK | - CEC_TX_STATUS_MAX_RETRIES; - msg->tx_nack_cnt = 1; - return 0; - } - } - if (msg->len > 1 && !cec_msg_is_broadcast(msg) && - cec_has_log_addr(adap, cec_msg_destination(msg))) { - dprintk(1, "cec_transmit_msg: destination is the adapter itself\n"); - return -EINVAL; - } - if (cec_msg_initiator(msg) != 0xf && - !cec_has_log_addr(adap, cec_msg_initiator(msg))) { - dprintk(1, "cec_transmit_msg: initiator has unknown logical address %d\n", - cec_msg_initiator(msg)); - return -EINVAL; - } - if (!adap->is_configured && !adap->is_configuring) - return -ENONET; - - if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) - return -EBUSY; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { - msg->msg[2] = adap->phys_addr >> 8; - msg->msg[3] = adap->phys_addr & 0xff; - } - - if (msg->timeout) - dprintk(2, "cec_transmit_msg: %*ph (wait for 0x%02x%s)\n", - msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); - else - dprintk(2, "cec_transmit_msg: %*ph%s\n", - msg->len, msg->msg, !block ? " (nb)" : ""); - - data->msg = *msg; - data->fh = fh; - data->adap = adap; - data->blocking = block; - - /* - * Determine if this message follows a message from the same - * initiator. Needed to determine the free signal time later on. - */ - if (msg->len > 1) { - if (!(list_empty(&adap->transmit_queue))) { - const struct cec_data *last; - - last = list_last_entry(&adap->transmit_queue, - const struct cec_data, list); - last_initiator = cec_msg_initiator(&last->msg); - } else if (adap->transmitting) { - last_initiator = - cec_msg_initiator(&adap->transmitting->msg); - } - } - data->new_initiator = last_initiator != cec_msg_initiator(msg); - init_completion(&data->c); - INIT_DELAYED_WORK(&data->work, cec_wait_timeout); - - if (fh) - list_add_tail(&data->xfer_list, &fh->xfer_list); - list_add_tail(&data->list, &adap->transmit_queue); - adap->transmit_queue_sz++; - if (!adap->transmitting) - wake_up_interruptible(&adap->kthread_waitq); - - /* All done if we don't need to block waiting for completion */ - if (!block) - return 0; - - /* - * If we don't get a completion before this time something is really - * wrong and we time out. - */ - timeout = CEC_XFER_TIMEOUT_MS; - /* Add the requested timeout if we have to wait for a reply as well */ - if (msg->timeout) - timeout += msg->timeout; - - /* - * Release the lock and wait, retake the lock afterwards. - */ - mutex_unlock(&adap->lock); - res = wait_for_completion_killable_timeout(&data->c, - msecs_to_jiffies(timeout)); - mutex_lock(&adap->lock); - - if (data->completed) { - /* The transmit completed (possibly with an error) */ - *msg = data->msg; - kfree(data); - return 0; - } - /* - * The wait for completion timed out or was interrupted, so mark this - * as non-blocking and disconnect from the filehandle since it is - * still 'in flight'. When it finally completes it will just drop the - * result silently. - */ - data->blocking = false; - if (data->fh) - list_del(&data->xfer_list); - data->fh = NULL; - - if (res == 0) { /* timed out */ - /* Check if the reply or the transmit failed */ - if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK)) - msg->rx_status = CEC_RX_STATUS_TIMEOUT; - else - msg->tx_status = CEC_TX_STATUS_MAX_RETRIES; - } - return res > 0 ? 0 : res; -} - -/* Helper function to be used by drivers and this framework. */ -int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, - bool block) -{ - int ret; - - mutex_lock(&adap->lock); - ret = cec_transmit_msg_fh(adap, msg, NULL, block); - mutex_unlock(&adap->lock); - return ret; -} -EXPORT_SYMBOL_GPL(cec_transmit_msg); - -/* - * I don't like forward references but without this the low-level - * cec_received_msg() function would come after a bunch of high-level - * CEC protocol handling functions. That was very confusing. - */ -static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, - bool is_reply); - -#define DIRECTED 0x80 -#define BCAST1_4 0x40 -#define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */ -#define BCAST (BCAST1_4 | BCAST2_0) -#define BOTH (BCAST | DIRECTED) - -/* - * Specify minimum length and whether the message is directed, broadcast - * or both. Messages that do not match the criteria are ignored as per - * the CEC specification. - */ -static const u8 cec_msg_size[256] = { - [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST, - [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED, - [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED, - [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED, - [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST, - [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST, - [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST, - [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST, - [CEC_MSG_STANDBY] = 2 | BOTH, - [CEC_MSG_RECORD_OFF] = 2 | DIRECTED, - [CEC_MSG_RECORD_ON] = 3 | DIRECTED, - [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED, - [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED, - [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED, - [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED, - [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED, - [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED, - [CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED, - [CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED, - [CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED, - [CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED, - [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED, - [CEC_MSG_CEC_VERSION] = 3 | DIRECTED, - [CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED, - [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED, - [CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED, - [CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST, - [CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST, - [CEC_MSG_REPORT_FEATURES] = 6 | BCAST, - [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED, - [CEC_MSG_DECK_CONTROL] = 3 | DIRECTED, - [CEC_MSG_DECK_STATUS] = 3 | DIRECTED, - [CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED, - [CEC_MSG_PLAY] = 3 | DIRECTED, - [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED, - [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED, - [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED, - [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED, - [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED, - [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED, - [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST, - [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED, - [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED, - [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH, - [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH, - [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH, - [CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED, - [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED, - [CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED, - [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED, - [CEC_MSG_MENU_STATUS] = 3 | DIRECTED, - [CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED, - [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED, - [CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED, - [CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0, - [CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED, - [CEC_MSG_ABORT] = 2 | DIRECTED, - [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED, - [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED, - [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED, - [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, - [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, - [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, - [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, - [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, - [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED, - [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED, - [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED, - [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED, - [CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED, - [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, - [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, - [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, - [CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST, - [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, -}; - -/* Called by the CEC adapter if a message is received */ -void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) -{ - struct cec_data *data; - u8 msg_init = cec_msg_initiator(msg); - u8 msg_dest = cec_msg_destination(msg); - u8 cmd = msg->msg[1]; - bool is_reply = false; - bool valid_la = true; - u8 min_len = 0; - - if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) - return; - - msg->rx_ts = ktime_get_ns(); - msg->rx_status = CEC_RX_STATUS_OK; - msg->sequence = msg->reply = msg->timeout = 0; - msg->tx_status = 0; - msg->tx_ts = 0; - msg->flags = 0; - memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); - - mutex_lock(&adap->lock); - dprintk(2, "cec_received_msg: %*ph\n", msg->len, msg->msg); - - /* Check if this message was for us (directed or broadcast). */ - if (!cec_msg_is_broadcast(msg)) - valid_la = cec_has_log_addr(adap, msg_dest); - - /* - * Check if the length is not too short or if the message is a - * broadcast message where a directed message was expected or - * vice versa. If so, then the message has to be ignored (according - * to section CEC 7.3 and CEC 12.2). - */ - if (valid_la && msg->len > 1 && cec_msg_size[cmd]) { - u8 dir_fl = cec_msg_size[cmd] & BOTH; - - min_len = cec_msg_size[cmd] & 0x1f; - if (msg->len < min_len) - valid_la = false; - else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) - valid_la = false; - else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) - valid_la = false; - else if (cec_msg_is_broadcast(msg) && - adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && - !(dir_fl & BCAST2_0)) - valid_la = false; - } - if (valid_la && min_len) { - /* These messages have special length requirements */ - switch (cmd) { - case CEC_MSG_TIMER_STATUS: - if (msg->msg[2] & 0x10) { - switch (msg->msg[2] & 0xf) { - case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: - case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: - if (msg->len < 5) - valid_la = false; - break; - } - } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { - if (msg->len < 5) - valid_la = false; - } - break; - case CEC_MSG_RECORD_ON: - switch (msg->msg[2]) { - case CEC_OP_RECORD_SRC_OWN: - break; - case CEC_OP_RECORD_SRC_DIGITAL: - if (msg->len < 10) - valid_la = false; - break; - case CEC_OP_RECORD_SRC_ANALOG: - if (msg->len < 7) - valid_la = false; - break; - case CEC_OP_RECORD_SRC_EXT_PLUG: - if (msg->len < 4) - valid_la = false; - break; - case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: - if (msg->len < 5) - valid_la = false; - break; - } - break; - } - } - - /* It's a valid message and not a poll or CDC message */ - if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) { - bool abort = cmd == CEC_MSG_FEATURE_ABORT; - - /* The aborted command is in msg[2] */ - if (abort) - cmd = msg->msg[2]; - - /* - * Walk over all transmitted messages that are waiting for a - * reply. - */ - list_for_each_entry(data, &adap->wait_queue, list) { - struct cec_msg *dst = &data->msg; - - /* - * The *only* CEC message that has two possible replies - * is CEC_MSG_INITIATE_ARC. - * In this case allow either of the two replies. - */ - if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && - (cmd == CEC_MSG_REPORT_ARC_INITIATED || - cmd == CEC_MSG_REPORT_ARC_TERMINATED) && - (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || - dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) - dst->reply = cmd; - - /* Does the command match? */ - if ((abort && cmd != dst->msg[1]) || - (!abort && cmd != dst->reply)) - continue; - - /* Does the addressing match? */ - if (msg_init != cec_msg_destination(dst) && - !cec_msg_is_broadcast(dst)) - continue; - - /* We got a reply */ - memcpy(dst->msg, msg->msg, msg->len); - dst->len = msg->len; - dst->rx_ts = msg->rx_ts; - dst->rx_status = msg->rx_status; - if (abort) - dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; - msg->flags = dst->flags; - /* Remove it from the wait_queue */ - list_del_init(&data->list); - - /* Cancel the pending timeout work */ - if (!cancel_delayed_work(&data->work)) { - mutex_unlock(&adap->lock); - flush_scheduled_work(); - mutex_lock(&adap->lock); - } - /* - * Mark this as a reply, provided someone is still - * waiting for the answer. - */ - if (data->fh) - is_reply = true; - cec_data_completed(data); - break; - } - } - mutex_unlock(&adap->lock); - - /* Pass the message on to any monitoring filehandles */ - cec_queue_msg_monitor(adap, msg, valid_la); - - /* We're done if it is not for us or a poll message */ - if (!valid_la || msg->len <= 1) - return; - - if (adap->log_addrs.log_addr_mask == 0) - return; - - /* - * Process the message on the protocol level. If is_reply is true, - * then cec_receive_notify() won't pass on the reply to the listener(s) - * since that was already done by cec_data_completed() above. - */ - cec_receive_notify(adap, msg, is_reply); -} -EXPORT_SYMBOL_GPL(cec_received_msg); - -/* Logical Address Handling */ - -/* - * Attempt to claim a specific logical address. - * - * This function is called with adap->lock held. - */ -static int cec_config_log_addr(struct cec_adapter *adap, - unsigned int idx, - unsigned int log_addr) -{ - struct cec_log_addrs *las = &adap->log_addrs; - struct cec_msg msg = { }; - int err; - - if (cec_has_log_addr(adap, log_addr)) - return 0; - - /* Send poll message */ - msg.len = 1; - msg.msg[0] = 0xf0 | log_addr; - err = cec_transmit_msg_fh(adap, &msg, NULL, true); - - /* - * While trying to poll the physical address was reset - * and the adapter was unconfigured, so bail out. - */ - if (!adap->is_configuring) - return -EINTR; - - if (err) - return err; - - if (msg.tx_status & CEC_TX_STATUS_OK) - return 0; - - /* - * Message not acknowledged, so this logical - * address is free to use. - */ - err = adap->ops->adap_log_addr(adap, log_addr); - if (err) - return err; - - las->log_addr[idx] = log_addr; - las->log_addr_mask |= 1 << log_addr; - adap->phys_addrs[log_addr] = adap->phys_addr; - - dprintk(2, "claimed addr %d (%d)\n", log_addr, - las->primary_device_type[idx]); - return 1; -} - -/* - * Unconfigure the adapter: clear all logical addresses and send - * the state changed event. - * - * This function is called with adap->lock held. - */ -static void cec_adap_unconfigure(struct cec_adapter *adap) -{ - WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); - adap->log_addrs.log_addr_mask = 0; - adap->is_configuring = false; - adap->is_configured = false; - memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); - wake_up_interruptible(&adap->kthread_waitq); - cec_post_state_event(adap); -} - -/* - * Attempt to claim the required logical addresses. - */ -static int cec_config_thread_func(void *arg) -{ - /* The various LAs for each type of device */ - static const u8 tv_log_addrs[] = { - CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC, - CEC_LOG_ADDR_INVALID - }; - static const u8 record_log_addrs[] = { - CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2, - CEC_LOG_ADDR_RECORD_3, - CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, - CEC_LOG_ADDR_INVALID - }; - static const u8 tuner_log_addrs[] = { - CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2, - CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4, - CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, - CEC_LOG_ADDR_INVALID - }; - static const u8 playback_log_addrs[] = { - CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2, - CEC_LOG_ADDR_PLAYBACK_3, - CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, - CEC_LOG_ADDR_INVALID - }; - static const u8 audiosystem_log_addrs[] = { - CEC_LOG_ADDR_AUDIOSYSTEM, - CEC_LOG_ADDR_INVALID - }; - static const u8 specific_use_log_addrs[] = { - CEC_LOG_ADDR_SPECIFIC, - CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, - CEC_LOG_ADDR_INVALID - }; - static const u8 *type2addrs[6] = { - [CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs, - [CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs, - [CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs, - [CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs, - [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs, - [CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs, - }; - static const u16 type2mask[] = { - [CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV, - [CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD, - [CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER, - [CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK, - [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM, - [CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC, - }; - struct cec_adapter *adap = arg; - struct cec_log_addrs *las = &adap->log_addrs; - int err; - int i, j; - - mutex_lock(&adap->lock); - dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n", - cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs); - las->log_addr_mask = 0; - - if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED) - goto configured; - - for (i = 0; i < las->num_log_addrs; i++) { - unsigned int type = las->log_addr_type[i]; - const u8 *la_list; - u8 last_la; - - /* - * The TV functionality can only map to physical address 0. - * For any other address, try the Specific functionality - * instead as per the spec. - */ - if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV) - type = CEC_LOG_ADDR_TYPE_SPECIFIC; - - la_list = type2addrs[type]; - last_la = las->log_addr[i]; - las->log_addr[i] = CEC_LOG_ADDR_INVALID; - if (last_la == CEC_LOG_ADDR_INVALID || - last_la == CEC_LOG_ADDR_UNREGISTERED || - !(last_la & type2mask[type])) - last_la = la_list[0]; - - err = cec_config_log_addr(adap, i, last_la); - if (err > 0) /* Reused last LA */ - continue; - - if (err < 0) - goto unconfigure; - - for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) { - /* Tried this one already, skip it */ - if (la_list[j] == last_la) - continue; - /* The backup addresses are CEC 2.0 specific */ - if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 || - la_list[j] == CEC_LOG_ADDR_BACKUP_2) && - las->cec_version < CEC_OP_CEC_VERSION_2_0) - continue; - - err = cec_config_log_addr(adap, i, la_list[j]); - if (err == 0) /* LA is in use */ - continue; - if (err < 0) - goto unconfigure; - /* Done, claimed an LA */ - break; - } - - if (la_list[j] == CEC_LOG_ADDR_INVALID) - dprintk(1, "could not claim LA %d\n", i); - } - - if (adap->log_addrs.log_addr_mask == 0 && - !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) - goto unconfigure; - -configured: - if (adap->log_addrs.log_addr_mask == 0) { - /* Fall back to unregistered */ - las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; - las->log_addr_mask = 1 << las->log_addr[0]; - for (i = 1; i < las->num_log_addrs; i++) - las->log_addr[i] = CEC_LOG_ADDR_INVALID; - } - adap->is_configured = true; - adap->is_configuring = false; - cec_post_state_event(adap); - mutex_unlock(&adap->lock); - - for (i = 0; i < las->num_log_addrs; i++) { - if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || - (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) - continue; - - /* - * Report Features must come first according - * to CEC 2.0 - */ - if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED) - cec_report_features(adap, i); - cec_report_phys_addr(adap, i); - } - for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) - las->log_addr[i] = CEC_LOG_ADDR_INVALID; - mutex_lock(&adap->lock); - adap->kthread_config = NULL; - mutex_unlock(&adap->lock); - complete(&adap->config_completion); - return 0; - -unconfigure: - for (i = 0; i < las->num_log_addrs; i++) - las->log_addr[i] = CEC_LOG_ADDR_INVALID; - cec_adap_unconfigure(adap); - adap->kthread_config = NULL; - mutex_unlock(&adap->lock); - complete(&adap->config_completion); - return 0; -} - -/* - * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the - * logical addresses. - * - * This function is called with adap->lock held. - */ -static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) -{ - if (WARN_ON(adap->is_configuring || adap->is_configured)) - return; - - init_completion(&adap->config_completion); - - /* Ready to kick off the thread */ - adap->is_configuring = true; - adap->kthread_config = kthread_run(cec_config_thread_func, adap, - "ceccfg-%s", adap->name); - if (IS_ERR(adap->kthread_config)) { - adap->kthread_config = NULL; - } else if (block) { - mutex_unlock(&adap->lock); - wait_for_completion(&adap->config_completion); - mutex_lock(&adap->lock); - } -} - -/* Set a new physical address and send an event notifying userspace of this. - * - * This function is called with adap->lock held. - */ -void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) -{ - if (phys_addr == adap->phys_addr || adap->devnode.unregistered) - return; - - if (phys_addr == CEC_PHYS_ADDR_INVALID || - adap->phys_addr != CEC_PHYS_ADDR_INVALID) { - adap->phys_addr = CEC_PHYS_ADDR_INVALID; - cec_post_state_event(adap); - cec_adap_unconfigure(adap); - /* Disabling monitor all mode should always succeed */ - if (adap->monitor_all_cnt) - WARN_ON(call_op(adap, adap_monitor_all_enable, false)); - WARN_ON(adap->ops->adap_enable(adap, false)); - if (phys_addr == CEC_PHYS_ADDR_INVALID) - return; - } - - if (adap->ops->adap_enable(adap, true)) - return; - - if (adap->monitor_all_cnt && - call_op(adap, adap_monitor_all_enable, true)) { - WARN_ON(adap->ops->adap_enable(adap, false)); - return; - } - adap->phys_addr = phys_addr; - cec_post_state_event(adap); - if (adap->log_addrs.num_log_addrs) - cec_claim_log_addrs(adap, block); -} - -void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) -{ - if (IS_ERR_OR_NULL(adap)) - return; - - mutex_lock(&adap->lock); - __cec_s_phys_addr(adap, phys_addr, block); - mutex_unlock(&adap->lock); -} -EXPORT_SYMBOL_GPL(cec_s_phys_addr); - -/* - * Called from either the ioctl or a driver to set the logical addresses. - * - * This function is called with adap->lock held. - */ -int __cec_s_log_addrs(struct cec_adapter *adap, - struct cec_log_addrs *log_addrs, bool block) -{ - u16 type_mask = 0; - int i; - - if (adap->devnode.unregistered) - return -ENODEV; - - if (!log_addrs || log_addrs->num_log_addrs == 0) { - adap->log_addrs.num_log_addrs = 0; - cec_adap_unconfigure(adap); - return 0; - } - - if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) { - /* - * Sanitize log_addrs fields if a CDC-Only device is - * requested. - */ - log_addrs->num_log_addrs = 1; - log_addrs->osd_name[0] = '\0'; - log_addrs->vendor_id = CEC_VENDOR_ID_NONE; - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; - /* - * This is just an internal convention since a CDC-Only device - * doesn't have to be a switch. But switches already use - * unregistered, so it makes some kind of sense to pick this - * as the primary device. Since a CDC-Only device never sends - * any 'normal' CEC messages this primary device type is never - * sent over the CEC bus. - */ - log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; - log_addrs->all_device_types[0] = 0; - log_addrs->features[0][0] = 0; - log_addrs->features[0][1] = 0; - } - - /* Ensure the osd name is 0-terminated */ - log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0'; - - /* Sanity checks */ - if (log_addrs->num_log_addrs > adap->available_log_addrs) { - dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs); - return -EINVAL; - } - - /* - * Vendor ID is a 24 bit number, so check if the value is - * within the correct range. - */ - if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE && - (log_addrs->vendor_id & 0xff000000) != 0) - return -EINVAL; - - if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 && - log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) - return -EINVAL; - - if (log_addrs->num_log_addrs > 1) - for (i = 0; i < log_addrs->num_log_addrs; i++) - if (log_addrs->log_addr_type[i] == - CEC_LOG_ADDR_TYPE_UNREGISTERED) { - dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n"); - return -EINVAL; - } - - for (i = 0; i < log_addrs->num_log_addrs; i++) { - const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]); - u8 *features = log_addrs->features[i]; - bool op_is_dev_features = false; - - log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; - if (type_mask & (1 << log_addrs->log_addr_type[i])) { - dprintk(1, "duplicate logical address type\n"); - return -EINVAL; - } - type_mask |= 1 << log_addrs->log_addr_type[i]; - if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) && - (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) { - /* Record already contains the playback functionality */ - dprintk(1, "invalid record + playback combination\n"); - return -EINVAL; - } - if (log_addrs->primary_device_type[i] > - CEC_OP_PRIM_DEVTYPE_PROCESSOR) { - dprintk(1, "unknown primary device type\n"); - return -EINVAL; - } - if (log_addrs->primary_device_type[i] == 2) { - dprintk(1, "invalid primary device type\n"); - return -EINVAL; - } - if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { - dprintk(1, "unknown logical address type\n"); - return -EINVAL; - } - for (i = 0; i < feature_sz; i++) { - if ((features[i] & 0x80) == 0) { - if (op_is_dev_features) - break; - op_is_dev_features = true; - } - } - if (!op_is_dev_features || i == feature_sz) { - dprintk(1, "malformed features\n"); - return -EINVAL; - } - /* Zero unused part of the feature array */ - memset(features + i + 1, 0, feature_sz - i - 1); - } - - if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) { - if (log_addrs->num_log_addrs > 2) { - dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n"); - return -EINVAL; - } - if (log_addrs->num_log_addrs == 2) { - if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) | - (1 << CEC_LOG_ADDR_TYPE_TV)))) { - dprintk(1, "Two LAs is only allowed for audiosystem and TV\n"); - return -EINVAL; - } - if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) | - (1 << CEC_LOG_ADDR_TYPE_RECORD)))) { - dprintk(1, "An audiosystem/TV can only be combined with record or playback\n"); - return -EINVAL; - } - } - } - - /* Zero unused LAs */ - for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) { - log_addrs->primary_device_type[i] = 0; - log_addrs->log_addr_type[i] = 0; - log_addrs->all_device_types[i] = 0; - memset(log_addrs->features[i], 0, - sizeof(log_addrs->features[i])); - } - - log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask; - adap->log_addrs = *log_addrs; - if (adap->phys_addr != CEC_PHYS_ADDR_INVALID) - cec_claim_log_addrs(adap, block); - return 0; -} - -int cec_s_log_addrs(struct cec_adapter *adap, - struct cec_log_addrs *log_addrs, bool block) -{ - int err; - - mutex_lock(&adap->lock); - err = __cec_s_log_addrs(adap, log_addrs, block); - mutex_unlock(&adap->lock); - return err; -} -EXPORT_SYMBOL_GPL(cec_s_log_addrs); - -/* High-level core CEC message handling */ - -/* Transmit the Report Features message */ -static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx) -{ - struct cec_msg msg = { }; - const struct cec_log_addrs *las = &adap->log_addrs; - const u8 *features = las->features[la_idx]; - bool op_is_dev_features = false; - unsigned int idx; - - /* This is 2.0 and up only */ - if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) - return 0; - - /* Report Features */ - msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; - msg.len = 4; - msg.msg[1] = CEC_MSG_REPORT_FEATURES; - msg.msg[2] = adap->log_addrs.cec_version; - msg.msg[3] = las->all_device_types[la_idx]; - - /* Write RC Profiles first, then Device Features */ - for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { - msg.msg[msg.len++] = features[idx]; - if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { - if (op_is_dev_features) - break; - op_is_dev_features = true; - } - } - return cec_transmit_msg(adap, &msg, false); -} - -/* Transmit the Report Physical Address message */ -static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx) -{ - const struct cec_log_addrs *las = &adap->log_addrs; - struct cec_msg msg = { }; - - /* Report Physical Address */ - msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; - cec_msg_report_physical_addr(&msg, adap->phys_addr, - las->primary_device_type[la_idx]); - dprintk(2, "config: la %d pa %x.%x.%x.%x\n", - las->log_addr[la_idx], - cec_phys_addr_exp(adap->phys_addr)); - return cec_transmit_msg(adap, &msg, false); -} - -/* Transmit the Feature Abort message */ -static int cec_feature_abort_reason(struct cec_adapter *adap, - struct cec_msg *msg, u8 reason) -{ - struct cec_msg tx_msg = { }; - - /* - * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT - * message! - */ - if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) - return 0; - cec_msg_set_reply_to(&tx_msg, msg); - cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); - return cec_transmit_msg(adap, &tx_msg, false); -} - -static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg) -{ - return cec_feature_abort_reason(adap, msg, - CEC_OP_ABORT_UNRECOGNIZED_OP); -} - -static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg) -{ - return cec_feature_abort_reason(adap, msg, - CEC_OP_ABORT_REFUSED); -} - -/* - * Called when a CEC message is received. This function will do any - * necessary core processing. The is_reply bool is true if this message - * is a reply to an earlier transmit. - * - * The message is either a broadcast message or a valid directed message. - */ -static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, - bool is_reply) -{ - bool is_broadcast = cec_msg_is_broadcast(msg); - u8 dest_laddr = cec_msg_destination(msg); - u8 init_laddr = cec_msg_initiator(msg); - u8 devtype = cec_log_addr2dev(adap, dest_laddr); - int la_idx = cec_log_addr2idx(adap, dest_laddr); - bool from_unregistered = init_laddr == 0xf; - struct cec_msg tx_cec_msg = { }; - - dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg); - - /* If this is a CDC-Only device, then ignore any non-CDC messages */ - if (cec_is_cdc_only(&adap->log_addrs) && - msg->msg[1] != CEC_MSG_CDC_MESSAGE) - return 0; - - if (adap->ops->received) { - /* Allow drivers to process the message first */ - if (adap->ops->received(adap, msg) != -ENOMSG) - return 0; - } - - /* - * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and - * CEC_MSG_USER_CONTROL_RELEASED messages always have to be - * handled by the CEC core, even if the passthrough mode is on. - * The others are just ignored if passthrough mode is on. - */ - switch (msg->msg[1]) { - case CEC_MSG_GET_CEC_VERSION: - case CEC_MSG_GIVE_DEVICE_VENDOR_ID: - case CEC_MSG_ABORT: - case CEC_MSG_GIVE_DEVICE_POWER_STATUS: - case CEC_MSG_GIVE_PHYSICAL_ADDR: - case CEC_MSG_GIVE_OSD_NAME: - case CEC_MSG_GIVE_FEATURES: - /* - * Skip processing these messages if the passthrough mode - * is on. - */ - if (adap->passthrough) - goto skip_processing; - /* Ignore if addressing is wrong */ - if (is_broadcast || from_unregistered) - return 0; - break; - - case CEC_MSG_USER_CONTROL_PRESSED: - case CEC_MSG_USER_CONTROL_RELEASED: - /* Wrong addressing mode: don't process */ - if (is_broadcast || from_unregistered) - goto skip_processing; - break; - - case CEC_MSG_REPORT_PHYSICAL_ADDR: - /* - * This message is always processed, regardless of the - * passthrough setting. - * - * Exception: don't process if wrong addressing mode. - */ - if (!is_broadcast) - goto skip_processing; - break; - - default: - break; - } - - cec_msg_set_reply_to(&tx_cec_msg, msg); - - switch (msg->msg[1]) { - /* The following messages are processed but still passed through */ - case CEC_MSG_REPORT_PHYSICAL_ADDR: { - u16 pa = (msg->msg[2] << 8) | msg->msg[3]; - - if (!from_unregistered) - adap->phys_addrs[init_laddr] = pa; - dprintk(1, "Reported physical address %x.%x.%x.%x for logical address %d\n", - cec_phys_addr_exp(pa), init_laddr); - break; - } - - case CEC_MSG_USER_CONTROL_PRESSED: - if (!(adap->capabilities & CEC_CAP_RC) || - !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) - break; - -#if IS_REACHABLE(CONFIG_RC_CORE) - switch (msg->msg[2]) { - /* - * Play function, this message can have variable length - * depending on the specific play function that is used. - */ - case 0x60: - if (msg->len == 2) - rc_keydown(adap->rc, RC_TYPE_CEC, - msg->msg[2], 0); - else - rc_keydown(adap->rc, RC_TYPE_CEC, - msg->msg[2] << 8 | msg->msg[3], 0); - break; - /* - * Other function messages that are not handled. - * Currently the RC framework does not allow to supply an - * additional parameter to a keypress. These "keys" contain - * other information such as channel number, an input number - * etc. - * For the time being these messages are not processed by the - * framework and are simply forwarded to the user space. - */ - case 0x56: case 0x57: - case 0x67: case 0x68: case 0x69: case 0x6a: - break; - default: - rc_keydown(adap->rc, RC_TYPE_CEC, msg->msg[2], 0); - break; - } -#endif - break; - - case CEC_MSG_USER_CONTROL_RELEASED: - if (!(adap->capabilities & CEC_CAP_RC) || - !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) - break; -#if IS_REACHABLE(CONFIG_RC_CORE) - rc_keyup(adap->rc); -#endif - break; - - /* - * The remaining messages are only processed if the passthrough mode - * is off. - */ - case CEC_MSG_GET_CEC_VERSION: - cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version); - return cec_transmit_msg(adap, &tx_cec_msg, false); - - case CEC_MSG_GIVE_PHYSICAL_ADDR: - /* Do nothing for CEC switches using addr 15 */ - if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15) - return 0; - cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype); - return cec_transmit_msg(adap, &tx_cec_msg, false); - - case CEC_MSG_GIVE_DEVICE_VENDOR_ID: - if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE) - return cec_feature_abort(adap, msg); - cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id); - return cec_transmit_msg(adap, &tx_cec_msg, false); - - case CEC_MSG_ABORT: - /* Do nothing for CEC switches */ - if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH) - return 0; - return cec_feature_refused(adap, msg); - - case CEC_MSG_GIVE_OSD_NAME: { - if (adap->log_addrs.osd_name[0] == 0) - return cec_feature_abort(adap, msg); - cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name); - return cec_transmit_msg(adap, &tx_cec_msg, false); - } - - case CEC_MSG_GIVE_FEATURES: - if (adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) - return cec_report_features(adap, la_idx); - return 0; - - default: - /* - * Unprocessed messages are aborted if userspace isn't doing - * any processing either. - */ - if (!is_broadcast && !is_reply && !adap->follower_cnt && - !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) - return cec_feature_abort(adap, msg); - break; - } - -skip_processing: - /* If this was a reply, then we're done, unless otherwise specified */ - if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS)) - return 0; - - /* - * Send to the exclusive follower if there is one, otherwise send - * to all followers. - */ - if (adap->cec_follower) - cec_queue_msg_fh(adap->cec_follower, msg); - else - cec_queue_msg_followers(adap, msg); - return 0; -} - -/* - * Helper functions to keep track of the 'monitor all' use count. - * - * These functions are called with adap->lock held. - */ -int cec_monitor_all_cnt_inc(struct cec_adapter *adap) -{ - int ret = 0; - - if (adap->monitor_all_cnt == 0) - ret = call_op(adap, adap_monitor_all_enable, 1); - if (ret == 0) - adap->monitor_all_cnt++; - return ret; -} - -void cec_monitor_all_cnt_dec(struct cec_adapter *adap) -{ - adap->monitor_all_cnt--; - if (adap->monitor_all_cnt == 0) - WARN_ON(call_op(adap, adap_monitor_all_enable, 0)); -} - -#ifdef CONFIG_MEDIA_CEC_DEBUG -/* - * Log the current state of the CEC adapter. - * Very useful for debugging. - */ -int cec_adap_status(struct seq_file *file, void *priv) -{ - struct cec_adapter *adap = dev_get_drvdata(file->private); - struct cec_data *data; - - mutex_lock(&adap->lock); - seq_printf(file, "configured: %d\n", adap->is_configured); - seq_printf(file, "configuring: %d\n", adap->is_configuring); - seq_printf(file, "phys_addr: %x.%x.%x.%x\n", - cec_phys_addr_exp(adap->phys_addr)); - seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs); - seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask); - if (adap->cec_follower) - seq_printf(file, "has CEC follower%s\n", - adap->passthrough ? " (in passthrough mode)" : ""); - if (adap->cec_initiator) - seq_puts(file, "has CEC initiator\n"); - if (adap->monitor_all_cnt) - seq_printf(file, "file handles in Monitor All mode: %u\n", - adap->monitor_all_cnt); - data = adap->transmitting; - if (data) - seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", - data->msg.len, data->msg.msg, data->msg.reply, - data->msg.timeout); - seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz); - list_for_each_entry(data, &adap->transmit_queue, list) { - seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n", - data->msg.len, data->msg.msg, data->msg.reply, - data->msg.timeout); - } - list_for_each_entry(data, &adap->wait_queue, list) { - seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n", - data->msg.len, data->msg.msg, data->msg.reply, - data->msg.timeout); - } - - call_void_op(adap, adap_status, file); - mutex_unlock(&adap->lock); - return 0; -} -#endif diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c deleted file mode 100644 index d4bc4ee2c6e5..000000000000 --- a/drivers/staging/media/cec/cec-api.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * cec-api.c - HDMI Consumer Electronics Control framework - API - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cec-priv.h" - -static inline struct cec_devnode *cec_devnode_data(struct file *filp) -{ - struct cec_fh *fh = filp->private_data; - - return &fh->adap->devnode; -} - -/* CEC file operations */ - -static unsigned int cec_poll(struct file *filp, - struct poll_table_struct *poll) -{ - struct cec_devnode *devnode = cec_devnode_data(filp); - struct cec_fh *fh = filp->private_data; - struct cec_adapter *adap = fh->adap; - unsigned int res = 0; - - if (!devnode->registered) - return POLLERR | POLLHUP; - mutex_lock(&adap->lock); - if (adap->is_configured && - adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ) - res |= POLLOUT | POLLWRNORM; - if (fh->queued_msgs) - res |= POLLIN | POLLRDNORM; - if (fh->pending_events) - res |= POLLPRI; - poll_wait(filp, &fh->wait, poll); - mutex_unlock(&adap->lock); - return res; -} - -static bool cec_is_busy(const struct cec_adapter *adap, - const struct cec_fh *fh) -{ - bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh; - bool valid_follower = adap->cec_follower && adap->cec_follower == fh; - - /* - * Exclusive initiators and followers can always access the CEC adapter - */ - if (valid_initiator || valid_follower) - return false; - /* - * All others can only access the CEC adapter if there is no - * exclusive initiator and they are in INITIATOR mode. - */ - return adap->cec_initiator || - fh->mode_initiator == CEC_MODE_NO_INITIATOR; -} - -static long cec_adap_g_caps(struct cec_adapter *adap, - struct cec_caps __user *parg) -{ - struct cec_caps caps = {}; - - strlcpy(caps.driver, adap->devnode.parent->driver->name, - sizeof(caps.driver)); - strlcpy(caps.name, adap->name, sizeof(caps.name)); - caps.available_log_addrs = adap->available_log_addrs; - caps.capabilities = adap->capabilities; - caps.version = LINUX_VERSION_CODE; - if (copy_to_user(parg, &caps, sizeof(caps))) - return -EFAULT; - return 0; -} - -static long cec_adap_g_phys_addr(struct cec_adapter *adap, - __u16 __user *parg) -{ - u16 phys_addr; - - mutex_lock(&adap->lock); - phys_addr = adap->phys_addr; - mutex_unlock(&adap->lock); - if (copy_to_user(parg, &phys_addr, sizeof(phys_addr))) - return -EFAULT; - return 0; -} - -static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh, - bool block, __u16 __user *parg) -{ - u16 phys_addr; - long err; - - if (!(adap->capabilities & CEC_CAP_PHYS_ADDR)) - return -ENOTTY; - if (copy_from_user(&phys_addr, parg, sizeof(phys_addr))) - return -EFAULT; - - err = cec_phys_addr_validate(phys_addr, NULL, NULL); - if (err) - return err; - mutex_lock(&adap->lock); - if (cec_is_busy(adap, fh)) - err = -EBUSY; - else - __cec_s_phys_addr(adap, phys_addr, block); - mutex_unlock(&adap->lock); - return err; -} - -static long cec_adap_g_log_addrs(struct cec_adapter *adap, - struct cec_log_addrs __user *parg) -{ - struct cec_log_addrs log_addrs; - - mutex_lock(&adap->lock); - log_addrs = adap->log_addrs; - if (!adap->is_configured) - memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID, - sizeof(log_addrs.log_addr)); - mutex_unlock(&adap->lock); - - if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) - return -EFAULT; - return 0; -} - -static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, - bool block, struct cec_log_addrs __user *parg) -{ - struct cec_log_addrs log_addrs; - long err = -EBUSY; - - if (!(adap->capabilities & CEC_CAP_LOG_ADDRS)) - return -ENOTTY; - if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) - return -EFAULT; - log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK | - CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU | - CEC_LOG_ADDRS_FL_CDC_ONLY; - mutex_lock(&adap->lock); - if (!adap->is_configuring && - (!log_addrs.num_log_addrs || !adap->is_configured) && - !cec_is_busy(adap, fh)) { - err = __cec_s_log_addrs(adap, &log_addrs, block); - if (!err) - log_addrs = adap->log_addrs; - } - mutex_unlock(&adap->lock); - if (err) - return err; - if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) - return -EFAULT; - return 0; -} - -static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, - bool block, struct cec_msg __user *parg) -{ - struct cec_msg msg = {}; - long err = 0; - - if (!(adap->capabilities & CEC_CAP_TRANSMIT)) - return -ENOTTY; - if (copy_from_user(&msg, parg, sizeof(msg))) - return -EFAULT; - - /* A CDC-Only device can only send CDC messages */ - if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) && - (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE)) - return -EINVAL; - - msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; - mutex_lock(&adap->lock); - if (!adap->is_configured) - err = -ENONET; - else if (cec_is_busy(adap, fh)) - err = -EBUSY; - else - err = cec_transmit_msg_fh(adap, &msg, fh, block); - mutex_unlock(&adap->lock); - if (err) - return err; - if (copy_to_user(parg, &msg, sizeof(msg))) - return -EFAULT; - return 0; -} - -/* Called by CEC_RECEIVE: wait for a message to arrive */ -static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block) -{ - u32 timeout = msg->timeout; - int res; - - do { - mutex_lock(&fh->lock); - /* Are there received messages queued up? */ - if (fh->queued_msgs) { - /* Yes, return the first one */ - struct cec_msg_entry *entry = - list_first_entry(&fh->msgs, - struct cec_msg_entry, list); - - list_del(&entry->list); - *msg = entry->msg; - kfree(entry); - fh->queued_msgs--; - mutex_unlock(&fh->lock); - /* restore original timeout value */ - msg->timeout = timeout; - return 0; - } - - /* No, return EAGAIN in non-blocking mode or wait */ - mutex_unlock(&fh->lock); - - /* Return when in non-blocking mode */ - if (!block) - return -EAGAIN; - - if (msg->timeout) { - /* The user specified a timeout */ - res = wait_event_interruptible_timeout(fh->wait, - fh->queued_msgs, - msecs_to_jiffies(msg->timeout)); - if (res == 0) - res = -ETIMEDOUT; - else if (res > 0) - res = 0; - } else { - /* Wait indefinitely */ - res = wait_event_interruptible(fh->wait, - fh->queued_msgs); - } - /* Exit on error, otherwise loop to get the new message */ - } while (!res); - return res; -} - -static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh, - bool block, struct cec_msg __user *parg) -{ - struct cec_msg msg = {}; - long err = 0; - - if (copy_from_user(&msg, parg, sizeof(msg))) - return -EFAULT; - mutex_lock(&adap->lock); - if (!adap->is_configured && fh->mode_follower < CEC_MODE_MONITOR) - err = -ENONET; - mutex_unlock(&adap->lock); - if (err) - return err; - - err = cec_receive_msg(fh, &msg, block); - if (err) - return err; - if (copy_to_user(parg, &msg, sizeof(msg))) - return -EFAULT; - return 0; -} - -static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, - bool block, struct cec_event __user *parg) -{ - struct cec_event *ev = NULL; - u64 ts = ~0ULL; - unsigned int i; - long err = 0; - - mutex_lock(&fh->lock); - while (!fh->pending_events && block) { - mutex_unlock(&fh->lock); - err = wait_event_interruptible(fh->wait, fh->pending_events); - if (err) - return err; - mutex_lock(&fh->lock); - } - - /* Find the oldest event */ - for (i = 0; i < CEC_NUM_EVENTS; i++) { - if (fh->pending_events & (1 << (i + 1)) && - fh->events[i].ts <= ts) { - ev = &fh->events[i]; - ts = ev->ts; - } - } - if (!ev) { - err = -EAGAIN; - goto unlock; - } - - if (copy_to_user(parg, ev, sizeof(*ev))) { - err = -EFAULT; - goto unlock; - } - - fh->pending_events &= ~(1 << ev->event); - -unlock: - mutex_unlock(&fh->lock); - return err; -} - -static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh, - u32 __user *parg) -{ - u32 mode = fh->mode_initiator | fh->mode_follower; - - if (copy_to_user(parg, &mode, sizeof(mode))) - return -EFAULT; - return 0; -} - -static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, - u32 __user *parg) -{ - u32 mode; - u8 mode_initiator; - u8 mode_follower; - long err = 0; - - if (copy_from_user(&mode, parg, sizeof(mode))) - return -EFAULT; - if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) - return -EINVAL; - - mode_initiator = mode & CEC_MODE_INITIATOR_MSK; - mode_follower = mode & CEC_MODE_FOLLOWER_MSK; - - if (mode_initiator > CEC_MODE_EXCL_INITIATOR || - mode_follower > CEC_MODE_MONITOR_ALL) - return -EINVAL; - - if (mode_follower == CEC_MODE_MONITOR_ALL && - !(adap->capabilities & CEC_CAP_MONITOR_ALL)) - return -EINVAL; - - /* Follower modes should always be able to send CEC messages */ - if ((mode_initiator == CEC_MODE_NO_INITIATOR || - !(adap->capabilities & CEC_CAP_TRANSMIT)) && - mode_follower >= CEC_MODE_FOLLOWER && - mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) - return -EINVAL; - - /* Monitor modes require CEC_MODE_NO_INITIATOR */ - if (mode_initiator && mode_follower >= CEC_MODE_MONITOR) - return -EINVAL; - - /* Monitor modes require CAP_NET_ADMIN */ - if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN)) - return -EPERM; - - mutex_lock(&adap->lock); - /* - * You can't become exclusive follower if someone else already - * has that job. - */ - if ((mode_follower == CEC_MODE_EXCL_FOLLOWER || - mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) && - adap->cec_follower && adap->cec_follower != fh) - err = -EBUSY; - /* - * You can't become exclusive initiator if someone else already - * has that job. - */ - if (mode_initiator == CEC_MODE_EXCL_INITIATOR && - adap->cec_initiator && adap->cec_initiator != fh) - err = -EBUSY; - - if (!err) { - bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL; - bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL; - - if (old_mon_all != new_mon_all) { - if (new_mon_all) - err = cec_monitor_all_cnt_inc(adap); - else - cec_monitor_all_cnt_dec(adap); - } - } - - if (err) { - mutex_unlock(&adap->lock); - return err; - } - - if (fh->mode_follower == CEC_MODE_FOLLOWER) - adap->follower_cnt--; - if (mode_follower == CEC_MODE_FOLLOWER) - adap->follower_cnt++; - if (mode_follower == CEC_MODE_EXCL_FOLLOWER || - mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { - adap->passthrough = - mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU; - adap->cec_follower = fh; - } else if (adap->cec_follower == fh) { - adap->passthrough = false; - adap->cec_follower = NULL; - } - if (mode_initiator == CEC_MODE_EXCL_INITIATOR) - adap->cec_initiator = fh; - else if (adap->cec_initiator == fh) - adap->cec_initiator = NULL; - fh->mode_initiator = mode_initiator; - fh->mode_follower = mode_follower; - mutex_unlock(&adap->lock); - return 0; -} - -static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct cec_devnode *devnode = cec_devnode_data(filp); - struct cec_fh *fh = filp->private_data; - struct cec_adapter *adap = fh->adap; - bool block = !(filp->f_flags & O_NONBLOCK); - void __user *parg = (void __user *)arg; - - if (!devnode->registered) - return -ENODEV; - - switch (cmd) { - case CEC_ADAP_G_CAPS: - return cec_adap_g_caps(adap, parg); - - case CEC_ADAP_G_PHYS_ADDR: - return cec_adap_g_phys_addr(adap, parg); - - case CEC_ADAP_S_PHYS_ADDR: - return cec_adap_s_phys_addr(adap, fh, block, parg); - - case CEC_ADAP_G_LOG_ADDRS: - return cec_adap_g_log_addrs(adap, parg); - - case CEC_ADAP_S_LOG_ADDRS: - return cec_adap_s_log_addrs(adap, fh, block, parg); - - case CEC_TRANSMIT: - return cec_transmit(adap, fh, block, parg); - - case CEC_RECEIVE: - return cec_receive(adap, fh, block, parg); - - case CEC_DQEVENT: - return cec_dqevent(adap, fh, block, parg); - - case CEC_G_MODE: - return cec_g_mode(adap, fh, parg); - - case CEC_S_MODE: - return cec_s_mode(adap, fh, parg); - - default: - return -ENOTTY; - } -} - -static int cec_open(struct inode *inode, struct file *filp) -{ - struct cec_devnode *devnode = - container_of(inode->i_cdev, struct cec_devnode, cdev); - struct cec_adapter *adap = to_cec_adapter(devnode); - struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); - /* - * Initial events that are automatically sent when the cec device is - * opened. - */ - struct cec_event ev_state = { - .event = CEC_EVENT_STATE_CHANGE, - .flags = CEC_EVENT_FL_INITIAL_STATE, - }; - int err; - - if (!fh) - return -ENOMEM; - - INIT_LIST_HEAD(&fh->msgs); - INIT_LIST_HEAD(&fh->xfer_list); - mutex_init(&fh->lock); - init_waitqueue_head(&fh->wait); - - fh->mode_initiator = CEC_MODE_INITIATOR; - fh->adap = adap; - - err = cec_get_device(devnode); - if (err) { - kfree(fh); - return err; - } - - filp->private_data = fh; - - mutex_lock(&devnode->lock); - /* Queue up initial state events */ - ev_state.state_change.phys_addr = adap->phys_addr; - ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; - cec_queue_event_fh(fh, &ev_state, 0); - - list_add(&fh->list, &devnode->fhs); - mutex_unlock(&devnode->lock); - - return 0; -} - -/* Override for the release function */ -static int cec_release(struct inode *inode, struct file *filp) -{ - struct cec_devnode *devnode = cec_devnode_data(filp); - struct cec_adapter *adap = to_cec_adapter(devnode); - struct cec_fh *fh = filp->private_data; - - mutex_lock(&adap->lock); - if (adap->cec_initiator == fh) - adap->cec_initiator = NULL; - if (adap->cec_follower == fh) { - adap->cec_follower = NULL; - adap->passthrough = false; - } - if (fh->mode_follower == CEC_MODE_FOLLOWER) - adap->follower_cnt--; - if (fh->mode_follower == CEC_MODE_MONITOR_ALL) - cec_monitor_all_cnt_dec(adap); - mutex_unlock(&adap->lock); - - mutex_lock(&devnode->lock); - list_del(&fh->list); - mutex_unlock(&devnode->lock); - - /* Unhook pending transmits from this filehandle. */ - mutex_lock(&adap->lock); - while (!list_empty(&fh->xfer_list)) { - struct cec_data *data = - list_first_entry(&fh->xfer_list, struct cec_data, xfer_list); - - data->blocking = false; - data->fh = NULL; - list_del(&data->xfer_list); - } - mutex_unlock(&adap->lock); - while (!list_empty(&fh->msgs)) { - struct cec_msg_entry *entry = - list_first_entry(&fh->msgs, struct cec_msg_entry, list); - - list_del(&entry->list); - kfree(entry); - } - kfree(fh); - - cec_put_device(devnode); - filp->private_data = NULL; - return 0; -} - -const struct file_operations cec_devnode_fops = { - .owner = THIS_MODULE, - .open = cec_open, - .unlocked_ioctl = cec_ioctl, - .release = cec_release, - .poll = cec_poll, - .llseek = no_llseek, -}; diff --git a/drivers/staging/media/cec/cec-core.c b/drivers/staging/media/cec/cec-core.c deleted file mode 100644 index b0137e247dc9..000000000000 --- a/drivers/staging/media/cec/cec-core.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * cec-core.c - HDMI Consumer Electronics Control framework - Core - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cec-priv.h" - -#define CEC_NUM_DEVICES 256 -#define CEC_NAME "cec" - -int cec_debug; -module_param_named(debug, cec_debug, int, 0644); -MODULE_PARM_DESC(debug, "debug level (0-2)"); - -static dev_t cec_dev_t; - -/* Active devices */ -static DEFINE_MUTEX(cec_devnode_lock); -static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES); - -static struct dentry *top_cec_dir; - -/* dev to cec_devnode */ -#define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev) - -int cec_get_device(struct cec_devnode *devnode) -{ - /* - * Check if the cec device is available. This needs to be done with - * the devnode->lock held to prevent an open/unregister race: - * without the lock, the device could be unregistered and freed between - * the devnode->registered check and get_device() calls, leading to - * a crash. - */ - mutex_lock(&devnode->lock); - /* - * return ENXIO if the cec device has been removed - * already or if it is not registered anymore. - */ - if (!devnode->registered) { - mutex_unlock(&devnode->lock); - return -ENXIO; - } - /* and increase the device refcount */ - get_device(&devnode->dev); - mutex_unlock(&devnode->lock); - return 0; -} - -void cec_put_device(struct cec_devnode *devnode) -{ - put_device(&devnode->dev); -} - -/* Called when the last user of the cec device exits. */ -static void cec_devnode_release(struct device *cd) -{ - struct cec_devnode *devnode = to_cec_devnode(cd); - - mutex_lock(&cec_devnode_lock); - /* Mark device node number as free */ - clear_bit(devnode->minor, cec_devnode_nums); - mutex_unlock(&cec_devnode_lock); - - cec_delete_adapter(to_cec_adapter(devnode)); -} - -static struct bus_type cec_bus_type = { - .name = CEC_NAME, -}; - -/* - * Register a cec device node - * - * The registration code assigns minor numbers and registers the new device node - * with the kernel. An error is returned if no free minor number can be found, - * or if the registration of the device node fails. - * - * Zero is returned on success. - * - * Note that if the cec_devnode_register call fails, the release() callback of - * the cec_devnode structure is *not* called, so the caller is responsible for - * freeing any data. - */ -static int __must_check cec_devnode_register(struct cec_devnode *devnode, - struct module *owner) -{ - int minor; - int ret; - - /* Initialization */ - INIT_LIST_HEAD(&devnode->fhs); - mutex_init(&devnode->lock); - - /* Part 1: Find a free minor number */ - mutex_lock(&cec_devnode_lock); - minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0); - if (minor == CEC_NUM_DEVICES) { - mutex_unlock(&cec_devnode_lock); - pr_err("could not get a free minor\n"); - return -ENFILE; - } - - set_bit(minor, cec_devnode_nums); - mutex_unlock(&cec_devnode_lock); - - devnode->minor = minor; - devnode->dev.bus = &cec_bus_type; - devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor); - devnode->dev.release = cec_devnode_release; - devnode->dev.parent = devnode->parent; - dev_set_name(&devnode->dev, "cec%d", devnode->minor); - device_initialize(&devnode->dev); - - /* Part 2: Initialize and register the character device */ - cdev_init(&devnode->cdev, &cec_devnode_fops); - devnode->cdev.kobj.parent = &devnode->dev.kobj; - devnode->cdev.owner = owner; - - ret = cdev_add(&devnode->cdev, devnode->dev.devt, 1); - if (ret < 0) { - pr_err("%s: cdev_add failed\n", __func__); - goto clr_bit; - } - - ret = device_add(&devnode->dev); - if (ret) - goto cdev_del; - - devnode->registered = true; - return 0; - -cdev_del: - cdev_del(&devnode->cdev); -clr_bit: - mutex_lock(&cec_devnode_lock); - clear_bit(devnode->minor, cec_devnode_nums); - mutex_unlock(&cec_devnode_lock); - return ret; -} - -/* - * Unregister a cec device node - * - * This unregisters the passed device. Future open calls will be met with - * errors. - * - * This function can safely be called if the device node has never been - * registered or has already been unregistered. - */ -static void cec_devnode_unregister(struct cec_devnode *devnode) -{ - struct cec_fh *fh; - - mutex_lock(&devnode->lock); - - /* Check if devnode was never registered or already unregistered */ - if (!devnode->registered || devnode->unregistered) { - mutex_unlock(&devnode->lock); - return; - } - - list_for_each_entry(fh, &devnode->fhs, list) - wake_up_interruptible(&fh->wait); - - devnode->registered = false; - devnode->unregistered = true; - mutex_unlock(&devnode->lock); - - device_del(&devnode->dev); - cdev_del(&devnode->cdev); - put_device(&devnode->dev); -} - -struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, - void *priv, const char *name, u32 caps, - u8 available_las, struct device *parent) -{ - struct cec_adapter *adap; - int res; - - if (WARN_ON(!parent)) - return ERR_PTR(-EINVAL); - if (WARN_ON(!caps)) - return ERR_PTR(-EINVAL); - if (WARN_ON(!ops)) - return ERR_PTR(-EINVAL); - if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS)) - return ERR_PTR(-EINVAL); - adap = kzalloc(sizeof(*adap), GFP_KERNEL); - if (!adap) - return ERR_PTR(-ENOMEM); - adap->owner = parent->driver->owner; - adap->devnode.parent = parent; - strlcpy(adap->name, name, sizeof(adap->name)); - adap->phys_addr = CEC_PHYS_ADDR_INVALID; - adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; - adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; - adap->capabilities = caps; - adap->available_log_addrs = available_las; - adap->sequence = 0; - adap->ops = ops; - adap->priv = priv; - memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); - mutex_init(&adap->lock); - INIT_LIST_HEAD(&adap->transmit_queue); - INIT_LIST_HEAD(&adap->wait_queue); - init_waitqueue_head(&adap->kthread_waitq); - - adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name); - if (IS_ERR(adap->kthread)) { - pr_err("cec-%s: kernel_thread() failed\n", name); - res = PTR_ERR(adap->kthread); - kfree(adap); - return ERR_PTR(res); - } - - if (!(caps & CEC_CAP_RC)) - return adap; - -#if IS_REACHABLE(CONFIG_RC_CORE) - /* Prepare the RC input device */ - adap->rc = rc_allocate_device(); - if (!adap->rc) { - pr_err("cec-%s: failed to allocate memory for rc_dev\n", - name); - kthread_stop(adap->kthread); - kfree(adap); - return ERR_PTR(-ENOMEM); - } - - snprintf(adap->input_name, sizeof(adap->input_name), - "RC for %s", name); - snprintf(adap->input_phys, sizeof(adap->input_phys), - "%s/input0", name); - - adap->rc->input_name = adap->input_name; - adap->rc->input_phys = adap->input_phys; - adap->rc->input_id.bustype = BUS_CEC; - adap->rc->input_id.vendor = 0; - adap->rc->input_id.product = 0; - adap->rc->input_id.version = 1; - adap->rc->dev.parent = parent; - adap->rc->driver_type = RC_DRIVER_SCANCODE; - adap->rc->driver_name = CEC_NAME; - adap->rc->allowed_protocols = RC_BIT_CEC; - adap->rc->priv = adap; - adap->rc->map_name = RC_MAP_CEC; - adap->rc->timeout = MS_TO_NS(100); -#else - adap->capabilities &= ~CEC_CAP_RC; -#endif - return adap; -} -EXPORT_SYMBOL_GPL(cec_allocate_adapter); - -int cec_register_adapter(struct cec_adapter *adap) -{ - int res; - - if (IS_ERR_OR_NULL(adap)) - return 0; - -#if IS_REACHABLE(CONFIG_RC_CORE) - if (adap->capabilities & CEC_CAP_RC) { - res = rc_register_device(adap->rc); - - if (res) { - pr_err("cec-%s: failed to prepare input device\n", - adap->name); - rc_free_device(adap->rc); - adap->rc = NULL; - return res; - } - } -#endif - - res = cec_devnode_register(&adap->devnode, adap->owner); - if (res) { -#if IS_REACHABLE(CONFIG_RC_CORE) - /* Note: rc_unregister also calls rc_free */ - rc_unregister_device(adap->rc); - adap->rc = NULL; -#endif - return res; - } - - dev_set_drvdata(&adap->devnode.dev, adap); -#ifdef CONFIG_MEDIA_CEC_DEBUG - if (!top_cec_dir) - return 0; - - adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir); - if (IS_ERR_OR_NULL(adap->cec_dir)) { - pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name); - return 0; - } - adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev, - "status", adap->cec_dir, cec_adap_status); - if (IS_ERR_OR_NULL(adap->status_file)) { - pr_warn("cec-%s: Failed to create status file\n", adap->name); - debugfs_remove_recursive(adap->cec_dir); - adap->cec_dir = NULL; - } -#endif - return 0; -} -EXPORT_SYMBOL_GPL(cec_register_adapter); - -void cec_unregister_adapter(struct cec_adapter *adap) -{ - if (IS_ERR_OR_NULL(adap)) - return; - -#if IS_REACHABLE(CONFIG_RC_CORE) - /* Note: rc_unregister also calls rc_free */ - rc_unregister_device(adap->rc); - adap->rc = NULL; -#endif - debugfs_remove_recursive(adap->cec_dir); - cec_devnode_unregister(&adap->devnode); -} -EXPORT_SYMBOL_GPL(cec_unregister_adapter); - -void cec_delete_adapter(struct cec_adapter *adap) -{ - if (IS_ERR_OR_NULL(adap)) - return; - mutex_lock(&adap->lock); - __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); - mutex_unlock(&adap->lock); - kthread_stop(adap->kthread); - if (adap->kthread_config) - kthread_stop(adap->kthread_config); -#if IS_REACHABLE(CONFIG_RC_CORE) - rc_free_device(adap->rc); -#endif - kfree(adap); -} -EXPORT_SYMBOL_GPL(cec_delete_adapter); - -/* - * Initialise cec for linux - */ -static int __init cec_devnode_init(void) -{ - int ret; - - pr_info("Linux cec interface: v0.10\n"); - ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, - CEC_NAME); - if (ret < 0) { - pr_warn("cec: unable to allocate major\n"); - return ret; - } - -#ifdef CONFIG_MEDIA_CEC_DEBUG - top_cec_dir = debugfs_create_dir("cec", NULL); - if (IS_ERR_OR_NULL(top_cec_dir)) { - pr_warn("cec: Failed to create debugfs cec dir\n"); - top_cec_dir = NULL; - } -#endif - - ret = bus_register(&cec_bus_type); - if (ret < 0) { - unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); - pr_warn("cec: bus_register failed\n"); - return -EIO; - } - - return 0; -} - -static void __exit cec_devnode_exit(void) -{ - debugfs_remove_recursive(top_cec_dir); - bus_unregister(&cec_bus_type); - unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); -} - -subsys_initcall(cec_devnode_init); -module_exit(cec_devnode_exit) - -MODULE_AUTHOR("Hans Verkuil "); -MODULE_DESCRIPTION("Device node registration for cec drivers"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/cec/cec-priv.h b/drivers/staging/media/cec/cec-priv.h deleted file mode 100644 index 70767a7900f2..000000000000 --- a/drivers/staging/media/cec/cec-priv.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * cec-priv.h - HDMI Consumer Electronics Control internal header - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _CEC_PRIV_H -#define _CEC_PRIV_H - -#include -#include - -#define dprintk(lvl, fmt, arg...) \ - do { \ - if (lvl <= cec_debug) \ - pr_info("cec-%s: " fmt, adap->name, ## arg); \ - } while (0) - -/* devnode to cec_adapter */ -#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode) - -/* cec-core.c */ -extern int cec_debug; -int cec_get_device(struct cec_devnode *devnode); -void cec_put_device(struct cec_devnode *devnode); - -/* cec-adap.c */ -int cec_monitor_all_cnt_inc(struct cec_adapter *adap); -void cec_monitor_all_cnt_dec(struct cec_adapter *adap); -int cec_adap_status(struct seq_file *file, void *priv); -int cec_thread_func(void *_adap); -void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block); -int __cec_s_log_addrs(struct cec_adapter *adap, - struct cec_log_addrs *log_addrs, bool block); -int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, - struct cec_fh *fh, bool block); -void cec_queue_event_fh(struct cec_fh *fh, - const struct cec_event *new_ev, u64 ts); - -/* cec-api.c */ -extern const struct file_operations cec_devnode_fops; - -#endif diff --git a/drivers/staging/media/pulse8-cec/Kconfig b/drivers/staging/media/pulse8-cec/Kconfig index c6aa2d1c9df0..6ffc407de62f 100644 --- a/drivers/staging/media/pulse8-cec/Kconfig +++ b/drivers/staging/media/pulse8-cec/Kconfig @@ -1,6 +1,6 @@ config USB_PULSE8_CEC tristate "Pulse Eight HDMI CEC" - depends on USB_ACM && MEDIA_CEC + depends on USB_ACM && MEDIA_CEC_SUPPORT select SERIO select SERIO_SERPORT ---help--- diff --git a/drivers/staging/media/s5p-cec/Kconfig b/drivers/staging/media/s5p-cec/Kconfig index 0315fd7ad0f1..ddfd955da0d4 100644 --- a/drivers/staging/media/s5p-cec/Kconfig +++ b/drivers/staging/media/s5p-cec/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SAMSUNG_S5P_CEC tristate "Samsung S5P CEC driver" - depends on VIDEO_DEV && MEDIA_CEC && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST) + depends on VIDEO_DEV && MEDIA_CEC_SUPPORT && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST) ---help--- This is a driver for Samsung S5P HDMI CEC interface. It uses the generic CEC framework interface. diff --git a/drivers/staging/media/st-cec/Kconfig b/drivers/staging/media/st-cec/Kconfig index 784d2c600aca..c04283db58d6 100644 --- a/drivers/staging/media/st-cec/Kconfig +++ b/drivers/staging/media/st-cec/Kconfig @@ -1,6 +1,6 @@ config VIDEO_STI_HDMI_CEC tristate "STMicroelectronics STiH4xx HDMI CEC driver" - depends on VIDEO_DEV && MEDIA_CEC && (ARCH_STI || COMPILE_TEST) + depends on VIDEO_DEV && MEDIA_CEC_SUPPORT && (ARCH_STI || COMPILE_TEST) ---help--- This is a driver for STIH4xx HDMI CEC interface. It uses the generic CEC framework interface. diff --git a/include/linux/cec-funcs.h b/include/linux/cec-funcs.h deleted file mode 100644 index 138bbf721e70..000000000000 --- a/include/linux/cec-funcs.h +++ /dev/null @@ -1,1971 +0,0 @@ -/* - * cec - HDMI Consumer Electronics Control message functions - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * Alternatively you can redistribute this file under the terms of the - * BSD license as stated below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. The names of its contributors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Note: this framework is still in staging and it is likely the API - * will change before it goes out of staging. - * - * Once it is moved out of staging this header will move to uapi. - */ -#ifndef _CEC_UAPI_FUNCS_H -#define _CEC_UAPI_FUNCS_H - -#include - -/* One Touch Play Feature */ -static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr) -{ - msg->len = 4; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_ACTIVE_SOURCE; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; -} - -static inline void cec_ops_active_source(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_image_view_on(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON; -} - -static inline void cec_msg_text_view_on(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_TEXT_VIEW_ON; -} - - -/* Routing Control Feature */ -static inline void cec_msg_inactive_source(struct cec_msg *msg, - __u16 phys_addr) -{ - msg->len = 4; - msg->msg[1] = CEC_MSG_INACTIVE_SOURCE; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; -} - -static inline void cec_ops_inactive_source(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_request_active_source(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE; - msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0; -} - -static inline void cec_msg_routing_information(struct cec_msg *msg, - __u16 phys_addr) -{ - msg->len = 4; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_ROUTING_INFORMATION; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; -} - -static inline void cec_ops_routing_information(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_routing_change(struct cec_msg *msg, - bool reply, - __u16 orig_phys_addr, - __u16 new_phys_addr) -{ - msg->len = 6; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_ROUTING_CHANGE; - msg->msg[2] = orig_phys_addr >> 8; - msg->msg[3] = orig_phys_addr & 0xff; - msg->msg[4] = new_phys_addr >> 8; - msg->msg[5] = new_phys_addr & 0xff; - msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0; -} - -static inline void cec_ops_routing_change(const struct cec_msg *msg, - __u16 *orig_phys_addr, - __u16 *new_phys_addr) -{ - *orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *new_phys_addr = (msg->msg[4] << 8) | msg->msg[5]; -} - -static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr) -{ - msg->len = 4; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_SET_STREAM_PATH; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; -} - -static inline void cec_ops_set_stream_path(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - - -/* Standby Feature */ -static inline void cec_msg_standby(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_STANDBY; -} - - -/* One Touch Record Feature */ -static inline void cec_msg_record_off(struct cec_msg *msg, bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_RECORD_OFF; - msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; -} - -struct cec_op_arib_data { - __u16 transport_id; - __u16 service_id; - __u16 orig_network_id; -}; - -struct cec_op_atsc_data { - __u16 transport_id; - __u16 program_number; -}; - -struct cec_op_dvb_data { - __u16 transport_id; - __u16 service_id; - __u16 orig_network_id; -}; - -struct cec_op_channel_data { - __u8 channel_number_fmt; - __u16 major; - __u16 minor; -}; - -struct cec_op_digital_service_id { - __u8 service_id_method; - __u8 dig_bcast_system; - union { - struct cec_op_arib_data arib; - struct cec_op_atsc_data atsc; - struct cec_op_dvb_data dvb; - struct cec_op_channel_data channel; - }; -}; - -struct cec_op_record_src { - __u8 type; - union { - struct cec_op_digital_service_id digital; - struct { - __u8 ana_bcast_type; - __u16 ana_freq; - __u8 bcast_system; - } analog; - struct { - __u8 plug; - } ext_plug; - struct { - __u16 phys_addr; - } ext_phys_addr; - }; -}; - -static inline void cec_set_digital_service_id(__u8 *msg, - const struct cec_op_digital_service_id *digital) -{ - *msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system; - if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { - *msg++ = (digital->channel.channel_number_fmt << 2) | - (digital->channel.major >> 8); - *msg++ = digital->channel.major & 0xff; - *msg++ = digital->channel.minor >> 8; - *msg++ = digital->channel.minor & 0xff; - *msg++ = 0; - *msg++ = 0; - return; - } - switch (digital->dig_bcast_system) { - case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN: - case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE: - case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT: - case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T: - *msg++ = digital->atsc.transport_id >> 8; - *msg++ = digital->atsc.transport_id & 0xff; - *msg++ = digital->atsc.program_number >> 8; - *msg++ = digital->atsc.program_number & 0xff; - *msg++ = 0; - *msg++ = 0; - break; - default: - *msg++ = digital->dvb.transport_id >> 8; - *msg++ = digital->dvb.transport_id & 0xff; - *msg++ = digital->dvb.service_id >> 8; - *msg++ = digital->dvb.service_id & 0xff; - *msg++ = digital->dvb.orig_network_id >> 8; - *msg++ = digital->dvb.orig_network_id & 0xff; - break; - } -} - -static inline void cec_get_digital_service_id(const __u8 *msg, - struct cec_op_digital_service_id *digital) -{ - digital->service_id_method = msg[0] >> 7; - digital->dig_bcast_system = msg[0] & 0x7f; - if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { - digital->channel.channel_number_fmt = msg[1] >> 2; - digital->channel.major = ((msg[1] & 3) << 6) | msg[2]; - digital->channel.minor = (msg[3] << 8) | msg[4]; - return; - } - digital->dvb.transport_id = (msg[1] << 8) | msg[2]; - digital->dvb.service_id = (msg[3] << 8) | msg[4]; - digital->dvb.orig_network_id = (msg[5] << 8) | msg[6]; -} - -static inline void cec_msg_record_on_own(struct cec_msg *msg) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_RECORD_ON; - msg->msg[2] = CEC_OP_RECORD_SRC_OWN; -} - -static inline void cec_msg_record_on_digital(struct cec_msg *msg, - const struct cec_op_digital_service_id *digital) -{ - msg->len = 10; - msg->msg[1] = CEC_MSG_RECORD_ON; - msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL; - cec_set_digital_service_id(msg->msg + 3, digital); -} - -static inline void cec_msg_record_on_analog(struct cec_msg *msg, - __u8 ana_bcast_type, - __u16 ana_freq, - __u8 bcast_system) -{ - msg->len = 7; - msg->msg[1] = CEC_MSG_RECORD_ON; - msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG; - msg->msg[3] = ana_bcast_type; - msg->msg[4] = ana_freq >> 8; - msg->msg[5] = ana_freq & 0xff; - msg->msg[6] = bcast_system; -} - -static inline void cec_msg_record_on_plug(struct cec_msg *msg, - __u8 plug) -{ - msg->len = 4; - msg->msg[1] = CEC_MSG_RECORD_ON; - msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG; - msg->msg[3] = plug; -} - -static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg, - __u16 phys_addr) -{ - msg->len = 5; - msg->msg[1] = CEC_MSG_RECORD_ON; - msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR; - msg->msg[3] = phys_addr >> 8; - msg->msg[4] = phys_addr & 0xff; -} - -static inline void cec_msg_record_on(struct cec_msg *msg, - bool reply, - const struct cec_op_record_src *rec_src) -{ - switch (rec_src->type) { - case CEC_OP_RECORD_SRC_OWN: - cec_msg_record_on_own(msg); - break; - case CEC_OP_RECORD_SRC_DIGITAL: - cec_msg_record_on_digital(msg, &rec_src->digital); - break; - case CEC_OP_RECORD_SRC_ANALOG: - cec_msg_record_on_analog(msg, - rec_src->analog.ana_bcast_type, - rec_src->analog.ana_freq, - rec_src->analog.bcast_system); - break; - case CEC_OP_RECORD_SRC_EXT_PLUG: - cec_msg_record_on_plug(msg, rec_src->ext_plug.plug); - break; - case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: - cec_msg_record_on_phys_addr(msg, - rec_src->ext_phys_addr.phys_addr); - break; - } - msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; -} - -static inline void cec_ops_record_on(const struct cec_msg *msg, - struct cec_op_record_src *rec_src) -{ - rec_src->type = msg->msg[2]; - switch (rec_src->type) { - case CEC_OP_RECORD_SRC_OWN: - break; - case CEC_OP_RECORD_SRC_DIGITAL: - cec_get_digital_service_id(msg->msg + 3, &rec_src->digital); - break; - case CEC_OP_RECORD_SRC_ANALOG: - rec_src->analog.ana_bcast_type = msg->msg[3]; - rec_src->analog.ana_freq = - (msg->msg[4] << 8) | msg->msg[5]; - rec_src->analog.bcast_system = msg->msg[6]; - break; - case CEC_OP_RECORD_SRC_EXT_PLUG: - rec_src->ext_plug.plug = msg->msg[3]; - break; - case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: - rec_src->ext_phys_addr.phys_addr = - (msg->msg[3] << 8) | msg->msg[4]; - break; - } -} - -static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_RECORD_STATUS; - msg->msg[2] = rec_status; -} - -static inline void cec_ops_record_status(const struct cec_msg *msg, - __u8 *rec_status) -{ - *rec_status = msg->msg[2]; -} - -static inline void cec_msg_record_tv_screen(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN; - msg->reply = reply ? CEC_MSG_RECORD_ON : 0; -} - - -/* Timer Programming Feature */ -static inline void cec_msg_timer_status(struct cec_msg *msg, - __u8 timer_overlap_warning, - __u8 media_info, - __u8 prog_info, - __u8 prog_error, - __u8 duration_hr, - __u8 duration_min) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_TIMER_STATUS; - msg->msg[2] = (timer_overlap_warning << 7) | - (media_info << 5) | - (prog_info ? 0x10 : 0) | - (prog_info ? prog_info : prog_error); - if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || - prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || - prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { - msg->len += 2; - msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10); - } -} - -static inline void cec_ops_timer_status(const struct cec_msg *msg, - __u8 *timer_overlap_warning, - __u8 *media_info, - __u8 *prog_info, - __u8 *prog_error, - __u8 *duration_hr, - __u8 *duration_min) -{ - *timer_overlap_warning = msg->msg[2] >> 7; - *media_info = (msg->msg[2] >> 5) & 3; - if (msg->msg[2] & 0x10) { - *prog_info = msg->msg[2] & 0xf; - *prog_error = 0; - } else { - *prog_info = 0; - *prog_error = msg->msg[2] & 0xf; - } - if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || - *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || - *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { - *duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf); - *duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - } else { - *duration_hr = *duration_min = 0; - } -} - -static inline void cec_msg_timer_cleared_status(struct cec_msg *msg, - __u8 timer_cleared_status) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS; - msg->msg[2] = timer_cleared_status; -} - -static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg, - __u8 *timer_cleared_status) -{ - *timer_cleared_status = msg->msg[2]; -} - -static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - __u8 ana_bcast_type, - __u16 ana_freq, - __u8 bcast_system) -{ - msg->len = 13; - msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - msg->msg[9] = ana_bcast_type; - msg->msg[10] = ana_freq >> 8; - msg->msg[11] = ana_freq & 0xff; - msg->msg[12] = bcast_system; - msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; -} - -static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - __u8 *ana_bcast_type, - __u16 *ana_freq, - __u8 *bcast_system) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - *ana_bcast_type = msg->msg[9]; - *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; - *bcast_system = msg->msg[12]; -} - -static inline void cec_msg_clear_digital_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - const struct cec_op_digital_service_id *digital) -{ - msg->len = 16; - msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; - msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - cec_set_digital_service_id(msg->msg + 9, digital); -} - -static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - struct cec_op_digital_service_id *digital) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - cec_get_digital_service_id(msg->msg + 9, digital); -} - -static inline void cec_msg_clear_ext_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - __u8 ext_src_spec, - __u8 plug, - __u16 phys_addr) -{ - msg->len = 13; - msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - msg->msg[9] = ext_src_spec; - msg->msg[10] = plug; - msg->msg[11] = phys_addr >> 8; - msg->msg[12] = phys_addr & 0xff; - msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; -} - -static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - __u8 *ext_src_spec, - __u8 *plug, - __u16 *phys_addr) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - *ext_src_spec = msg->msg[9]; - *plug = msg->msg[10]; - *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; -} - -static inline void cec_msg_set_analogue_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - __u8 ana_bcast_type, - __u16 ana_freq, - __u8 bcast_system) -{ - msg->len = 13; - msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - msg->msg[9] = ana_bcast_type; - msg->msg[10] = ana_freq >> 8; - msg->msg[11] = ana_freq & 0xff; - msg->msg[12] = bcast_system; - msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; -} - -static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - __u8 *ana_bcast_type, - __u16 *ana_freq, - __u8 *bcast_system) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - *ana_bcast_type = msg->msg[9]; - *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; - *bcast_system = msg->msg[12]; -} - -static inline void cec_msg_set_digital_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - const struct cec_op_digital_service_id *digital) -{ - msg->len = 16; - msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; - msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - cec_set_digital_service_id(msg->msg + 9, digital); -} - -static inline void cec_ops_set_digital_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - struct cec_op_digital_service_id *digital) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - cec_get_digital_service_id(msg->msg + 9, digital); -} - -static inline void cec_msg_set_ext_timer(struct cec_msg *msg, - bool reply, - __u8 day, - __u8 month, - __u8 start_hr, - __u8 start_min, - __u8 duration_hr, - __u8 duration_min, - __u8 recording_seq, - __u8 ext_src_spec, - __u8 plug, - __u16 phys_addr) -{ - msg->len = 13; - msg->msg[1] = CEC_MSG_SET_EXT_TIMER; - msg->msg[2] = day; - msg->msg[3] = month; - /* Hours and minutes are in BCD format */ - msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); - msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); - msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); - msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); - msg->msg[8] = recording_seq; - msg->msg[9] = ext_src_spec; - msg->msg[10] = plug; - msg->msg[11] = phys_addr >> 8; - msg->msg[12] = phys_addr & 0xff; - msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; -} - -static inline void cec_ops_set_ext_timer(const struct cec_msg *msg, - __u8 *day, - __u8 *month, - __u8 *start_hr, - __u8 *start_min, - __u8 *duration_hr, - __u8 *duration_min, - __u8 *recording_seq, - __u8 *ext_src_spec, - __u8 *plug, - __u16 *phys_addr) -{ - *day = msg->msg[2]; - *month = msg->msg[3]; - /* Hours and minutes are in BCD format */ - *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); - *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); - *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); - *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); - *recording_seq = msg->msg[8]; - *ext_src_spec = msg->msg[9]; - *plug = msg->msg[10]; - *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; -} - -static inline void cec_msg_set_timer_program_title(struct cec_msg *msg, - const char *prog_title) -{ - unsigned int len = strlen(prog_title); - - if (len > 14) - len = 14; - msg->len = 2 + len; - msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE; - memcpy(msg->msg + 2, prog_title, len); -} - -static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg, - char *prog_title) -{ - unsigned int len = msg->len > 2 ? msg->len - 2 : 0; - - if (len > 14) - len = 14; - memcpy(prog_title, msg->msg + 2, len); - prog_title[len] = '\0'; -} - -/* System Information Feature */ -static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_CEC_VERSION; - msg->msg[2] = cec_version; -} - -static inline void cec_ops_cec_version(const struct cec_msg *msg, - __u8 *cec_version) -{ - *cec_version = msg->msg[2]; -} - -static inline void cec_msg_get_cec_version(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GET_CEC_VERSION; - msg->reply = reply ? CEC_MSG_CEC_VERSION : 0; -} - -static inline void cec_msg_report_physical_addr(struct cec_msg *msg, - __u16 phys_addr, __u8 prim_devtype) -{ - msg->len = 5; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; - msg->msg[4] = prim_devtype; -} - -static inline void cec_ops_report_physical_addr(const struct cec_msg *msg, - __u16 *phys_addr, __u8 *prim_devtype) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *prim_devtype = msg->msg[4]; -} - -static inline void cec_msg_give_physical_addr(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR; - msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0; -} - -static inline void cec_msg_set_menu_language(struct cec_msg *msg, - const char *language) -{ - msg->len = 5; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE; - memcpy(msg->msg + 2, language, 3); -} - -static inline void cec_ops_set_menu_language(const struct cec_msg *msg, - char *language) -{ - memcpy(language, msg->msg + 2, 3); - language[3] = '\0'; -} - -static inline void cec_msg_get_menu_language(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE; - msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0; -} - -/* - * Assumes a single RC Profile byte and a single Device Features byte, - * i.e. no extended features are supported by this helper function. - * - * As of CEC 2.0 no extended features are defined, should those be added - * in the future, then this function needs to be adapted or a new function - * should be added. - */ -static inline void cec_msg_report_features(struct cec_msg *msg, - __u8 cec_version, __u8 all_device_types, - __u8 rc_profile, __u8 dev_features) -{ - msg->len = 6; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_REPORT_FEATURES; - msg->msg[2] = cec_version; - msg->msg[3] = all_device_types; - msg->msg[4] = rc_profile; - msg->msg[5] = dev_features; -} - -static inline void cec_ops_report_features(const struct cec_msg *msg, - __u8 *cec_version, __u8 *all_device_types, - const __u8 **rc_profile, const __u8 **dev_features) -{ - const __u8 *p = &msg->msg[4]; - - *cec_version = msg->msg[2]; - *all_device_types = msg->msg[3]; - *rc_profile = p; - while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT)) - p++; - if (!(*p & CEC_OP_FEAT_EXT)) { - *dev_features = p + 1; - while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT)) - p++; - } - if (*p & CEC_OP_FEAT_EXT) - *rc_profile = *dev_features = NULL; -} - -static inline void cec_msg_give_features(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_FEATURES; - msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0; -} - -/* Deck Control Feature */ -static inline void cec_msg_deck_control(struct cec_msg *msg, - __u8 deck_control_mode) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_DECK_CONTROL; - msg->msg[2] = deck_control_mode; -} - -static inline void cec_ops_deck_control(const struct cec_msg *msg, - __u8 *deck_control_mode) -{ - *deck_control_mode = msg->msg[2]; -} - -static inline void cec_msg_deck_status(struct cec_msg *msg, - __u8 deck_info) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_DECK_STATUS; - msg->msg[2] = deck_info; -} - -static inline void cec_ops_deck_status(const struct cec_msg *msg, - __u8 *deck_info) -{ - *deck_info = msg->msg[2]; -} - -static inline void cec_msg_give_deck_status(struct cec_msg *msg, - bool reply, - __u8 status_req) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS; - msg->msg[2] = status_req; - msg->reply = reply ? CEC_MSG_DECK_STATUS : 0; -} - -static inline void cec_ops_give_deck_status(const struct cec_msg *msg, - __u8 *status_req) -{ - *status_req = msg->msg[2]; -} - -static inline void cec_msg_play(struct cec_msg *msg, - __u8 play_mode) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_PLAY; - msg->msg[2] = play_mode; -} - -static inline void cec_ops_play(const struct cec_msg *msg, - __u8 *play_mode) -{ - *play_mode = msg->msg[2]; -} - - -/* Tuner Control Feature */ -struct cec_op_tuner_device_info { - __u8 rec_flag; - __u8 tuner_display_info; - bool is_analog; - union { - struct cec_op_digital_service_id digital; - struct { - __u8 ana_bcast_type; - __u16 ana_freq; - __u8 bcast_system; - } analog; - }; -}; - -static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg, - __u8 rec_flag, - __u8 tuner_display_info, - __u8 ana_bcast_type, - __u16 ana_freq, - __u8 bcast_system) -{ - msg->len = 7; - msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; - msg->msg[2] = (rec_flag << 7) | tuner_display_info; - msg->msg[3] = ana_bcast_type; - msg->msg[4] = ana_freq >> 8; - msg->msg[5] = ana_freq & 0xff; - msg->msg[6] = bcast_system; -} - -static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg, - __u8 rec_flag, __u8 tuner_display_info, - const struct cec_op_digital_service_id *digital) -{ - msg->len = 10; - msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; - msg->msg[2] = (rec_flag << 7) | tuner_display_info; - cec_set_digital_service_id(msg->msg + 3, digital); -} - -static inline void cec_msg_tuner_device_status(struct cec_msg *msg, - const struct cec_op_tuner_device_info *tuner_dev_info) -{ - if (tuner_dev_info->is_analog) - cec_msg_tuner_device_status_analog(msg, - tuner_dev_info->rec_flag, - tuner_dev_info->tuner_display_info, - tuner_dev_info->analog.ana_bcast_type, - tuner_dev_info->analog.ana_freq, - tuner_dev_info->analog.bcast_system); - else - cec_msg_tuner_device_status_digital(msg, - tuner_dev_info->rec_flag, - tuner_dev_info->tuner_display_info, - &tuner_dev_info->digital); -} - -static inline void cec_ops_tuner_device_status(const struct cec_msg *msg, - struct cec_op_tuner_device_info *tuner_dev_info) -{ - tuner_dev_info->is_analog = msg->len < 10; - tuner_dev_info->rec_flag = msg->msg[2] >> 7; - tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f; - if (tuner_dev_info->is_analog) { - tuner_dev_info->analog.ana_bcast_type = msg->msg[3]; - tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5]; - tuner_dev_info->analog.bcast_system = msg->msg[6]; - return; - } - cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital); -} - -static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg, - bool reply, - __u8 status_req) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS; - msg->msg[2] = status_req; - msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0; -} - -static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg, - __u8 *status_req) -{ - *status_req = msg->msg[2]; -} - -static inline void cec_msg_select_analogue_service(struct cec_msg *msg, - __u8 ana_bcast_type, - __u16 ana_freq, - __u8 bcast_system) -{ - msg->len = 6; - msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE; - msg->msg[2] = ana_bcast_type; - msg->msg[3] = ana_freq >> 8; - msg->msg[4] = ana_freq & 0xff; - msg->msg[5] = bcast_system; -} - -static inline void cec_ops_select_analogue_service(const struct cec_msg *msg, - __u8 *ana_bcast_type, - __u16 *ana_freq, - __u8 *bcast_system) -{ - *ana_bcast_type = msg->msg[2]; - *ana_freq = (msg->msg[3] << 8) | msg->msg[4]; - *bcast_system = msg->msg[5]; -} - -static inline void cec_msg_select_digital_service(struct cec_msg *msg, - const struct cec_op_digital_service_id *digital) -{ - msg->len = 9; - msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE; - cec_set_digital_service_id(msg->msg + 2, digital); -} - -static inline void cec_ops_select_digital_service(const struct cec_msg *msg, - struct cec_op_digital_service_id *digital) -{ - cec_get_digital_service_id(msg->msg + 2, digital); -} - -static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT; -} - -static inline void cec_msg_tuner_step_increment(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT; -} - - -/* Vendor Specific Commands Feature */ -static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id) -{ - msg->len = 5; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID; - msg->msg[2] = vendor_id >> 16; - msg->msg[3] = (vendor_id >> 8) & 0xff; - msg->msg[4] = vendor_id & 0xff; -} - -static inline void cec_ops_device_vendor_id(const struct cec_msg *msg, - __u32 *vendor_id) -{ - *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; -} - -static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID; - msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; -} - -static inline void cec_msg_vendor_command(struct cec_msg *msg, - __u8 size, const __u8 *vendor_cmd) -{ - if (size > 14) - size = 14; - msg->len = 2 + size; - msg->msg[1] = CEC_MSG_VENDOR_COMMAND; - memcpy(msg->msg + 2, vendor_cmd, size); -} - -static inline void cec_ops_vendor_command(const struct cec_msg *msg, - __u8 *size, - const __u8 **vendor_cmd) -{ - *size = msg->len - 2; - - if (*size > 14) - *size = 14; - *vendor_cmd = msg->msg + 2; -} - -static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg, - __u32 vendor_id, __u8 size, - const __u8 *vendor_cmd) -{ - if (size > 11) - size = 11; - msg->len = 5 + size; - msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID; - msg->msg[2] = vendor_id >> 16; - msg->msg[3] = (vendor_id >> 8) & 0xff; - msg->msg[4] = vendor_id & 0xff; - memcpy(msg->msg + 5, vendor_cmd, size); -} - -static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg, - __u32 *vendor_id, __u8 *size, - const __u8 **vendor_cmd) -{ - *size = msg->len - 5; - - if (*size > 11) - *size = 11; - *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; - *vendor_cmd = msg->msg + 5; -} - -static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg, - __u8 size, - const __u8 *rc_code) -{ - if (size > 14) - size = 14; - msg->len = 2 + size; - msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN; - memcpy(msg->msg + 2, rc_code, size); -} - -static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg, - __u8 *size, - const __u8 **rc_code) -{ - *size = msg->len - 2; - - if (*size > 14) - *size = 14; - *rc_code = msg->msg + 2; -} - -static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP; -} - - -/* OSD Display Feature */ -static inline void cec_msg_set_osd_string(struct cec_msg *msg, - __u8 disp_ctl, - const char *osd) -{ - unsigned int len = strlen(osd); - - if (len > 13) - len = 13; - msg->len = 3 + len; - msg->msg[1] = CEC_MSG_SET_OSD_STRING; - msg->msg[2] = disp_ctl; - memcpy(msg->msg + 3, osd, len); -} - -static inline void cec_ops_set_osd_string(const struct cec_msg *msg, - __u8 *disp_ctl, - char *osd) -{ - unsigned int len = msg->len > 3 ? msg->len - 3 : 0; - - *disp_ctl = msg->msg[2]; - if (len > 13) - len = 13; - memcpy(osd, msg->msg + 3, len); - osd[len] = '\0'; -} - - -/* Device OSD Transfer Feature */ -static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name) -{ - unsigned int len = strlen(name); - - if (len > 14) - len = 14; - msg->len = 2 + len; - msg->msg[1] = CEC_MSG_SET_OSD_NAME; - memcpy(msg->msg + 2, name, len); -} - -static inline void cec_ops_set_osd_name(const struct cec_msg *msg, - char *name) -{ - unsigned int len = msg->len > 2 ? msg->len - 2 : 0; - - if (len > 14) - len = 14; - memcpy(name, msg->msg + 2, len); - name[len] = '\0'; -} - -static inline void cec_msg_give_osd_name(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_OSD_NAME; - msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0; -} - - -/* Device Menu Control Feature */ -static inline void cec_msg_menu_status(struct cec_msg *msg, - __u8 menu_state) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_MENU_STATUS; - msg->msg[2] = menu_state; -} - -static inline void cec_ops_menu_status(const struct cec_msg *msg, - __u8 *menu_state) -{ - *menu_state = msg->msg[2]; -} - -static inline void cec_msg_menu_request(struct cec_msg *msg, - bool reply, - __u8 menu_req) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_MENU_REQUEST; - msg->msg[2] = menu_req; - msg->reply = reply ? CEC_MSG_MENU_STATUS : 0; -} - -static inline void cec_ops_menu_request(const struct cec_msg *msg, - __u8 *menu_req) -{ - *menu_req = msg->msg[2]; -} - -struct cec_op_ui_command { - __u8 ui_cmd; - bool has_opt_arg; - union { - struct cec_op_channel_data channel_identifier; - __u8 ui_broadcast_type; - __u8 ui_sound_presentation_control; - __u8 play_mode; - __u8 ui_function_media; - __u8 ui_function_select_av_input; - __u8 ui_function_select_audio_input; - }; -}; - -static inline void cec_msg_user_control_pressed(struct cec_msg *msg, - const struct cec_op_ui_command *ui_cmd) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED; - msg->msg[2] = ui_cmd->ui_cmd; - if (!ui_cmd->has_opt_arg) - return; - switch (ui_cmd->ui_cmd) { - case 0x56: - case 0x57: - case 0x60: - case 0x68: - case 0x69: - case 0x6a: - /* The optional operand is one byte for all these ui commands */ - msg->len++; - msg->msg[3] = ui_cmd->play_mode; - break; - case 0x67: - msg->len += 4; - msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | - (ui_cmd->channel_identifier.major >> 8); - msg->msg[4] = ui_cmd->channel_identifier.major & 0xff; - msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; - msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; - break; - } -} - -static inline void cec_ops_user_control_pressed(const struct cec_msg *msg, - struct cec_op_ui_command *ui_cmd) -{ - ui_cmd->ui_cmd = msg->msg[2]; - ui_cmd->has_opt_arg = false; - if (msg->len == 3) - return; - switch (ui_cmd->ui_cmd) { - case 0x56: - case 0x57: - case 0x60: - case 0x68: - case 0x69: - case 0x6a: - /* The optional operand is one byte for all these ui commands */ - ui_cmd->play_mode = msg->msg[3]; - ui_cmd->has_opt_arg = true; - break; - case 0x67: - if (msg->len < 7) - break; - ui_cmd->has_opt_arg = true; - ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2; - ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4]; - ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6]; - break; - } -} - -static inline void cec_msg_user_control_released(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED; -} - -/* Remote Control Passthrough Feature */ - -/* Power Status Feature */ -static inline void cec_msg_report_power_status(struct cec_msg *msg, - __u8 pwr_state) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS; - msg->msg[2] = pwr_state; -} - -static inline void cec_ops_report_power_status(const struct cec_msg *msg, - __u8 *pwr_state) -{ - *pwr_state = msg->msg[2]; -} - -static inline void cec_msg_give_device_power_status(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS; - msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0; -} - -/* General Protocol Messages */ -static inline void cec_msg_feature_abort(struct cec_msg *msg, - __u8 abort_msg, __u8 reason) -{ - msg->len = 4; - msg->msg[1] = CEC_MSG_FEATURE_ABORT; - msg->msg[2] = abort_msg; - msg->msg[3] = reason; -} - -static inline void cec_ops_feature_abort(const struct cec_msg *msg, - __u8 *abort_msg, __u8 *reason) -{ - *abort_msg = msg->msg[2]; - *reason = msg->msg[3]; -} - -/* This changes the current message into a feature abort message */ -static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason) -{ - cec_msg_set_reply_to(msg, msg); - msg->len = 4; - msg->msg[2] = msg->msg[1]; - msg->msg[3] = reason; - msg->msg[1] = CEC_MSG_FEATURE_ABORT; -} - -static inline void cec_msg_abort(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_ABORT; -} - - -/* System Audio Control Feature */ -static inline void cec_msg_report_audio_status(struct cec_msg *msg, - __u8 aud_mute_status, - __u8 aud_vol_status) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS; - msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f); -} - -static inline void cec_ops_report_audio_status(const struct cec_msg *msg, - __u8 *aud_mute_status, - __u8 *aud_vol_status) -{ - *aud_mute_status = msg->msg[2] >> 7; - *aud_vol_status = msg->msg[2] & 0x7f; -} - -static inline void cec_msg_give_audio_status(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS; - msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0; -} - -static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg, - __u8 sys_aud_status) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE; - msg->msg[2] = sys_aud_status; -} - -static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg, - __u8 *sys_aud_status) -{ - *sys_aud_status = msg->msg[2]; -} - -static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg, - bool reply, - __u16 phys_addr) -{ - msg->len = phys_addr == 0xffff ? 2 : 4; - msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; - msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0; - -} - -static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg, - __u16 *phys_addr) -{ - if (msg->len < 4) - *phys_addr = 0xffff; - else - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg, - __u8 sys_aud_status) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS; - msg->msg[2] = sys_aud_status; -} - -static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg, - __u8 *sys_aud_status) -{ - *sys_aud_status = msg->msg[2]; -} - -static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS; - msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0; -} - -static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg, - __u8 num_descriptors, - const __u32 *descriptors) -{ - unsigned int i; - - if (num_descriptors > 4) - num_descriptors = 4; - msg->len = 2 + num_descriptors * 3; - msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR; - for (i = 0; i < num_descriptors; i++) { - msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff; - msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff; - msg->msg[4 + i * 3] = descriptors[i] & 0xff; - } -} - -static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg, - __u8 *num_descriptors, - __u32 *descriptors) -{ - unsigned int i; - - *num_descriptors = (msg->len - 2) / 3; - if (*num_descriptors > 4) - *num_descriptors = 4; - for (i = 0; i < *num_descriptors; i++) - descriptors[i] = (msg->msg[2 + i * 3] << 16) | - (msg->msg[3 + i * 3] << 8) | - msg->msg[4 + i * 3]; -} - -static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg, - bool reply, - __u8 num_descriptors, - const __u8 *audio_format_id, - const __u8 *audio_format_code) -{ - unsigned int i; - - if (num_descriptors > 4) - num_descriptors = 4; - msg->len = 2 + num_descriptors; - msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR; - msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0; - for (i = 0; i < num_descriptors; i++) - msg->msg[2 + i] = (audio_format_id[i] << 6) | - (audio_format_code[i] & 0x3f); -} - -static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg, - __u8 *num_descriptors, - __u8 *audio_format_id, - __u8 *audio_format_code) -{ - unsigned int i; - - *num_descriptors = msg->len - 2; - if (*num_descriptors > 4) - *num_descriptors = 4; - for (i = 0; i < *num_descriptors; i++) { - audio_format_id[i] = msg->msg[2 + i] >> 6; - audio_format_code[i] = msg->msg[2 + i] & 0x3f; - } -} - - -/* Audio Rate Control Feature */ -static inline void cec_msg_set_audio_rate(struct cec_msg *msg, - __u8 audio_rate) -{ - msg->len = 3; - msg->msg[1] = CEC_MSG_SET_AUDIO_RATE; - msg->msg[2] = audio_rate; -} - -static inline void cec_ops_set_audio_rate(const struct cec_msg *msg, - __u8 *audio_rate) -{ - *audio_rate = msg->msg[2]; -} - - -/* Audio Return Channel Control Feature */ -static inline void cec_msg_report_arc_initiated(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED; -} - -static inline void cec_msg_initiate_arc(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_INITIATE_ARC; - msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0; -} - -static inline void cec_msg_request_arc_initiation(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION; - msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0; -} - -static inline void cec_msg_report_arc_terminated(struct cec_msg *msg) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED; -} - -static inline void cec_msg_terminate_arc(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_TERMINATE_ARC; - msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0; -} - -static inline void cec_msg_request_arc_termination(struct cec_msg *msg, - bool reply) -{ - msg->len = 2; - msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION; - msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0; -} - - -/* Dynamic Audio Lipsync Feature */ -/* Only for CEC 2.0 and up */ -static inline void cec_msg_report_current_latency(struct cec_msg *msg, - __u16 phys_addr, - __u8 video_latency, - __u8 low_latency_mode, - __u8 audio_out_compensated, - __u8 audio_out_delay) -{ - msg->len = 7; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; - msg->msg[4] = video_latency; - msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; - msg->msg[6] = audio_out_delay; -} - -static inline void cec_ops_report_current_latency(const struct cec_msg *msg, - __u16 *phys_addr, - __u8 *video_latency, - __u8 *low_latency_mode, - __u8 *audio_out_compensated, - __u8 *audio_out_delay) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *video_latency = msg->msg[4]; - *low_latency_mode = (msg->msg[5] >> 2) & 1; - *audio_out_compensated = msg->msg[5] & 3; - *audio_out_delay = msg->msg[6]; -} - -static inline void cec_msg_request_current_latency(struct cec_msg *msg, - bool reply, - __u16 phys_addr) -{ - msg->len = 4; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY; - msg->msg[2] = phys_addr >> 8; - msg->msg[3] = phys_addr & 0xff; - msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0; -} - -static inline void cec_ops_request_current_latency(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - - -/* Capability Discovery and Control Feature */ -static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg, - __u16 phys_addr1, - __u16 phys_addr2) -{ - msg->len = 9; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; - msg->msg[5] = phys_addr1 >> 8; - msg->msg[6] = phys_addr1 & 0xff; - msg->msg[7] = phys_addr2 >> 8; - msg->msg[8] = phys_addr2 & 0xff; -} - -static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg, - __u16 *phys_addr, - __u16 *phys_addr1, - __u16 *phys_addr2) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; - *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; -} - -static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg, - __u16 target_phys_addr, - __u8 hec_func_state, - __u8 host_func_state, - __u8 enc_func_state, - __u8 cdc_errcode, - __u8 has_field, - __u16 hec_field) -{ - msg->len = has_field ? 10 : 8; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE; - msg->msg[5] = target_phys_addr >> 8; - msg->msg[6] = target_phys_addr & 0xff; - msg->msg[7] = (hec_func_state << 6) | - (host_func_state << 4) | - (enc_func_state << 2) | - cdc_errcode; - if (has_field) { - msg->msg[8] = hec_field >> 8; - msg->msg[9] = hec_field & 0xff; - } -} - -static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg, - __u16 *phys_addr, - __u16 *target_phys_addr, - __u8 *hec_func_state, - __u8 *host_func_state, - __u8 *enc_func_state, - __u8 *cdc_errcode, - __u8 *has_field, - __u16 *hec_field) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *target_phys_addr = (msg->msg[5] << 8) | msg->msg[6]; - *hec_func_state = msg->msg[7] >> 6; - *host_func_state = (msg->msg[7] >> 4) & 3; - *enc_func_state = (msg->msg[7] >> 4) & 3; - *cdc_errcode = msg->msg[7] & 3; - *has_field = msg->len >= 10; - *hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0; -} - -static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg, - __u16 phys_addr1, - __u16 phys_addr2, - __u8 hec_set_state, - __u16 phys_addr3, - __u16 phys_addr4, - __u16 phys_addr5) -{ - msg->len = 10; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; - msg->msg[5] = phys_addr1 >> 8; - msg->msg[6] = phys_addr1 & 0xff; - msg->msg[7] = phys_addr2 >> 8; - msg->msg[8] = phys_addr2 & 0xff; - msg->msg[9] = hec_set_state; - if (phys_addr3 != CEC_PHYS_ADDR_INVALID) { - msg->msg[msg->len++] = phys_addr3 >> 8; - msg->msg[msg->len++] = phys_addr3 & 0xff; - if (phys_addr4 != CEC_PHYS_ADDR_INVALID) { - msg->msg[msg->len++] = phys_addr4 >> 8; - msg->msg[msg->len++] = phys_addr4 & 0xff; - if (phys_addr5 != CEC_PHYS_ADDR_INVALID) { - msg->msg[msg->len++] = phys_addr5 >> 8; - msg->msg[msg->len++] = phys_addr5 & 0xff; - } - } - } -} - -static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg, - __u16 *phys_addr, - __u16 *phys_addr1, - __u16 *phys_addr2, - __u8 *hec_set_state, - __u16 *phys_addr3, - __u16 *phys_addr4, - __u16 *phys_addr5) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; - *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; - *hec_set_state = msg->msg[9]; - *phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID; - if (msg->len >= 12) - *phys_addr3 = (msg->msg[10] << 8) | msg->msg[11]; - if (msg->len >= 14) - *phys_addr4 = (msg->msg[12] << 8) | msg->msg[13]; - if (msg->len >= 16) - *phys_addr5 = (msg->msg[14] << 8) | msg->msg[15]; -} - -static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg, - __u16 phys_addr1, - __u8 hec_set_state) -{ - msg->len = 8; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT; - msg->msg[5] = phys_addr1 >> 8; - msg->msg[6] = phys_addr1 & 0xff; - msg->msg[7] = hec_set_state; -} - -static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg, - __u16 *phys_addr, - __u16 *phys_addr1, - __u8 *hec_set_state) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; - *hec_set_state = msg->msg[7]; -} - -static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg, - __u16 phys_addr1, - __u16 phys_addr2, - __u16 phys_addr3) -{ - msg->len = 11; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION; - msg->msg[5] = phys_addr1 >> 8; - msg->msg[6] = phys_addr1 & 0xff; - msg->msg[7] = phys_addr2 >> 8; - msg->msg[8] = phys_addr2 & 0xff; - msg->msg[9] = phys_addr3 >> 8; - msg->msg[10] = phys_addr3 & 0xff; -} - -static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg, - __u16 *phys_addr, - __u16 *phys_addr1, - __u16 *phys_addr2, - __u16 *phys_addr3) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; - *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; - *phys_addr3 = (msg->msg[9] << 8) | msg->msg[10]; -} - -static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg) -{ - msg->len = 5; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE; -} - -static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg) -{ - msg->len = 5; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER; -} - -static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg, - __u16 *phys_addr) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; -} - -static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg, - __u8 input_port, - __u8 hpd_state) -{ - msg->len = 6; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE; - msg->msg[5] = (input_port << 4) | hpd_state; -} - -static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg, - __u16 *phys_addr, - __u8 *input_port, - __u8 *hpd_state) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *input_port = msg->msg[5] >> 4; - *hpd_state = msg->msg[5] & 0xf; -} - -static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg, - __u8 hpd_state, - __u8 hpd_error) -{ - msg->len = 6; - msg->msg[0] |= 0xf; /* broadcast */ - msg->msg[1] = CEC_MSG_CDC_MESSAGE; - /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ - msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE; - msg->msg[5] = (hpd_state << 4) | hpd_error; -} - -static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg, - __u16 *phys_addr, - __u8 *hpd_state, - __u8 *hpd_error) -{ - *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - *hpd_state = msg->msg[5] >> 4; - *hpd_error = msg->msg[5] & 0xf; -} - -#endif diff --git a/include/linux/cec.h b/include/linux/cec.h deleted file mode 100644 index 9c87711c0e1c..000000000000 --- a/include/linux/cec.h +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * cec - HDMI Consumer Electronics Control public header - * - * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * Alternatively you can redistribute this file under the terms of the - * BSD license as stated below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. The names of its contributors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Note: this framework is still in staging and it is likely the API - * will change before it goes out of staging. - * - * Once it is moved out of staging this header will move to uapi. - */ -#ifndef _CEC_UAPI_H -#define _CEC_UAPI_H - -#include - -#define CEC_MAX_MSG_SIZE 16 - -/** - * struct cec_msg - CEC message structure. - * @tx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the - * driver when the message transmission has finished. - * @rx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the - * driver when the message was received. - * @len: Length in bytes of the message. - * @timeout: The timeout (in ms) that is used to timeout CEC_RECEIVE. - * Set to 0 if you want to wait forever. This timeout can also be - * used with CEC_TRANSMIT as the timeout for waiting for a reply. - * If 0, then it will use a 1 second timeout instead of waiting - * forever as is done with CEC_RECEIVE. - * @sequence: The framework assigns a sequence number to messages that are - * sent. This can be used to track replies to previously sent - * messages. - * @flags: Set to 0. - * @msg: The message payload. - * @reply: This field is ignored with CEC_RECEIVE and is only used by - * CEC_TRANSMIT. If non-zero, then wait for a reply with this - * opcode. Set to CEC_MSG_FEATURE_ABORT if you want to wait for - * a possible ABORT reply. If there was an error when sending the - * msg or FeatureAbort was returned, then reply is set to 0. - * If reply is non-zero upon return, then len/msg are set to - * the received message. - * If reply is zero upon return and status has the - * CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to - * the received feature abort message. - * If reply is zero upon return and status has the - * CEC_TX_STATUS_MAX_RETRIES bit set, then no reply was seen at - * all. If reply is non-zero for CEC_TRANSMIT and the message is a - * broadcast, then -EINVAL is returned. - * if reply is non-zero, then timeout is set to 1000 (the required - * maximum response time). - * @rx_status: The message receive status bits. Set by the driver. - * @tx_status: The message transmit status bits. Set by the driver. - * @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver. - * @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver. - * @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the - * driver. - * @tx_error_cnt: The number of 'Error' events. Set by the driver. - */ -struct cec_msg { - __u64 tx_ts; - __u64 rx_ts; - __u32 len; - __u32 timeout; - __u32 sequence; - __u32 flags; - __u8 msg[CEC_MAX_MSG_SIZE]; - __u8 reply; - __u8 rx_status; - __u8 tx_status; - __u8 tx_arb_lost_cnt; - __u8 tx_nack_cnt; - __u8 tx_low_drive_cnt; - __u8 tx_error_cnt; -}; - -/** - * cec_msg_initiator - return the initiator's logical address. - * @msg: the message structure - */ -static inline __u8 cec_msg_initiator(const struct cec_msg *msg) -{ - return msg->msg[0] >> 4; -} - -/** - * cec_msg_destination - return the destination's logical address. - * @msg: the message structure - */ -static inline __u8 cec_msg_destination(const struct cec_msg *msg) -{ - return msg->msg[0] & 0xf; -} - -/** - * cec_msg_opcode - return the opcode of the message, -1 for poll - * @msg: the message structure - */ -static inline int cec_msg_opcode(const struct cec_msg *msg) -{ - return msg->len > 1 ? msg->msg[1] : -1; -} - -/** - * cec_msg_is_broadcast - return true if this is a broadcast message. - * @msg: the message structure - */ -static inline bool cec_msg_is_broadcast(const struct cec_msg *msg) -{ - return (msg->msg[0] & 0xf) == 0xf; -} - -/** - * cec_msg_init - initialize the message structure. - * @msg: the message structure - * @initiator: the logical address of the initiator - * @destination:the logical address of the destination (0xf for broadcast) - * - * The whole structure is zeroed, the len field is set to 1 (i.e. a poll - * message) and the initiator and destination are filled in. - */ -static inline void cec_msg_init(struct cec_msg *msg, - __u8 initiator, __u8 destination) -{ - memset(msg, 0, sizeof(*msg)); - msg->msg[0] = (initiator << 4) | destination; - msg->len = 1; -} - -/** - * cec_msg_set_reply_to - fill in destination/initiator in a reply message. - * @msg: the message structure for the reply - * @orig: the original message structure - * - * Set the msg destination to the orig initiator and the msg initiator to the - * orig destination. Note that msg and orig may be the same pointer, in which - * case the change is done in place. - */ -static inline void cec_msg_set_reply_to(struct cec_msg *msg, - struct cec_msg *orig) -{ - /* The destination becomes the initiator and vice versa */ - msg->msg[0] = (cec_msg_destination(orig) << 4) | - cec_msg_initiator(orig); - msg->reply = msg->timeout = 0; -} - -/* cec_msg flags field */ -#define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0) - -/* cec_msg tx/rx_status field */ -#define CEC_TX_STATUS_OK (1 << 0) -#define CEC_TX_STATUS_ARB_LOST (1 << 1) -#define CEC_TX_STATUS_NACK (1 << 2) -#define CEC_TX_STATUS_LOW_DRIVE (1 << 3) -#define CEC_TX_STATUS_ERROR (1 << 4) -#define CEC_TX_STATUS_MAX_RETRIES (1 << 5) - -#define CEC_RX_STATUS_OK (1 << 0) -#define CEC_RX_STATUS_TIMEOUT (1 << 1) -#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2) - -static inline bool cec_msg_status_is_ok(const struct cec_msg *msg) -{ - if (msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) - return false; - if (msg->rx_status && !(msg->rx_status & CEC_RX_STATUS_OK)) - return false; - if (!msg->tx_status && !msg->rx_status) - return false; - return !(msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT); -} - -#define CEC_LOG_ADDR_INVALID 0xff -#define CEC_PHYS_ADDR_INVALID 0xffff - -/* - * The maximum number of logical addresses one device can be assigned to. - * The CEC 2.0 spec allows for only 2 logical addresses at the moment. The - * Analog Devices CEC hardware supports 3. So let's go wild and go for 4. - */ -#define CEC_MAX_LOG_ADDRS 4 - -/* The logical addresses defined by CEC 2.0 */ -#define CEC_LOG_ADDR_TV 0 -#define CEC_LOG_ADDR_RECORD_1 1 -#define CEC_LOG_ADDR_RECORD_2 2 -#define CEC_LOG_ADDR_TUNER_1 3 -#define CEC_LOG_ADDR_PLAYBACK_1 4 -#define CEC_LOG_ADDR_AUDIOSYSTEM 5 -#define CEC_LOG_ADDR_TUNER_2 6 -#define CEC_LOG_ADDR_TUNER_3 7 -#define CEC_LOG_ADDR_PLAYBACK_2 8 -#define CEC_LOG_ADDR_RECORD_3 9 -#define CEC_LOG_ADDR_TUNER_4 10 -#define CEC_LOG_ADDR_PLAYBACK_3 11 -#define CEC_LOG_ADDR_BACKUP_1 12 -#define CEC_LOG_ADDR_BACKUP_2 13 -#define CEC_LOG_ADDR_SPECIFIC 14 -#define CEC_LOG_ADDR_UNREGISTERED 15 /* as initiator address */ -#define CEC_LOG_ADDR_BROADCAST 15 /* ad destination address */ - -/* The logical address types that the CEC device wants to claim */ -#define CEC_LOG_ADDR_TYPE_TV 0 -#define CEC_LOG_ADDR_TYPE_RECORD 1 -#define CEC_LOG_ADDR_TYPE_TUNER 2 -#define CEC_LOG_ADDR_TYPE_PLAYBACK 3 -#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM 4 -#define CEC_LOG_ADDR_TYPE_SPECIFIC 5 -#define CEC_LOG_ADDR_TYPE_UNREGISTERED 6 -/* - * Switches should use UNREGISTERED. - * Processors should use SPECIFIC. - */ - -#define CEC_LOG_ADDR_MASK_TV (1 << CEC_LOG_ADDR_TV) -#define CEC_LOG_ADDR_MASK_RECORD ((1 << CEC_LOG_ADDR_RECORD_1) | \ - (1 << CEC_LOG_ADDR_RECORD_2) | \ - (1 << CEC_LOG_ADDR_RECORD_3)) -#define CEC_LOG_ADDR_MASK_TUNER ((1 << CEC_LOG_ADDR_TUNER_1) | \ - (1 << CEC_LOG_ADDR_TUNER_2) | \ - (1 << CEC_LOG_ADDR_TUNER_3) | \ - (1 << CEC_LOG_ADDR_TUNER_4)) -#define CEC_LOG_ADDR_MASK_PLAYBACK ((1 << CEC_LOG_ADDR_PLAYBACK_1) | \ - (1 << CEC_LOG_ADDR_PLAYBACK_2) | \ - (1 << CEC_LOG_ADDR_PLAYBACK_3)) -#define CEC_LOG_ADDR_MASK_AUDIOSYSTEM (1 << CEC_LOG_ADDR_AUDIOSYSTEM) -#define CEC_LOG_ADDR_MASK_BACKUP ((1 << CEC_LOG_ADDR_BACKUP_1) | \ - (1 << CEC_LOG_ADDR_BACKUP_2)) -#define CEC_LOG_ADDR_MASK_SPECIFIC (1 << CEC_LOG_ADDR_SPECIFIC) -#define CEC_LOG_ADDR_MASK_UNREGISTERED (1 << CEC_LOG_ADDR_UNREGISTERED) - -static inline bool cec_has_tv(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_TV; -} - -static inline bool cec_has_record(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_RECORD; -} - -static inline bool cec_has_tuner(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_TUNER; -} - -static inline bool cec_has_playback(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_PLAYBACK; -} - -static inline bool cec_has_audiosystem(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_AUDIOSYSTEM; -} - -static inline bool cec_has_backup(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_BACKUP; -} - -static inline bool cec_has_specific(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_SPECIFIC; -} - -static inline bool cec_is_unregistered(__u16 log_addr_mask) -{ - return log_addr_mask & CEC_LOG_ADDR_MASK_UNREGISTERED; -} - -static inline bool cec_is_unconfigured(__u16 log_addr_mask) -{ - return log_addr_mask == 0; -} - -/* - * Use this if there is no vendor ID (CEC_G_VENDOR_ID) or if the vendor ID - * should be disabled (CEC_S_VENDOR_ID) - */ -#define CEC_VENDOR_ID_NONE 0xffffffff - -/* The message handling modes */ -/* Modes for initiator */ -#define CEC_MODE_NO_INITIATOR (0x0 << 0) -#define CEC_MODE_INITIATOR (0x1 << 0) -#define CEC_MODE_EXCL_INITIATOR (0x2 << 0) -#define CEC_MODE_INITIATOR_MSK 0x0f - -/* Modes for follower */ -#define CEC_MODE_NO_FOLLOWER (0x0 << 4) -#define CEC_MODE_FOLLOWER (0x1 << 4) -#define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) -#define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4) -#define CEC_MODE_MONITOR (0xe << 4) -#define CEC_MODE_MONITOR_ALL (0xf << 4) -#define CEC_MODE_FOLLOWER_MSK 0xf0 - -/* Userspace has to configure the physical address */ -#define CEC_CAP_PHYS_ADDR (1 << 0) -/* Userspace has to configure the logical addresses */ -#define CEC_CAP_LOG_ADDRS (1 << 1) -/* Userspace can transmit messages (and thus become follower as well) */ -#define CEC_CAP_TRANSMIT (1 << 2) -/* - * Passthrough all messages instead of processing them. - */ -#define CEC_CAP_PASSTHROUGH (1 << 3) -/* Supports remote control */ -#define CEC_CAP_RC (1 << 4) -/* Hardware can monitor all messages, not just directed and broadcast. */ -#define CEC_CAP_MONITOR_ALL (1 << 5) - -/** - * struct cec_caps - CEC capabilities structure. - * @driver: name of the CEC device driver. - * @name: name of the CEC device. @driver + @name must be unique. - * @available_log_addrs: number of available logical addresses. - * @capabilities: capabilities of the CEC adapter. - * @version: version of the CEC adapter framework. - */ -struct cec_caps { - char driver[32]; - char name[32]; - __u32 available_log_addrs; - __u32 capabilities; - __u32 version; -}; - -/** - * struct cec_log_addrs - CEC logical addresses structure. - * @log_addr: the claimed logical addresses. Set by the driver. - * @log_addr_mask: current logical address mask. Set by the driver. - * @cec_version: the CEC version that the adapter should implement. Set by the - * caller. - * @num_log_addrs: how many logical addresses should be claimed. Set by the - * caller. - * @vendor_id: the vendor ID of the device. Set by the caller. - * @flags: flags. - * @osd_name: the OSD name of the device. Set by the caller. - * @primary_device_type: the primary device type for each logical address. - * Set by the caller. - * @log_addr_type: the logical address types. Set by the caller. - * @all_device_types: CEC 2.0: all device types represented by the logical - * address. Set by the caller. - * @features: CEC 2.0: The logical address features. Set by the caller. - */ -struct cec_log_addrs { - __u8 log_addr[CEC_MAX_LOG_ADDRS]; - __u16 log_addr_mask; - __u8 cec_version; - __u8 num_log_addrs; - __u32 vendor_id; - __u32 flags; - char osd_name[15]; - __u8 primary_device_type[CEC_MAX_LOG_ADDRS]; - __u8 log_addr_type[CEC_MAX_LOG_ADDRS]; - - /* CEC 2.0 */ - __u8 all_device_types[CEC_MAX_LOG_ADDRS]; - __u8 features[CEC_MAX_LOG_ADDRS][12]; -}; - -/* Allow a fallback to unregistered */ -#define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) -/* Passthrough RC messages to the input subsystem */ -#define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1) -/* CDC-Only device: supports only CDC messages */ -#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2) - -/* Events */ - -/* Event that occurs when the adapter state changes */ -#define CEC_EVENT_STATE_CHANGE 1 -/* - * This event is sent when messages are lost because the application - * didn't empty the message queue in time - */ -#define CEC_EVENT_LOST_MSGS 2 - -#define CEC_EVENT_FL_INITIAL_STATE (1 << 0) - -/** - * struct cec_event_state_change - used when the CEC adapter changes state. - * @phys_addr: the current physical address - * @log_addr_mask: the current logical address mask - */ -struct cec_event_state_change { - __u16 phys_addr; - __u16 log_addr_mask; -}; - -/** - * struct cec_event_lost_msgs - tells you how many messages were lost due. - * @lost_msgs: how many messages were lost. - */ -struct cec_event_lost_msgs { - __u32 lost_msgs; -}; - -/** - * struct cec_event - CEC event structure - * @ts: the timestamp of when the event was sent. - * @event: the event. - * array. - * @state_change: the event payload for CEC_EVENT_STATE_CHANGE. - * @lost_msgs: the event payload for CEC_EVENT_LOST_MSGS. - * @raw: array to pad the union. - */ -struct cec_event { - __u64 ts; - __u32 event; - __u32 flags; - union { - struct cec_event_state_change state_change; - struct cec_event_lost_msgs lost_msgs; - __u32 raw[16]; - }; -}; - -/* ioctls */ - -/* Adapter capabilities */ -#define CEC_ADAP_G_CAPS _IOWR('a', 0, struct cec_caps) - -/* - * phys_addr is either 0 (if this is the CEC root device) - * or a valid physical address obtained from the sink's EDID - * as read by this CEC device (if this is a source device) - * or a physical address obtained and modified from a sink - * EDID and used for a sink CEC device. - * If nothing is connected, then phys_addr is 0xffff. - * See HDMI 1.4b, section 8.7 (Physical Address). - * - * The CEC_ADAP_S_PHYS_ADDR ioctl may not be available if that is handled - * internally. - */ -#define CEC_ADAP_G_PHYS_ADDR _IOR('a', 1, __u16) -#define CEC_ADAP_S_PHYS_ADDR _IOW('a', 2, __u16) - -/* - * Configure the CEC adapter. It sets the device type and which - * logical types it will try to claim. It will return which - * logical addresses it could actually claim. - * An error is returned if the adapter is disabled or if there - * is no physical address assigned. - */ - -#define CEC_ADAP_G_LOG_ADDRS _IOR('a', 3, struct cec_log_addrs) -#define CEC_ADAP_S_LOG_ADDRS _IOWR('a', 4, struct cec_log_addrs) - -/* Transmit/receive a CEC command */ -#define CEC_TRANSMIT _IOWR('a', 5, struct cec_msg) -#define CEC_RECEIVE _IOWR('a', 6, struct cec_msg) - -/* Dequeue CEC events */ -#define CEC_DQEVENT _IOWR('a', 7, struct cec_event) - -/* - * Get and set the message handling mode for this filehandle. - */ -#define CEC_G_MODE _IOR('a', 8, __u32) -#define CEC_S_MODE _IOW('a', 9, __u32) - -/* - * The remainder of this header defines all CEC messages and operands. - * The format matters since it the cec-ctl utility parses it to generate - * code for implementing all these messages. - * - * Comments ending with 'Feature' group messages for each feature. - * If messages are part of multiple features, then the "Has also" - * comment is used to list the previously defined messages that are - * supported by the feature. - * - * Before operands are defined a comment is added that gives the - * name of the operand and in brackets the variable name of the - * corresponding argument in the cec-funcs.h function. - */ - -/* Messages */ - -/* One Touch Play Feature */ -#define CEC_MSG_ACTIVE_SOURCE 0x82 -#define CEC_MSG_IMAGE_VIEW_ON 0x04 -#define CEC_MSG_TEXT_VIEW_ON 0x0d - - -/* Routing Control Feature */ - -/* - * Has also: - * CEC_MSG_ACTIVE_SOURCE - */ - -#define CEC_MSG_INACTIVE_SOURCE 0x9d -#define CEC_MSG_REQUEST_ACTIVE_SOURCE 0x85 -#define CEC_MSG_ROUTING_CHANGE 0x80 -#define CEC_MSG_ROUTING_INFORMATION 0x81 -#define CEC_MSG_SET_STREAM_PATH 0x86 - - -/* Standby Feature */ -#define CEC_MSG_STANDBY 0x36 - - -/* One Touch Record Feature */ -#define CEC_MSG_RECORD_OFF 0x0b -#define CEC_MSG_RECORD_ON 0x09 -/* Record Source Type Operand (rec_src_type) */ -#define CEC_OP_RECORD_SRC_OWN 1 -#define CEC_OP_RECORD_SRC_DIGITAL 2 -#define CEC_OP_RECORD_SRC_ANALOG 3 -#define CEC_OP_RECORD_SRC_EXT_PLUG 4 -#define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR 5 -/* Service Identification Method Operand (service_id_method) */ -#define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID 0 -#define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL 1 -/* Digital Service Broadcast System Operand (dig_bcast_system) */ -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN 0x00 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN 0x01 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN 0x02 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS 0x08 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS 0x09 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T 0x0a -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE 0x10 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT 0x11 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T 0x12 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C 0x18 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S 0x19 -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2 0x1a -#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T 0x1b -/* Analogue Broadcast Type Operand (ana_bcast_type) */ -#define CEC_OP_ANA_BCAST_TYPE_CABLE 0 -#define CEC_OP_ANA_BCAST_TYPE_SATELLITE 1 -#define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL 2 -/* Broadcast System Operand (bcast_system) */ -#define CEC_OP_BCAST_SYSTEM_PAL_BG 0x00 -#define CEC_OP_BCAST_SYSTEM_SECAM_LQ 0x01 /* SECAM L' */ -#define CEC_OP_BCAST_SYSTEM_PAL_M 0x02 -#define CEC_OP_BCAST_SYSTEM_NTSC_M 0x03 -#define CEC_OP_BCAST_SYSTEM_PAL_I 0x04 -#define CEC_OP_BCAST_SYSTEM_SECAM_DK 0x05 -#define CEC_OP_BCAST_SYSTEM_SECAM_BG 0x06 -#define CEC_OP_BCAST_SYSTEM_SECAM_L 0x07 -#define CEC_OP_BCAST_SYSTEM_PAL_DK 0x08 -#define CEC_OP_BCAST_SYSTEM_OTHER 0x1f -/* Channel Number Format Operand (channel_number_fmt) */ -#define CEC_OP_CHANNEL_NUMBER_FMT_1_PART 0x01 -#define CEC_OP_CHANNEL_NUMBER_FMT_2_PART 0x02 - -#define CEC_MSG_RECORD_STATUS 0x0a -/* Record Status Operand (rec_status) */ -#define CEC_OP_RECORD_STATUS_CUR_SRC 0x01 -#define CEC_OP_RECORD_STATUS_DIG_SERVICE 0x02 -#define CEC_OP_RECORD_STATUS_ANA_SERVICE 0x03 -#define CEC_OP_RECORD_STATUS_EXT_INPUT 0x04 -#define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE 0x05 -#define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE 0x06 -#define CEC_OP_RECORD_STATUS_NO_SERVICE 0x07 -#define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG 0x09 -#define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR 0x0a -#define CEC_OP_RECORD_STATUS_UNSUP_CA 0x0b -#define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS 0x0c -#define CEC_OP_RECORD_STATUS_CANT_COPY_SRC 0x0d -#define CEC_OP_RECORD_STATUS_NO_MORE_COPIES 0x0e -#define CEC_OP_RECORD_STATUS_NO_MEDIA 0x10 -#define CEC_OP_RECORD_STATUS_PLAYING 0x11 -#define CEC_OP_RECORD_STATUS_ALREADY_RECORDING 0x12 -#define CEC_OP_RECORD_STATUS_MEDIA_PROT 0x13 -#define CEC_OP_RECORD_STATUS_NO_SIGNAL 0x14 -#define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM 0x15 -#define CEC_OP_RECORD_STATUS_NO_SPACE 0x16 -#define CEC_OP_RECORD_STATUS_PARENTAL_LOCK 0x17 -#define CEC_OP_RECORD_STATUS_TERMINATED_OK 0x1a -#define CEC_OP_RECORD_STATUS_ALREADY_TERM 0x1b -#define CEC_OP_RECORD_STATUS_OTHER 0x1f - -#define CEC_MSG_RECORD_TV_SCREEN 0x0f - - -/* Timer Programming Feature */ -#define CEC_MSG_CLEAR_ANALOGUE_TIMER 0x33 -/* Recording Sequence Operand (recording_seq) */ -#define CEC_OP_REC_SEQ_SUNDAY 0x01 -#define CEC_OP_REC_SEQ_MONDAY 0x02 -#define CEC_OP_REC_SEQ_TUESDAY 0x04 -#define CEC_OP_REC_SEQ_WEDNESDAY 0x08 -#define CEC_OP_REC_SEQ_THURSDAY 0x10 -#define CEC_OP_REC_SEQ_FRIDAY 0x20 -#define CEC_OP_REC_SEQ_SATERDAY 0x40 -#define CEC_OP_REC_SEQ_ONCE_ONLY 0x00 - -#define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99 - -#define CEC_MSG_CLEAR_EXT_TIMER 0xa1 -/* External Source Specifier Operand (ext_src_spec) */ -#define CEC_OP_EXT_SRC_PLUG 0x04 -#define CEC_OP_EXT_SRC_PHYS_ADDR 0x05 - -#define CEC_MSG_SET_ANALOGUE_TIMER 0x34 -#define CEC_MSG_SET_DIGITAL_TIMER 0x97 -#define CEC_MSG_SET_EXT_TIMER 0xa2 - -#define CEC_MSG_SET_TIMER_PROGRAM_TITLE 0x67 -#define CEC_MSG_TIMER_CLEARED_STATUS 0x43 -/* Timer Cleared Status Data Operand (timer_cleared_status) */ -#define CEC_OP_TIMER_CLR_STAT_RECORDING 0x00 -#define CEC_OP_TIMER_CLR_STAT_NO_MATCHING 0x01 -#define CEC_OP_TIMER_CLR_STAT_NO_INFO 0x02 -#define CEC_OP_TIMER_CLR_STAT_CLEARED 0x80 - -#define CEC_MSG_TIMER_STATUS 0x35 -/* Timer Overlap Warning Operand (timer_overlap_warning) */ -#define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP 0 -#define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP 1 -/* Media Info Operand (media_info) */ -#define CEC_OP_MEDIA_INFO_UNPROT_MEDIA 0 -#define CEC_OP_MEDIA_INFO_PROT_MEDIA 1 -#define CEC_OP_MEDIA_INFO_NO_MEDIA 2 -/* Programmed Indicator Operand (prog_indicator) */ -#define CEC_OP_PROG_IND_NOT_PROGRAMMED 0 -#define CEC_OP_PROG_IND_PROGRAMMED 1 -/* Programmed Info Operand (prog_info) */ -#define CEC_OP_PROG_INFO_ENOUGH_SPACE 0x08 -#define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE 0x09 -#define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE 0x0b -#define CEC_OP_PROG_INFO_NONE_AVAILABLE 0x0a -/* Not Programmed Error Info Operand (prog_error) */ -#define CEC_OP_PROG_ERROR_NO_FREE_TIMER 0x01 -#define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE 0x02 -#define CEC_OP_PROG_ERROR_REC_SEQ_ERROR 0x03 -#define CEC_OP_PROG_ERROR_INV_EXT_PLUG 0x04 -#define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR 0x05 -#define CEC_OP_PROG_ERROR_CA_UNSUPP 0x06 -#define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS 0x07 -#define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP 0x08 -#define CEC_OP_PROG_ERROR_PARENTAL_LOCK 0x09 -#define CEC_OP_PROG_ERROR_CLOCK_FAILURE 0x0a -#define CEC_OP_PROG_ERROR_DUPLICATE 0x0e - - -/* System Information Feature */ -#define CEC_MSG_CEC_VERSION 0x9e -/* CEC Version Operand (cec_version) */ -#define CEC_OP_CEC_VERSION_1_3A 4 -#define CEC_OP_CEC_VERSION_1_4 5 -#define CEC_OP_CEC_VERSION_2_0 6 - -#define CEC_MSG_GET_CEC_VERSION 0x9f -#define CEC_MSG_GIVE_PHYSICAL_ADDR 0x83 -#define CEC_MSG_GET_MENU_LANGUAGE 0x91 -#define CEC_MSG_REPORT_PHYSICAL_ADDR 0x84 -/* Primary Device Type Operand (prim_devtype) */ -#define CEC_OP_PRIM_DEVTYPE_TV 0 -#define CEC_OP_PRIM_DEVTYPE_RECORD 1 -#define CEC_OP_PRIM_DEVTYPE_TUNER 3 -#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4 -#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5 -#define CEC_OP_PRIM_DEVTYPE_SWITCH 6 -#define CEC_OP_PRIM_DEVTYPE_PROCESSOR 7 - -#define CEC_MSG_SET_MENU_LANGUAGE 0x32 -#define CEC_MSG_REPORT_FEATURES 0xa6 /* HDMI 2.0 */ -/* All Device Types Operand (all_device_types) */ -#define CEC_OP_ALL_DEVTYPE_TV 0x80 -#define CEC_OP_ALL_DEVTYPE_RECORD 0x40 -#define CEC_OP_ALL_DEVTYPE_TUNER 0x20 -#define CEC_OP_ALL_DEVTYPE_PLAYBACK 0x10 -#define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM 0x08 -#define CEC_OP_ALL_DEVTYPE_SWITCH 0x04 -/* - * And if you wondering what happened to PROCESSOR devices: those should - * be mapped to a SWITCH. - */ - -/* Valid for RC Profile and Device Feature operands */ -#define CEC_OP_FEAT_EXT 0x80 /* Extension bit */ -/* RC Profile Operand (rc_profile) */ -#define CEC_OP_FEAT_RC_TV_PROFILE_NONE 0x00 -#define CEC_OP_FEAT_RC_TV_PROFILE_1 0x02 -#define CEC_OP_FEAT_RC_TV_PROFILE_2 0x06 -#define CEC_OP_FEAT_RC_TV_PROFILE_3 0x0a -#define CEC_OP_FEAT_RC_TV_PROFILE_4 0x0e -#define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU 0x50 -#define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU 0x48 -#define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU 0x44 -#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU 0x42 -#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU 0x41 -/* Device Feature Operand (dev_features) */ -#define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN 0x40 -#define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING 0x20 -#define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL 0x10 -#define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08 -#define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04 -#define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02 - -#define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */ - - -/* Deck Control Feature */ -#define CEC_MSG_DECK_CONTROL 0x42 -/* Deck Control Mode Operand (deck_control_mode) */ -#define CEC_OP_DECK_CTL_MODE_SKIP_FWD 1 -#define CEC_OP_DECK_CTL_MODE_SKIP_REV 2 -#define CEC_OP_DECK_CTL_MODE_STOP 3 -#define CEC_OP_DECK_CTL_MODE_EJECT 4 - -#define CEC_MSG_DECK_STATUS 0x1b -/* Deck Info Operand (deck_info) */ -#define CEC_OP_DECK_INFO_PLAY 0x11 -#define CEC_OP_DECK_INFO_RECORD 0x12 -#define CEC_OP_DECK_INFO_PLAY_REV 0x13 -#define CEC_OP_DECK_INFO_STILL 0x14 -#define CEC_OP_DECK_INFO_SLOW 0x15 -#define CEC_OP_DECK_INFO_SLOW_REV 0x16 -#define CEC_OP_DECK_INFO_FAST_FWD 0x17 -#define CEC_OP_DECK_INFO_FAST_REV 0x18 -#define CEC_OP_DECK_INFO_NO_MEDIA 0x19 -#define CEC_OP_DECK_INFO_STOP 0x1a -#define CEC_OP_DECK_INFO_SKIP_FWD 0x1b -#define CEC_OP_DECK_INFO_SKIP_REV 0x1c -#define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD 0x1d -#define CEC_OP_DECK_INFO_INDEX_SEARCH_REV 0x1e -#define CEC_OP_DECK_INFO_OTHER 0x1f - -#define CEC_MSG_GIVE_DECK_STATUS 0x1a -/* Status Request Operand (status_req) */ -#define CEC_OP_STATUS_REQ_ON 1 -#define CEC_OP_STATUS_REQ_OFF 2 -#define CEC_OP_STATUS_REQ_ONCE 3 - -#define CEC_MSG_PLAY 0x41 -/* Play Mode Operand (play_mode) */ -#define CEC_OP_PLAY_MODE_PLAY_FWD 0x24 -#define CEC_OP_PLAY_MODE_PLAY_REV 0x20 -#define CEC_OP_PLAY_MODE_PLAY_STILL 0x25 -#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN 0x05 -#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED 0x06 -#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX 0x07 -#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN 0x09 -#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED 0x0a -#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX 0x0b -#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN 0x15 -#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED 0x16 -#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX 0x17 -#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN 0x19 -#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED 0x1a -#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX 0x1b - - -/* Tuner Control Feature */ -#define CEC_MSG_GIVE_TUNER_DEVICE_STATUS 0x08 -#define CEC_MSG_SELECT_ANALOGUE_SERVICE 0x92 -#define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93 -#define CEC_MSG_TUNER_DEVICE_STATUS 0x07 -/* Recording Flag Operand (rec_flag) */ -#define CEC_OP_REC_FLAG_USED 0 -#define CEC_OP_REC_FLAG_NOT_USED 1 -/* Tuner Display Info Operand (tuner_display_info) */ -#define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0 -#define CEC_OP_TUNER_DISPLAY_INFO_NONE 1 -#define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE 2 - -#define CEC_MSG_TUNER_STEP_DECREMENT 0x06 -#define CEC_MSG_TUNER_STEP_INCREMENT 0x05 - - -/* Vendor Specific Commands Feature */ - -/* - * Has also: - * CEC_MSG_CEC_VERSION - * CEC_MSG_GET_CEC_VERSION - */ -#define CEC_MSG_DEVICE_VENDOR_ID 0x87 -#define CEC_MSG_GIVE_DEVICE_VENDOR_ID 0x8c -#define CEC_MSG_VENDOR_COMMAND 0x89 -#define CEC_MSG_VENDOR_COMMAND_WITH_ID 0xa0 -#define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN 0x8a -#define CEC_MSG_VENDOR_REMOTE_BUTTON_UP 0x8b - - -/* OSD Display Feature */ -#define CEC_MSG_SET_OSD_STRING 0x64 -/* Display Control Operand (disp_ctl) */ -#define CEC_OP_DISP_CTL_DEFAULT 0x00 -#define CEC_OP_DISP_CTL_UNTIL_CLEARED 0x40 -#define CEC_OP_DISP_CTL_CLEAR 0x80 - - -/* Device OSD Transfer Feature */ -#define CEC_MSG_GIVE_OSD_NAME 0x46 -#define CEC_MSG_SET_OSD_NAME 0x47 - - -/* Device Menu Control Feature */ -#define CEC_MSG_MENU_REQUEST 0x8d -/* Menu Request Type Operand (menu_req) */ -#define CEC_OP_MENU_REQUEST_ACTIVATE 0x00 -#define CEC_OP_MENU_REQUEST_DEACTIVATE 0x01 -#define CEC_OP_MENU_REQUEST_QUERY 0x02 - -#define CEC_MSG_MENU_STATUS 0x8e -/* Menu State Operand (menu_state) */ -#define CEC_OP_MENU_STATE_ACTIVATED 0x00 -#define CEC_OP_MENU_STATE_DEACTIVATED 0x01 - -#define CEC_MSG_USER_CONTROL_PRESSED 0x44 -/* UI Broadcast Type Operand (ui_bcast_type) */ -#define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL 0x00 -#define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA 0x01 -#define CEC_OP_UI_BCAST_TYPE_ANALOGUE 0x10 -#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T 0x20 -#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE 0x30 -#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT 0x40 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL 0x50 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL_T 0x60 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE 0x70 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT 0x80 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT 0x90 -#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2 0x91 -#define CEC_OP_UI_BCAST_TYPE_IP 0xa0 -/* UI Sound Presentation Control Operand (ui_snd_pres_ctl) */ -#define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO 0x10 -#define CEC_OP_UI_SND_PRES_CTL_KARAOKE 0x20 -#define CEC_OP_UI_SND_PRES_CTL_DOWNMIX 0x80 -#define CEC_OP_UI_SND_PRES_CTL_REVERB 0x90 -#define CEC_OP_UI_SND_PRES_CTL_EQUALIZER 0xa0 -#define CEC_OP_UI_SND_PRES_CTL_BASS_UP 0xb1 -#define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL 0xb2 -#define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN 0xb3 -#define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP 0xc1 -#define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL 0xc2 -#define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN 0xc3 - -#define CEC_MSG_USER_CONTROL_RELEASED 0x45 - - -/* Remote Control Passthrough Feature */ - -/* - * Has also: - * CEC_MSG_USER_CONTROL_PRESSED - * CEC_MSG_USER_CONTROL_RELEASED - */ - - -/* Power Status Feature */ -#define CEC_MSG_GIVE_DEVICE_POWER_STATUS 0x8f -#define CEC_MSG_REPORT_POWER_STATUS 0x90 -/* Power Status Operand (pwr_state) */ -#define CEC_OP_POWER_STATUS_ON 0 -#define CEC_OP_POWER_STATUS_STANDBY 1 -#define CEC_OP_POWER_STATUS_TO_ON 2 -#define CEC_OP_POWER_STATUS_TO_STANDBY 3 - - -/* General Protocol Messages */ -#define CEC_MSG_FEATURE_ABORT 0x00 -/* Abort Reason Operand (reason) */ -#define CEC_OP_ABORT_UNRECOGNIZED_OP 0 -#define CEC_OP_ABORT_INCORRECT_MODE 1 -#define CEC_OP_ABORT_NO_SOURCE 2 -#define CEC_OP_ABORT_INVALID_OP 3 -#define CEC_OP_ABORT_REFUSED 4 -#define CEC_OP_ABORT_UNDETERMINED 5 - -#define CEC_MSG_ABORT 0xff - - -/* System Audio Control Feature */ - -/* - * Has also: - * CEC_MSG_USER_CONTROL_PRESSED - * CEC_MSG_USER_CONTROL_RELEASED - */ -#define CEC_MSG_GIVE_AUDIO_STATUS 0x71 -#define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7d -#define CEC_MSG_REPORT_AUDIO_STATUS 0x7a -/* Audio Mute Status Operand (aud_mute_status) */ -#define CEC_OP_AUD_MUTE_STATUS_OFF 0 -#define CEC_OP_AUD_MUTE_STATUS_ON 1 - -#define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR 0xa3 -#define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR 0xa4 -#define CEC_MSG_SET_SYSTEM_AUDIO_MODE 0x72 -/* System Audio Status Operand (sys_aud_status) */ -#define CEC_OP_SYS_AUD_STATUS_OFF 0 -#define CEC_OP_SYS_AUD_STATUS_ON 1 - -#define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 0x70 -#define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 0x7e -/* Audio Format ID Operand (audio_format_id) */ -#define CEC_OP_AUD_FMT_ID_CEA861 0 -#define CEC_OP_AUD_FMT_ID_CEA861_CXT 1 - - -/* Audio Rate Control Feature */ -#define CEC_MSG_SET_AUDIO_RATE 0x9a -/* Audio Rate Operand (audio_rate) */ -#define CEC_OP_AUD_RATE_OFF 0 -#define CEC_OP_AUD_RATE_WIDE_STD 1 -#define CEC_OP_AUD_RATE_WIDE_FAST 2 -#define CEC_OP_AUD_RATE_WIDE_SLOW 3 -#define CEC_OP_AUD_RATE_NARROW_STD 4 -#define CEC_OP_AUD_RATE_NARROW_FAST 5 -#define CEC_OP_AUD_RATE_NARROW_SLOW 6 - - -/* Audio Return Channel Control Feature */ -#define CEC_MSG_INITIATE_ARC 0xc0 -#define CEC_MSG_REPORT_ARC_INITIATED 0xc1 -#define CEC_MSG_REPORT_ARC_TERMINATED 0xc2 -#define CEC_MSG_REQUEST_ARC_INITIATION 0xc3 -#define CEC_MSG_REQUEST_ARC_TERMINATION 0xc4 -#define CEC_MSG_TERMINATE_ARC 0xc5 - - -/* Dynamic Audio Lipsync Feature */ -/* Only for CEC 2.0 and up */ -#define CEC_MSG_REQUEST_CURRENT_LATENCY 0xa7 -#define CEC_MSG_REPORT_CURRENT_LATENCY 0xa8 -/* Low Latency Mode Operand (low_latency_mode) */ -#define CEC_OP_LOW_LATENCY_MODE_OFF 0 -#define CEC_OP_LOW_LATENCY_MODE_ON 1 -/* Audio Output Compensated Operand (audio_out_compensated) */ -#define CEC_OP_AUD_OUT_COMPENSATED_NA 0 -#define CEC_OP_AUD_OUT_COMPENSATED_DELAY 1 -#define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY 2 -#define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY 3 - - -/* Capability Discovery and Control Feature */ -#define CEC_MSG_CDC_MESSAGE 0xf8 -/* Ethernet-over-HDMI: nobody ever does this... */ -#define CEC_MSG_CDC_HEC_INQUIRE_STATE 0x00 -#define CEC_MSG_CDC_HEC_REPORT_STATE 0x01 -/* HEC Functionality State Operand (hec_func_state) */ -#define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED 0 -#define CEC_OP_HEC_FUNC_STATE_INACTIVE 1 -#define CEC_OP_HEC_FUNC_STATE_ACTIVE 2 -#define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD 3 -/* Host Functionality State Operand (host_func_state) */ -#define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED 0 -#define CEC_OP_HOST_FUNC_STATE_INACTIVE 1 -#define CEC_OP_HOST_FUNC_STATE_ACTIVE 2 -/* ENC Functionality State Operand (enc_func_state) */ -#define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED 0 -#define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE 1 -#define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE 2 -/* CDC Error Code Operand (cdc_errcode) */ -#define CEC_OP_CDC_ERROR_CODE_NONE 0 -#define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED 1 -#define CEC_OP_CDC_ERROR_CODE_WRONG_STATE 2 -#define CEC_OP_CDC_ERROR_CODE_OTHER 3 -/* HEC Support Operand (hec_support) */ -#define CEC_OP_HEC_SUPPORT_NO 0 -#define CEC_OP_HEC_SUPPORT_YES 1 -/* HEC Activation Operand (hec_activation) */ -#define CEC_OP_HEC_ACTIVATION_ON 0 -#define CEC_OP_HEC_ACTIVATION_OFF 1 - -#define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT 0x02 -#define CEC_MSG_CDC_HEC_SET_STATE 0x03 -/* HEC Set State Operand (hec_set_state) */ -#define CEC_OP_HEC_SET_STATE_DEACTIVATE 0 -#define CEC_OP_HEC_SET_STATE_ACTIVATE 1 - -#define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION 0x04 -#define CEC_MSG_CDC_HEC_NOTIFY_ALIVE 0x05 -#define CEC_MSG_CDC_HEC_DISCOVER 0x06 -/* Hotplug Detect messages */ -#define CEC_MSG_CDC_HPD_SET_STATE 0x10 -/* HPD State Operand (hpd_state) */ -#define CEC_OP_HPD_STATE_CP_EDID_DISABLE 0 -#define CEC_OP_HPD_STATE_CP_EDID_ENABLE 1 -#define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE 2 -#define CEC_OP_HPD_STATE_EDID_DISABLE 3 -#define CEC_OP_HPD_STATE_EDID_ENABLE 4 -#define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE 5 -#define CEC_MSG_CDC_HPD_REPORT_STATE 0x11 -/* HPD Error Code Operand (hpd_error) */ -#define CEC_OP_HPD_ERROR_NONE 0 -#define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE 1 -#define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE 2 -#define CEC_OP_HPD_ERROR_OTHER 3 -#define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 4 - -/* End of Messages */ - -/* Helper functions to identify the 'special' CEC devices */ - -static inline bool cec_is_2nd_tv(const struct cec_log_addrs *las) -{ - /* - * It is a second TV if the logical address is 14 or 15 and the - * primary device type is a TV. - */ - return las->num_log_addrs && - las->log_addr[0] >= CEC_LOG_ADDR_SPECIFIC && - las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_TV; -} - -static inline bool cec_is_processor(const struct cec_log_addrs *las) -{ - /* - * It is a processor if the logical address is 12-15 and the - * primary device type is a Processor. - */ - return las->num_log_addrs && - las->log_addr[0] >= CEC_LOG_ADDR_BACKUP_1 && - las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_PROCESSOR; -} - -static inline bool cec_is_switch(const struct cec_log_addrs *las) -{ - /* - * It is a switch if the logical address is 15 and the - * primary device type is a Switch and the CDC-Only flag is not set. - */ - return las->num_log_addrs == 1 && - las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && - las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && - !(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); -} - -static inline bool cec_is_cdc_only(const struct cec_log_addrs *las) -{ - /* - * It is a CDC-only device if the logical address is 15 and the - * primary device type is a Switch and the CDC-Only flag is set. - */ - return las->num_log_addrs == 1 && - las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && - las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && - (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); -} - -#endif diff --git a/include/media/cec.h b/include/media/cec.h index fdb5d600e4bb..717eaf552f3d 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -196,7 +196,7 @@ static inline bool cec_is_sink(const struct cec_adapter *adap) return adap->phys_addr == 0; } -#if IS_ENABLED(CONFIG_MEDIA_CEC) +#if IS_ENABLED(CONFIG_MEDIA_CEC_SUPPORT) struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, const char *name, u32 caps, u8 available_las, struct device *parent); diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 6965d0909554..c49c448cff92 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -82,6 +82,8 @@ header-y += capi.h header-y += cciss_defs.h header-y += cciss_ioctl.h header-y += cdrom.h +header-y += cec.h +header-y += cec-funcs.h header-y += cgroupstats.h header-y += chio.h header-y += cm4000_cs.h diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h new file mode 100644 index 000000000000..1a1de2169f48 --- /dev/null +++ b/include/uapi/linux/cec-funcs.h @@ -0,0 +1,1965 @@ +/* + * cec - HDMI Consumer Electronics Control message functions + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _CEC_UAPI_FUNCS_H +#define _CEC_UAPI_FUNCS_H + +#include + +/* One Touch Play Feature */ +static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr) +{ + msg->len = 4; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_ACTIVE_SOURCE; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; +} + +static inline void cec_ops_active_source(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_image_view_on(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON; +} + +static inline void cec_msg_text_view_on(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_TEXT_VIEW_ON; +} + + +/* Routing Control Feature */ +static inline void cec_msg_inactive_source(struct cec_msg *msg, + __u16 phys_addr) +{ + msg->len = 4; + msg->msg[1] = CEC_MSG_INACTIVE_SOURCE; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; +} + +static inline void cec_ops_inactive_source(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_request_active_source(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE; + msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0; +} + +static inline void cec_msg_routing_information(struct cec_msg *msg, + __u16 phys_addr) +{ + msg->len = 4; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_ROUTING_INFORMATION; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; +} + +static inline void cec_ops_routing_information(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_routing_change(struct cec_msg *msg, + bool reply, + __u16 orig_phys_addr, + __u16 new_phys_addr) +{ + msg->len = 6; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_ROUTING_CHANGE; + msg->msg[2] = orig_phys_addr >> 8; + msg->msg[3] = orig_phys_addr & 0xff; + msg->msg[4] = new_phys_addr >> 8; + msg->msg[5] = new_phys_addr & 0xff; + msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0; +} + +static inline void cec_ops_routing_change(const struct cec_msg *msg, + __u16 *orig_phys_addr, + __u16 *new_phys_addr) +{ + *orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *new_phys_addr = (msg->msg[4] << 8) | msg->msg[5]; +} + +static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr) +{ + msg->len = 4; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_SET_STREAM_PATH; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; +} + +static inline void cec_ops_set_stream_path(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + + +/* Standby Feature */ +static inline void cec_msg_standby(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_STANDBY; +} + + +/* One Touch Record Feature */ +static inline void cec_msg_record_off(struct cec_msg *msg, bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_RECORD_OFF; + msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; +} + +struct cec_op_arib_data { + __u16 transport_id; + __u16 service_id; + __u16 orig_network_id; +}; + +struct cec_op_atsc_data { + __u16 transport_id; + __u16 program_number; +}; + +struct cec_op_dvb_data { + __u16 transport_id; + __u16 service_id; + __u16 orig_network_id; +}; + +struct cec_op_channel_data { + __u8 channel_number_fmt; + __u16 major; + __u16 minor; +}; + +struct cec_op_digital_service_id { + __u8 service_id_method; + __u8 dig_bcast_system; + union { + struct cec_op_arib_data arib; + struct cec_op_atsc_data atsc; + struct cec_op_dvb_data dvb; + struct cec_op_channel_data channel; + }; +}; + +struct cec_op_record_src { + __u8 type; + union { + struct cec_op_digital_service_id digital; + struct { + __u8 ana_bcast_type; + __u16 ana_freq; + __u8 bcast_system; + } analog; + struct { + __u8 plug; + } ext_plug; + struct { + __u16 phys_addr; + } ext_phys_addr; + }; +}; + +static inline void cec_set_digital_service_id(__u8 *msg, + const struct cec_op_digital_service_id *digital) +{ + *msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system; + if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { + *msg++ = (digital->channel.channel_number_fmt << 2) | + (digital->channel.major >> 8); + *msg++ = digital->channel.major & 0xff; + *msg++ = digital->channel.minor >> 8; + *msg++ = digital->channel.minor & 0xff; + *msg++ = 0; + *msg++ = 0; + return; + } + switch (digital->dig_bcast_system) { + case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN: + case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE: + case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT: + case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T: + *msg++ = digital->atsc.transport_id >> 8; + *msg++ = digital->atsc.transport_id & 0xff; + *msg++ = digital->atsc.program_number >> 8; + *msg++ = digital->atsc.program_number & 0xff; + *msg++ = 0; + *msg++ = 0; + break; + default: + *msg++ = digital->dvb.transport_id >> 8; + *msg++ = digital->dvb.transport_id & 0xff; + *msg++ = digital->dvb.service_id >> 8; + *msg++ = digital->dvb.service_id & 0xff; + *msg++ = digital->dvb.orig_network_id >> 8; + *msg++ = digital->dvb.orig_network_id & 0xff; + break; + } +} + +static inline void cec_get_digital_service_id(const __u8 *msg, + struct cec_op_digital_service_id *digital) +{ + digital->service_id_method = msg[0] >> 7; + digital->dig_bcast_system = msg[0] & 0x7f; + if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { + digital->channel.channel_number_fmt = msg[1] >> 2; + digital->channel.major = ((msg[1] & 3) << 6) | msg[2]; + digital->channel.minor = (msg[3] << 8) | msg[4]; + return; + } + digital->dvb.transport_id = (msg[1] << 8) | msg[2]; + digital->dvb.service_id = (msg[3] << 8) | msg[4]; + digital->dvb.orig_network_id = (msg[5] << 8) | msg[6]; +} + +static inline void cec_msg_record_on_own(struct cec_msg *msg) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_RECORD_ON; + msg->msg[2] = CEC_OP_RECORD_SRC_OWN; +} + +static inline void cec_msg_record_on_digital(struct cec_msg *msg, + const struct cec_op_digital_service_id *digital) +{ + msg->len = 10; + msg->msg[1] = CEC_MSG_RECORD_ON; + msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL; + cec_set_digital_service_id(msg->msg + 3, digital); +} + +static inline void cec_msg_record_on_analog(struct cec_msg *msg, + __u8 ana_bcast_type, + __u16 ana_freq, + __u8 bcast_system) +{ + msg->len = 7; + msg->msg[1] = CEC_MSG_RECORD_ON; + msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG; + msg->msg[3] = ana_bcast_type; + msg->msg[4] = ana_freq >> 8; + msg->msg[5] = ana_freq & 0xff; + msg->msg[6] = bcast_system; +} + +static inline void cec_msg_record_on_plug(struct cec_msg *msg, + __u8 plug) +{ + msg->len = 4; + msg->msg[1] = CEC_MSG_RECORD_ON; + msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG; + msg->msg[3] = plug; +} + +static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg, + __u16 phys_addr) +{ + msg->len = 5; + msg->msg[1] = CEC_MSG_RECORD_ON; + msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR; + msg->msg[3] = phys_addr >> 8; + msg->msg[4] = phys_addr & 0xff; +} + +static inline void cec_msg_record_on(struct cec_msg *msg, + bool reply, + const struct cec_op_record_src *rec_src) +{ + switch (rec_src->type) { + case CEC_OP_RECORD_SRC_OWN: + cec_msg_record_on_own(msg); + break; + case CEC_OP_RECORD_SRC_DIGITAL: + cec_msg_record_on_digital(msg, &rec_src->digital); + break; + case CEC_OP_RECORD_SRC_ANALOG: + cec_msg_record_on_analog(msg, + rec_src->analog.ana_bcast_type, + rec_src->analog.ana_freq, + rec_src->analog.bcast_system); + break; + case CEC_OP_RECORD_SRC_EXT_PLUG: + cec_msg_record_on_plug(msg, rec_src->ext_plug.plug); + break; + case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: + cec_msg_record_on_phys_addr(msg, + rec_src->ext_phys_addr.phys_addr); + break; + } + msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; +} + +static inline void cec_ops_record_on(const struct cec_msg *msg, + struct cec_op_record_src *rec_src) +{ + rec_src->type = msg->msg[2]; + switch (rec_src->type) { + case CEC_OP_RECORD_SRC_OWN: + break; + case CEC_OP_RECORD_SRC_DIGITAL: + cec_get_digital_service_id(msg->msg + 3, &rec_src->digital); + break; + case CEC_OP_RECORD_SRC_ANALOG: + rec_src->analog.ana_bcast_type = msg->msg[3]; + rec_src->analog.ana_freq = + (msg->msg[4] << 8) | msg->msg[5]; + rec_src->analog.bcast_system = msg->msg[6]; + break; + case CEC_OP_RECORD_SRC_EXT_PLUG: + rec_src->ext_plug.plug = msg->msg[3]; + break; + case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: + rec_src->ext_phys_addr.phys_addr = + (msg->msg[3] << 8) | msg->msg[4]; + break; + } +} + +static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_RECORD_STATUS; + msg->msg[2] = rec_status; +} + +static inline void cec_ops_record_status(const struct cec_msg *msg, + __u8 *rec_status) +{ + *rec_status = msg->msg[2]; +} + +static inline void cec_msg_record_tv_screen(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN; + msg->reply = reply ? CEC_MSG_RECORD_ON : 0; +} + + +/* Timer Programming Feature */ +static inline void cec_msg_timer_status(struct cec_msg *msg, + __u8 timer_overlap_warning, + __u8 media_info, + __u8 prog_info, + __u8 prog_error, + __u8 duration_hr, + __u8 duration_min) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_TIMER_STATUS; + msg->msg[2] = (timer_overlap_warning << 7) | + (media_info << 5) | + (prog_info ? 0x10 : 0) | + (prog_info ? prog_info : prog_error); + if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || + prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || + prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { + msg->len += 2; + msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10); + } +} + +static inline void cec_ops_timer_status(const struct cec_msg *msg, + __u8 *timer_overlap_warning, + __u8 *media_info, + __u8 *prog_info, + __u8 *prog_error, + __u8 *duration_hr, + __u8 *duration_min) +{ + *timer_overlap_warning = msg->msg[2] >> 7; + *media_info = (msg->msg[2] >> 5) & 3; + if (msg->msg[2] & 0x10) { + *prog_info = msg->msg[2] & 0xf; + *prog_error = 0; + } else { + *prog_info = 0; + *prog_error = msg->msg[2] & 0xf; + } + if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || + *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || + *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { + *duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf); + *duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + } else { + *duration_hr = *duration_min = 0; + } +} + +static inline void cec_msg_timer_cleared_status(struct cec_msg *msg, + __u8 timer_cleared_status) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS; + msg->msg[2] = timer_cleared_status; +} + +static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg, + __u8 *timer_cleared_status) +{ + *timer_cleared_status = msg->msg[2]; +} + +static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + __u8 ana_bcast_type, + __u16 ana_freq, + __u8 bcast_system) +{ + msg->len = 13; + msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + msg->msg[9] = ana_bcast_type; + msg->msg[10] = ana_freq >> 8; + msg->msg[11] = ana_freq & 0xff; + msg->msg[12] = bcast_system; + msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; +} + +static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + __u8 *ana_bcast_type, + __u16 *ana_freq, + __u8 *bcast_system) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + *ana_bcast_type = msg->msg[9]; + *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; + *bcast_system = msg->msg[12]; +} + +static inline void cec_msg_clear_digital_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + const struct cec_op_digital_service_id *digital) +{ + msg->len = 16; + msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; + msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + cec_set_digital_service_id(msg->msg + 9, digital); +} + +static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + struct cec_op_digital_service_id *digital) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + cec_get_digital_service_id(msg->msg + 9, digital); +} + +static inline void cec_msg_clear_ext_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + __u8 ext_src_spec, + __u8 plug, + __u16 phys_addr) +{ + msg->len = 13; + msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + msg->msg[9] = ext_src_spec; + msg->msg[10] = plug; + msg->msg[11] = phys_addr >> 8; + msg->msg[12] = phys_addr & 0xff; + msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; +} + +static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + __u8 *ext_src_spec, + __u8 *plug, + __u16 *phys_addr) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + *ext_src_spec = msg->msg[9]; + *plug = msg->msg[10]; + *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; +} + +static inline void cec_msg_set_analogue_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + __u8 ana_bcast_type, + __u16 ana_freq, + __u8 bcast_system) +{ + msg->len = 13; + msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + msg->msg[9] = ana_bcast_type; + msg->msg[10] = ana_freq >> 8; + msg->msg[11] = ana_freq & 0xff; + msg->msg[12] = bcast_system; + msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; +} + +static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + __u8 *ana_bcast_type, + __u16 *ana_freq, + __u8 *bcast_system) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + *ana_bcast_type = msg->msg[9]; + *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; + *bcast_system = msg->msg[12]; +} + +static inline void cec_msg_set_digital_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + const struct cec_op_digital_service_id *digital) +{ + msg->len = 16; + msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; + msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + cec_set_digital_service_id(msg->msg + 9, digital); +} + +static inline void cec_ops_set_digital_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + struct cec_op_digital_service_id *digital) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + cec_get_digital_service_id(msg->msg + 9, digital); +} + +static inline void cec_msg_set_ext_timer(struct cec_msg *msg, + bool reply, + __u8 day, + __u8 month, + __u8 start_hr, + __u8 start_min, + __u8 duration_hr, + __u8 duration_min, + __u8 recording_seq, + __u8 ext_src_spec, + __u8 plug, + __u16 phys_addr) +{ + msg->len = 13; + msg->msg[1] = CEC_MSG_SET_EXT_TIMER; + msg->msg[2] = day; + msg->msg[3] = month; + /* Hours and minutes are in BCD format */ + msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); + msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); + msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); + msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); + msg->msg[8] = recording_seq; + msg->msg[9] = ext_src_spec; + msg->msg[10] = plug; + msg->msg[11] = phys_addr >> 8; + msg->msg[12] = phys_addr & 0xff; + msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; +} + +static inline void cec_ops_set_ext_timer(const struct cec_msg *msg, + __u8 *day, + __u8 *month, + __u8 *start_hr, + __u8 *start_min, + __u8 *duration_hr, + __u8 *duration_min, + __u8 *recording_seq, + __u8 *ext_src_spec, + __u8 *plug, + __u16 *phys_addr) +{ + *day = msg->msg[2]; + *month = msg->msg[3]; + /* Hours and minutes are in BCD format */ + *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); + *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); + *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); + *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); + *recording_seq = msg->msg[8]; + *ext_src_spec = msg->msg[9]; + *plug = msg->msg[10]; + *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; +} + +static inline void cec_msg_set_timer_program_title(struct cec_msg *msg, + const char *prog_title) +{ + unsigned int len = strlen(prog_title); + + if (len > 14) + len = 14; + msg->len = 2 + len; + msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE; + memcpy(msg->msg + 2, prog_title, len); +} + +static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg, + char *prog_title) +{ + unsigned int len = msg->len > 2 ? msg->len - 2 : 0; + + if (len > 14) + len = 14; + memcpy(prog_title, msg->msg + 2, len); + prog_title[len] = '\0'; +} + +/* System Information Feature */ +static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_CEC_VERSION; + msg->msg[2] = cec_version; +} + +static inline void cec_ops_cec_version(const struct cec_msg *msg, + __u8 *cec_version) +{ + *cec_version = msg->msg[2]; +} + +static inline void cec_msg_get_cec_version(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GET_CEC_VERSION; + msg->reply = reply ? CEC_MSG_CEC_VERSION : 0; +} + +static inline void cec_msg_report_physical_addr(struct cec_msg *msg, + __u16 phys_addr, __u8 prim_devtype) +{ + msg->len = 5; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; + msg->msg[4] = prim_devtype; +} + +static inline void cec_ops_report_physical_addr(const struct cec_msg *msg, + __u16 *phys_addr, __u8 *prim_devtype) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *prim_devtype = msg->msg[4]; +} + +static inline void cec_msg_give_physical_addr(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR; + msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0; +} + +static inline void cec_msg_set_menu_language(struct cec_msg *msg, + const char *language) +{ + msg->len = 5; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE; + memcpy(msg->msg + 2, language, 3); +} + +static inline void cec_ops_set_menu_language(const struct cec_msg *msg, + char *language) +{ + memcpy(language, msg->msg + 2, 3); + language[3] = '\0'; +} + +static inline void cec_msg_get_menu_language(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE; + msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0; +} + +/* + * Assumes a single RC Profile byte and a single Device Features byte, + * i.e. no extended features are supported by this helper function. + * + * As of CEC 2.0 no extended features are defined, should those be added + * in the future, then this function needs to be adapted or a new function + * should be added. + */ +static inline void cec_msg_report_features(struct cec_msg *msg, + __u8 cec_version, __u8 all_device_types, + __u8 rc_profile, __u8 dev_features) +{ + msg->len = 6; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_REPORT_FEATURES; + msg->msg[2] = cec_version; + msg->msg[3] = all_device_types; + msg->msg[4] = rc_profile; + msg->msg[5] = dev_features; +} + +static inline void cec_ops_report_features(const struct cec_msg *msg, + __u8 *cec_version, __u8 *all_device_types, + const __u8 **rc_profile, const __u8 **dev_features) +{ + const __u8 *p = &msg->msg[4]; + + *cec_version = msg->msg[2]; + *all_device_types = msg->msg[3]; + *rc_profile = p; + while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT)) + p++; + if (!(*p & CEC_OP_FEAT_EXT)) { + *dev_features = p + 1; + while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT)) + p++; + } + if (*p & CEC_OP_FEAT_EXT) + *rc_profile = *dev_features = NULL; +} + +static inline void cec_msg_give_features(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_FEATURES; + msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0; +} + +/* Deck Control Feature */ +static inline void cec_msg_deck_control(struct cec_msg *msg, + __u8 deck_control_mode) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_DECK_CONTROL; + msg->msg[2] = deck_control_mode; +} + +static inline void cec_ops_deck_control(const struct cec_msg *msg, + __u8 *deck_control_mode) +{ + *deck_control_mode = msg->msg[2]; +} + +static inline void cec_msg_deck_status(struct cec_msg *msg, + __u8 deck_info) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_DECK_STATUS; + msg->msg[2] = deck_info; +} + +static inline void cec_ops_deck_status(const struct cec_msg *msg, + __u8 *deck_info) +{ + *deck_info = msg->msg[2]; +} + +static inline void cec_msg_give_deck_status(struct cec_msg *msg, + bool reply, + __u8 status_req) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS; + msg->msg[2] = status_req; + msg->reply = reply ? CEC_MSG_DECK_STATUS : 0; +} + +static inline void cec_ops_give_deck_status(const struct cec_msg *msg, + __u8 *status_req) +{ + *status_req = msg->msg[2]; +} + +static inline void cec_msg_play(struct cec_msg *msg, + __u8 play_mode) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_PLAY; + msg->msg[2] = play_mode; +} + +static inline void cec_ops_play(const struct cec_msg *msg, + __u8 *play_mode) +{ + *play_mode = msg->msg[2]; +} + + +/* Tuner Control Feature */ +struct cec_op_tuner_device_info { + __u8 rec_flag; + __u8 tuner_display_info; + bool is_analog; + union { + struct cec_op_digital_service_id digital; + struct { + __u8 ana_bcast_type; + __u16 ana_freq; + __u8 bcast_system; + } analog; + }; +}; + +static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg, + __u8 rec_flag, + __u8 tuner_display_info, + __u8 ana_bcast_type, + __u16 ana_freq, + __u8 bcast_system) +{ + msg->len = 7; + msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; + msg->msg[2] = (rec_flag << 7) | tuner_display_info; + msg->msg[3] = ana_bcast_type; + msg->msg[4] = ana_freq >> 8; + msg->msg[5] = ana_freq & 0xff; + msg->msg[6] = bcast_system; +} + +static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg, + __u8 rec_flag, __u8 tuner_display_info, + const struct cec_op_digital_service_id *digital) +{ + msg->len = 10; + msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; + msg->msg[2] = (rec_flag << 7) | tuner_display_info; + cec_set_digital_service_id(msg->msg + 3, digital); +} + +static inline void cec_msg_tuner_device_status(struct cec_msg *msg, + const struct cec_op_tuner_device_info *tuner_dev_info) +{ + if (tuner_dev_info->is_analog) + cec_msg_tuner_device_status_analog(msg, + tuner_dev_info->rec_flag, + tuner_dev_info->tuner_display_info, + tuner_dev_info->analog.ana_bcast_type, + tuner_dev_info->analog.ana_freq, + tuner_dev_info->analog.bcast_system); + else + cec_msg_tuner_device_status_digital(msg, + tuner_dev_info->rec_flag, + tuner_dev_info->tuner_display_info, + &tuner_dev_info->digital); +} + +static inline void cec_ops_tuner_device_status(const struct cec_msg *msg, + struct cec_op_tuner_device_info *tuner_dev_info) +{ + tuner_dev_info->is_analog = msg->len < 10; + tuner_dev_info->rec_flag = msg->msg[2] >> 7; + tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f; + if (tuner_dev_info->is_analog) { + tuner_dev_info->analog.ana_bcast_type = msg->msg[3]; + tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5]; + tuner_dev_info->analog.bcast_system = msg->msg[6]; + return; + } + cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital); +} + +static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg, + bool reply, + __u8 status_req) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS; + msg->msg[2] = status_req; + msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0; +} + +static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg, + __u8 *status_req) +{ + *status_req = msg->msg[2]; +} + +static inline void cec_msg_select_analogue_service(struct cec_msg *msg, + __u8 ana_bcast_type, + __u16 ana_freq, + __u8 bcast_system) +{ + msg->len = 6; + msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE; + msg->msg[2] = ana_bcast_type; + msg->msg[3] = ana_freq >> 8; + msg->msg[4] = ana_freq & 0xff; + msg->msg[5] = bcast_system; +} + +static inline void cec_ops_select_analogue_service(const struct cec_msg *msg, + __u8 *ana_bcast_type, + __u16 *ana_freq, + __u8 *bcast_system) +{ + *ana_bcast_type = msg->msg[2]; + *ana_freq = (msg->msg[3] << 8) | msg->msg[4]; + *bcast_system = msg->msg[5]; +} + +static inline void cec_msg_select_digital_service(struct cec_msg *msg, + const struct cec_op_digital_service_id *digital) +{ + msg->len = 9; + msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE; + cec_set_digital_service_id(msg->msg + 2, digital); +} + +static inline void cec_ops_select_digital_service(const struct cec_msg *msg, + struct cec_op_digital_service_id *digital) +{ + cec_get_digital_service_id(msg->msg + 2, digital); +} + +static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT; +} + +static inline void cec_msg_tuner_step_increment(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT; +} + + +/* Vendor Specific Commands Feature */ +static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id) +{ + msg->len = 5; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID; + msg->msg[2] = vendor_id >> 16; + msg->msg[3] = (vendor_id >> 8) & 0xff; + msg->msg[4] = vendor_id & 0xff; +} + +static inline void cec_ops_device_vendor_id(const struct cec_msg *msg, + __u32 *vendor_id) +{ + *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; +} + +static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID; + msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; +} + +static inline void cec_msg_vendor_command(struct cec_msg *msg, + __u8 size, const __u8 *vendor_cmd) +{ + if (size > 14) + size = 14; + msg->len = 2 + size; + msg->msg[1] = CEC_MSG_VENDOR_COMMAND; + memcpy(msg->msg + 2, vendor_cmd, size); +} + +static inline void cec_ops_vendor_command(const struct cec_msg *msg, + __u8 *size, + const __u8 **vendor_cmd) +{ + *size = msg->len - 2; + + if (*size > 14) + *size = 14; + *vendor_cmd = msg->msg + 2; +} + +static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg, + __u32 vendor_id, __u8 size, + const __u8 *vendor_cmd) +{ + if (size > 11) + size = 11; + msg->len = 5 + size; + msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID; + msg->msg[2] = vendor_id >> 16; + msg->msg[3] = (vendor_id >> 8) & 0xff; + msg->msg[4] = vendor_id & 0xff; + memcpy(msg->msg + 5, vendor_cmd, size); +} + +static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg, + __u32 *vendor_id, __u8 *size, + const __u8 **vendor_cmd) +{ + *size = msg->len - 5; + + if (*size > 11) + *size = 11; + *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; + *vendor_cmd = msg->msg + 5; +} + +static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg, + __u8 size, + const __u8 *rc_code) +{ + if (size > 14) + size = 14; + msg->len = 2 + size; + msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN; + memcpy(msg->msg + 2, rc_code, size); +} + +static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg, + __u8 *size, + const __u8 **rc_code) +{ + *size = msg->len - 2; + + if (*size > 14) + *size = 14; + *rc_code = msg->msg + 2; +} + +static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP; +} + + +/* OSD Display Feature */ +static inline void cec_msg_set_osd_string(struct cec_msg *msg, + __u8 disp_ctl, + const char *osd) +{ + unsigned int len = strlen(osd); + + if (len > 13) + len = 13; + msg->len = 3 + len; + msg->msg[1] = CEC_MSG_SET_OSD_STRING; + msg->msg[2] = disp_ctl; + memcpy(msg->msg + 3, osd, len); +} + +static inline void cec_ops_set_osd_string(const struct cec_msg *msg, + __u8 *disp_ctl, + char *osd) +{ + unsigned int len = msg->len > 3 ? msg->len - 3 : 0; + + *disp_ctl = msg->msg[2]; + if (len > 13) + len = 13; + memcpy(osd, msg->msg + 3, len); + osd[len] = '\0'; +} + + +/* Device OSD Transfer Feature */ +static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name) +{ + unsigned int len = strlen(name); + + if (len > 14) + len = 14; + msg->len = 2 + len; + msg->msg[1] = CEC_MSG_SET_OSD_NAME; + memcpy(msg->msg + 2, name, len); +} + +static inline void cec_ops_set_osd_name(const struct cec_msg *msg, + char *name) +{ + unsigned int len = msg->len > 2 ? msg->len - 2 : 0; + + if (len > 14) + len = 14; + memcpy(name, msg->msg + 2, len); + name[len] = '\0'; +} + +static inline void cec_msg_give_osd_name(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_OSD_NAME; + msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0; +} + + +/* Device Menu Control Feature */ +static inline void cec_msg_menu_status(struct cec_msg *msg, + __u8 menu_state) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_MENU_STATUS; + msg->msg[2] = menu_state; +} + +static inline void cec_ops_menu_status(const struct cec_msg *msg, + __u8 *menu_state) +{ + *menu_state = msg->msg[2]; +} + +static inline void cec_msg_menu_request(struct cec_msg *msg, + bool reply, + __u8 menu_req) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_MENU_REQUEST; + msg->msg[2] = menu_req; + msg->reply = reply ? CEC_MSG_MENU_STATUS : 0; +} + +static inline void cec_ops_menu_request(const struct cec_msg *msg, + __u8 *menu_req) +{ + *menu_req = msg->msg[2]; +} + +struct cec_op_ui_command { + __u8 ui_cmd; + bool has_opt_arg; + union { + struct cec_op_channel_data channel_identifier; + __u8 ui_broadcast_type; + __u8 ui_sound_presentation_control; + __u8 play_mode; + __u8 ui_function_media; + __u8 ui_function_select_av_input; + __u8 ui_function_select_audio_input; + }; +}; + +static inline void cec_msg_user_control_pressed(struct cec_msg *msg, + const struct cec_op_ui_command *ui_cmd) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED; + msg->msg[2] = ui_cmd->ui_cmd; + if (!ui_cmd->has_opt_arg) + return; + switch (ui_cmd->ui_cmd) { + case 0x56: + case 0x57: + case 0x60: + case 0x68: + case 0x69: + case 0x6a: + /* The optional operand is one byte for all these ui commands */ + msg->len++; + msg->msg[3] = ui_cmd->play_mode; + break; + case 0x67: + msg->len += 4; + msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | + (ui_cmd->channel_identifier.major >> 8); + msg->msg[4] = ui_cmd->channel_identifier.major & 0xff; + msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; + msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; + break; + } +} + +static inline void cec_ops_user_control_pressed(const struct cec_msg *msg, + struct cec_op_ui_command *ui_cmd) +{ + ui_cmd->ui_cmd = msg->msg[2]; + ui_cmd->has_opt_arg = false; + if (msg->len == 3) + return; + switch (ui_cmd->ui_cmd) { + case 0x56: + case 0x57: + case 0x60: + case 0x68: + case 0x69: + case 0x6a: + /* The optional operand is one byte for all these ui commands */ + ui_cmd->play_mode = msg->msg[3]; + ui_cmd->has_opt_arg = true; + break; + case 0x67: + if (msg->len < 7) + break; + ui_cmd->has_opt_arg = true; + ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2; + ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4]; + ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6]; + break; + } +} + +static inline void cec_msg_user_control_released(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED; +} + +/* Remote Control Passthrough Feature */ + +/* Power Status Feature */ +static inline void cec_msg_report_power_status(struct cec_msg *msg, + __u8 pwr_state) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS; + msg->msg[2] = pwr_state; +} + +static inline void cec_ops_report_power_status(const struct cec_msg *msg, + __u8 *pwr_state) +{ + *pwr_state = msg->msg[2]; +} + +static inline void cec_msg_give_device_power_status(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS; + msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0; +} + +/* General Protocol Messages */ +static inline void cec_msg_feature_abort(struct cec_msg *msg, + __u8 abort_msg, __u8 reason) +{ + msg->len = 4; + msg->msg[1] = CEC_MSG_FEATURE_ABORT; + msg->msg[2] = abort_msg; + msg->msg[3] = reason; +} + +static inline void cec_ops_feature_abort(const struct cec_msg *msg, + __u8 *abort_msg, __u8 *reason) +{ + *abort_msg = msg->msg[2]; + *reason = msg->msg[3]; +} + +/* This changes the current message into a feature abort message */ +static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason) +{ + cec_msg_set_reply_to(msg, msg); + msg->len = 4; + msg->msg[2] = msg->msg[1]; + msg->msg[3] = reason; + msg->msg[1] = CEC_MSG_FEATURE_ABORT; +} + +static inline void cec_msg_abort(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_ABORT; +} + + +/* System Audio Control Feature */ +static inline void cec_msg_report_audio_status(struct cec_msg *msg, + __u8 aud_mute_status, + __u8 aud_vol_status) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS; + msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f); +} + +static inline void cec_ops_report_audio_status(const struct cec_msg *msg, + __u8 *aud_mute_status, + __u8 *aud_vol_status) +{ + *aud_mute_status = msg->msg[2] >> 7; + *aud_vol_status = msg->msg[2] & 0x7f; +} + +static inline void cec_msg_give_audio_status(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS; + msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0; +} + +static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg, + __u8 sys_aud_status) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE; + msg->msg[2] = sys_aud_status; +} + +static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg, + __u8 *sys_aud_status) +{ + *sys_aud_status = msg->msg[2]; +} + +static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg, + bool reply, + __u16 phys_addr) +{ + msg->len = phys_addr == 0xffff ? 2 : 4; + msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; + msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0; + +} + +static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg, + __u16 *phys_addr) +{ + if (msg->len < 4) + *phys_addr = 0xffff; + else + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg, + __u8 sys_aud_status) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS; + msg->msg[2] = sys_aud_status; +} + +static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg, + __u8 *sys_aud_status) +{ + *sys_aud_status = msg->msg[2]; +} + +static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS; + msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0; +} + +static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg, + __u8 num_descriptors, + const __u32 *descriptors) +{ + unsigned int i; + + if (num_descriptors > 4) + num_descriptors = 4; + msg->len = 2 + num_descriptors * 3; + msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR; + for (i = 0; i < num_descriptors; i++) { + msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff; + msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff; + msg->msg[4 + i * 3] = descriptors[i] & 0xff; + } +} + +static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg, + __u8 *num_descriptors, + __u32 *descriptors) +{ + unsigned int i; + + *num_descriptors = (msg->len - 2) / 3; + if (*num_descriptors > 4) + *num_descriptors = 4; + for (i = 0; i < *num_descriptors; i++) + descriptors[i] = (msg->msg[2 + i * 3] << 16) | + (msg->msg[3 + i * 3] << 8) | + msg->msg[4 + i * 3]; +} + +static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg, + bool reply, + __u8 num_descriptors, + const __u8 *audio_format_id, + const __u8 *audio_format_code) +{ + unsigned int i; + + if (num_descriptors > 4) + num_descriptors = 4; + msg->len = 2 + num_descriptors; + msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR; + msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0; + for (i = 0; i < num_descriptors; i++) + msg->msg[2 + i] = (audio_format_id[i] << 6) | + (audio_format_code[i] & 0x3f); +} + +static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg, + __u8 *num_descriptors, + __u8 *audio_format_id, + __u8 *audio_format_code) +{ + unsigned int i; + + *num_descriptors = msg->len - 2; + if (*num_descriptors > 4) + *num_descriptors = 4; + for (i = 0; i < *num_descriptors; i++) { + audio_format_id[i] = msg->msg[2 + i] >> 6; + audio_format_code[i] = msg->msg[2 + i] & 0x3f; + } +} + + +/* Audio Rate Control Feature */ +static inline void cec_msg_set_audio_rate(struct cec_msg *msg, + __u8 audio_rate) +{ + msg->len = 3; + msg->msg[1] = CEC_MSG_SET_AUDIO_RATE; + msg->msg[2] = audio_rate; +} + +static inline void cec_ops_set_audio_rate(const struct cec_msg *msg, + __u8 *audio_rate) +{ + *audio_rate = msg->msg[2]; +} + + +/* Audio Return Channel Control Feature */ +static inline void cec_msg_report_arc_initiated(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED; +} + +static inline void cec_msg_initiate_arc(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_INITIATE_ARC; + msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0; +} + +static inline void cec_msg_request_arc_initiation(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION; + msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0; +} + +static inline void cec_msg_report_arc_terminated(struct cec_msg *msg) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED; +} + +static inline void cec_msg_terminate_arc(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_TERMINATE_ARC; + msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0; +} + +static inline void cec_msg_request_arc_termination(struct cec_msg *msg, + bool reply) +{ + msg->len = 2; + msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION; + msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0; +} + + +/* Dynamic Audio Lipsync Feature */ +/* Only for CEC 2.0 and up */ +static inline void cec_msg_report_current_latency(struct cec_msg *msg, + __u16 phys_addr, + __u8 video_latency, + __u8 low_latency_mode, + __u8 audio_out_compensated, + __u8 audio_out_delay) +{ + msg->len = 7; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; + msg->msg[4] = video_latency; + msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; + msg->msg[6] = audio_out_delay; +} + +static inline void cec_ops_report_current_latency(const struct cec_msg *msg, + __u16 *phys_addr, + __u8 *video_latency, + __u8 *low_latency_mode, + __u8 *audio_out_compensated, + __u8 *audio_out_delay) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *video_latency = msg->msg[4]; + *low_latency_mode = (msg->msg[5] >> 2) & 1; + *audio_out_compensated = msg->msg[5] & 3; + *audio_out_delay = msg->msg[6]; +} + +static inline void cec_msg_request_current_latency(struct cec_msg *msg, + bool reply, + __u16 phys_addr) +{ + msg->len = 4; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY; + msg->msg[2] = phys_addr >> 8; + msg->msg[3] = phys_addr & 0xff; + msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0; +} + +static inline void cec_ops_request_current_latency(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + + +/* Capability Discovery and Control Feature */ +static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg, + __u16 phys_addr1, + __u16 phys_addr2) +{ + msg->len = 9; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; + msg->msg[5] = phys_addr1 >> 8; + msg->msg[6] = phys_addr1 & 0xff; + msg->msg[7] = phys_addr2 >> 8; + msg->msg[8] = phys_addr2 & 0xff; +} + +static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg, + __u16 *phys_addr, + __u16 *phys_addr1, + __u16 *phys_addr2) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; + *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; +} + +static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg, + __u16 target_phys_addr, + __u8 hec_func_state, + __u8 host_func_state, + __u8 enc_func_state, + __u8 cdc_errcode, + __u8 has_field, + __u16 hec_field) +{ + msg->len = has_field ? 10 : 8; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE; + msg->msg[5] = target_phys_addr >> 8; + msg->msg[6] = target_phys_addr & 0xff; + msg->msg[7] = (hec_func_state << 6) | + (host_func_state << 4) | + (enc_func_state << 2) | + cdc_errcode; + if (has_field) { + msg->msg[8] = hec_field >> 8; + msg->msg[9] = hec_field & 0xff; + } +} + +static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg, + __u16 *phys_addr, + __u16 *target_phys_addr, + __u8 *hec_func_state, + __u8 *host_func_state, + __u8 *enc_func_state, + __u8 *cdc_errcode, + __u8 *has_field, + __u16 *hec_field) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *target_phys_addr = (msg->msg[5] << 8) | msg->msg[6]; + *hec_func_state = msg->msg[7] >> 6; + *host_func_state = (msg->msg[7] >> 4) & 3; + *enc_func_state = (msg->msg[7] >> 4) & 3; + *cdc_errcode = msg->msg[7] & 3; + *has_field = msg->len >= 10; + *hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0; +} + +static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg, + __u16 phys_addr1, + __u16 phys_addr2, + __u8 hec_set_state, + __u16 phys_addr3, + __u16 phys_addr4, + __u16 phys_addr5) +{ + msg->len = 10; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; + msg->msg[5] = phys_addr1 >> 8; + msg->msg[6] = phys_addr1 & 0xff; + msg->msg[7] = phys_addr2 >> 8; + msg->msg[8] = phys_addr2 & 0xff; + msg->msg[9] = hec_set_state; + if (phys_addr3 != CEC_PHYS_ADDR_INVALID) { + msg->msg[msg->len++] = phys_addr3 >> 8; + msg->msg[msg->len++] = phys_addr3 & 0xff; + if (phys_addr4 != CEC_PHYS_ADDR_INVALID) { + msg->msg[msg->len++] = phys_addr4 >> 8; + msg->msg[msg->len++] = phys_addr4 & 0xff; + if (phys_addr5 != CEC_PHYS_ADDR_INVALID) { + msg->msg[msg->len++] = phys_addr5 >> 8; + msg->msg[msg->len++] = phys_addr5 & 0xff; + } + } + } +} + +static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg, + __u16 *phys_addr, + __u16 *phys_addr1, + __u16 *phys_addr2, + __u8 *hec_set_state, + __u16 *phys_addr3, + __u16 *phys_addr4, + __u16 *phys_addr5) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; + *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; + *hec_set_state = msg->msg[9]; + *phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID; + if (msg->len >= 12) + *phys_addr3 = (msg->msg[10] << 8) | msg->msg[11]; + if (msg->len >= 14) + *phys_addr4 = (msg->msg[12] << 8) | msg->msg[13]; + if (msg->len >= 16) + *phys_addr5 = (msg->msg[14] << 8) | msg->msg[15]; +} + +static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg, + __u16 phys_addr1, + __u8 hec_set_state) +{ + msg->len = 8; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT; + msg->msg[5] = phys_addr1 >> 8; + msg->msg[6] = phys_addr1 & 0xff; + msg->msg[7] = hec_set_state; +} + +static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg, + __u16 *phys_addr, + __u16 *phys_addr1, + __u8 *hec_set_state) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; + *hec_set_state = msg->msg[7]; +} + +static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg, + __u16 phys_addr1, + __u16 phys_addr2, + __u16 phys_addr3) +{ + msg->len = 11; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION; + msg->msg[5] = phys_addr1 >> 8; + msg->msg[6] = phys_addr1 & 0xff; + msg->msg[7] = phys_addr2 >> 8; + msg->msg[8] = phys_addr2 & 0xff; + msg->msg[9] = phys_addr3 >> 8; + msg->msg[10] = phys_addr3 & 0xff; +} + +static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg, + __u16 *phys_addr, + __u16 *phys_addr1, + __u16 *phys_addr2, + __u16 *phys_addr3) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; + *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; + *phys_addr3 = (msg->msg[9] << 8) | msg->msg[10]; +} + +static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg) +{ + msg->len = 5; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE; +} + +static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg) +{ + msg->len = 5; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER; +} + +static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg, + __u16 *phys_addr) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; +} + +static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg, + __u8 input_port, + __u8 hpd_state) +{ + msg->len = 6; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE; + msg->msg[5] = (input_port << 4) | hpd_state; +} + +static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg, + __u16 *phys_addr, + __u8 *input_port, + __u8 *hpd_state) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *input_port = msg->msg[5] >> 4; + *hpd_state = msg->msg[5] & 0xf; +} + +static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg, + __u8 hpd_state, + __u8 hpd_error) +{ + msg->len = 6; + msg->msg[0] |= 0xf; /* broadcast */ + msg->msg[1] = CEC_MSG_CDC_MESSAGE; + /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ + msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE; + msg->msg[5] = (hpd_state << 4) | hpd_error; +} + +static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg, + __u16 *phys_addr, + __u8 *hpd_state, + __u8 *hpd_error) +{ + *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; + *hpd_state = msg->msg[5] >> 4; + *hpd_error = msg->msg[5] & 0xf; +} + +#endif diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h new file mode 100644 index 000000000000..f4ec0af67707 --- /dev/null +++ b/include/uapi/linux/cec.h @@ -0,0 +1,1065 @@ +/* + * cec - HDMI Consumer Electronics Control public header + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _CEC_UAPI_H +#define _CEC_UAPI_H + +#include + +#define CEC_MAX_MSG_SIZE 16 + +/** + * struct cec_msg - CEC message structure. + * @tx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the + * driver when the message transmission has finished. + * @rx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the + * driver when the message was received. + * @len: Length in bytes of the message. + * @timeout: The timeout (in ms) that is used to timeout CEC_RECEIVE. + * Set to 0 if you want to wait forever. This timeout can also be + * used with CEC_TRANSMIT as the timeout for waiting for a reply. + * If 0, then it will use a 1 second timeout instead of waiting + * forever as is done with CEC_RECEIVE. + * @sequence: The framework assigns a sequence number to messages that are + * sent. This can be used to track replies to previously sent + * messages. + * @flags: Set to 0. + * @msg: The message payload. + * @reply: This field is ignored with CEC_RECEIVE and is only used by + * CEC_TRANSMIT. If non-zero, then wait for a reply with this + * opcode. Set to CEC_MSG_FEATURE_ABORT if you want to wait for + * a possible ABORT reply. If there was an error when sending the + * msg or FeatureAbort was returned, then reply is set to 0. + * If reply is non-zero upon return, then len/msg are set to + * the received message. + * If reply is zero upon return and status has the + * CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to + * the received feature abort message. + * If reply is zero upon return and status has the + * CEC_TX_STATUS_MAX_RETRIES bit set, then no reply was seen at + * all. If reply is non-zero for CEC_TRANSMIT and the message is a + * broadcast, then -EINVAL is returned. + * if reply is non-zero, then timeout is set to 1000 (the required + * maximum response time). + * @rx_status: The message receive status bits. Set by the driver. + * @tx_status: The message transmit status bits. Set by the driver. + * @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver. + * @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver. + * @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the + * driver. + * @tx_error_cnt: The number of 'Error' events. Set by the driver. + */ +struct cec_msg { + __u64 tx_ts; + __u64 rx_ts; + __u32 len; + __u32 timeout; + __u32 sequence; + __u32 flags; + __u8 msg[CEC_MAX_MSG_SIZE]; + __u8 reply; + __u8 rx_status; + __u8 tx_status; + __u8 tx_arb_lost_cnt; + __u8 tx_nack_cnt; + __u8 tx_low_drive_cnt; + __u8 tx_error_cnt; +}; + +/** + * cec_msg_initiator - return the initiator's logical address. + * @msg: the message structure + */ +static inline __u8 cec_msg_initiator(const struct cec_msg *msg) +{ + return msg->msg[0] >> 4; +} + +/** + * cec_msg_destination - return the destination's logical address. + * @msg: the message structure + */ +static inline __u8 cec_msg_destination(const struct cec_msg *msg) +{ + return msg->msg[0] & 0xf; +} + +/** + * cec_msg_opcode - return the opcode of the message, -1 for poll + * @msg: the message structure + */ +static inline int cec_msg_opcode(const struct cec_msg *msg) +{ + return msg->len > 1 ? msg->msg[1] : -1; +} + +/** + * cec_msg_is_broadcast - return true if this is a broadcast message. + * @msg: the message structure + */ +static inline bool cec_msg_is_broadcast(const struct cec_msg *msg) +{ + return (msg->msg[0] & 0xf) == 0xf; +} + +/** + * cec_msg_init - initialize the message structure. + * @msg: the message structure + * @initiator: the logical address of the initiator + * @destination:the logical address of the destination (0xf for broadcast) + * + * The whole structure is zeroed, the len field is set to 1 (i.e. a poll + * message) and the initiator and destination are filled in. + */ +static inline void cec_msg_init(struct cec_msg *msg, + __u8 initiator, __u8 destination) +{ + memset(msg, 0, sizeof(*msg)); + msg->msg[0] = (initiator << 4) | destination; + msg->len = 1; +} + +/** + * cec_msg_set_reply_to - fill in destination/initiator in a reply message. + * @msg: the message structure for the reply + * @orig: the original message structure + * + * Set the msg destination to the orig initiator and the msg initiator to the + * orig destination. Note that msg and orig may be the same pointer, in which + * case the change is done in place. + */ +static inline void cec_msg_set_reply_to(struct cec_msg *msg, + struct cec_msg *orig) +{ + /* The destination becomes the initiator and vice versa */ + msg->msg[0] = (cec_msg_destination(orig) << 4) | + cec_msg_initiator(orig); + msg->reply = msg->timeout = 0; +} + +/* cec_msg flags field */ +#define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0) + +/* cec_msg tx/rx_status field */ +#define CEC_TX_STATUS_OK (1 << 0) +#define CEC_TX_STATUS_ARB_LOST (1 << 1) +#define CEC_TX_STATUS_NACK (1 << 2) +#define CEC_TX_STATUS_LOW_DRIVE (1 << 3) +#define CEC_TX_STATUS_ERROR (1 << 4) +#define CEC_TX_STATUS_MAX_RETRIES (1 << 5) + +#define CEC_RX_STATUS_OK (1 << 0) +#define CEC_RX_STATUS_TIMEOUT (1 << 1) +#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2) + +static inline bool cec_msg_status_is_ok(const struct cec_msg *msg) +{ + if (msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) + return false; + if (msg->rx_status && !(msg->rx_status & CEC_RX_STATUS_OK)) + return false; + if (!msg->tx_status && !msg->rx_status) + return false; + return !(msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT); +} + +#define CEC_LOG_ADDR_INVALID 0xff +#define CEC_PHYS_ADDR_INVALID 0xffff + +/* + * The maximum number of logical addresses one device can be assigned to. + * The CEC 2.0 spec allows for only 2 logical addresses at the moment. The + * Analog Devices CEC hardware supports 3. So let's go wild and go for 4. + */ +#define CEC_MAX_LOG_ADDRS 4 + +/* The logical addresses defined by CEC 2.0 */ +#define CEC_LOG_ADDR_TV 0 +#define CEC_LOG_ADDR_RECORD_1 1 +#define CEC_LOG_ADDR_RECORD_2 2 +#define CEC_LOG_ADDR_TUNER_1 3 +#define CEC_LOG_ADDR_PLAYBACK_1 4 +#define CEC_LOG_ADDR_AUDIOSYSTEM 5 +#define CEC_LOG_ADDR_TUNER_2 6 +#define CEC_LOG_ADDR_TUNER_3 7 +#define CEC_LOG_ADDR_PLAYBACK_2 8 +#define CEC_LOG_ADDR_RECORD_3 9 +#define CEC_LOG_ADDR_TUNER_4 10 +#define CEC_LOG_ADDR_PLAYBACK_3 11 +#define CEC_LOG_ADDR_BACKUP_1 12 +#define CEC_LOG_ADDR_BACKUP_2 13 +#define CEC_LOG_ADDR_SPECIFIC 14 +#define CEC_LOG_ADDR_UNREGISTERED 15 /* as initiator address */ +#define CEC_LOG_ADDR_BROADCAST 15 /* ad destination address */ + +/* The logical address types that the CEC device wants to claim */ +#define CEC_LOG_ADDR_TYPE_TV 0 +#define CEC_LOG_ADDR_TYPE_RECORD 1 +#define CEC_LOG_ADDR_TYPE_TUNER 2 +#define CEC_LOG_ADDR_TYPE_PLAYBACK 3 +#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM 4 +#define CEC_LOG_ADDR_TYPE_SPECIFIC 5 +#define CEC_LOG_ADDR_TYPE_UNREGISTERED 6 +/* + * Switches should use UNREGISTERED. + * Processors should use SPECIFIC. + */ + +#define CEC_LOG_ADDR_MASK_TV (1 << CEC_LOG_ADDR_TV) +#define CEC_LOG_ADDR_MASK_RECORD ((1 << CEC_LOG_ADDR_RECORD_1) | \ + (1 << CEC_LOG_ADDR_RECORD_2) | \ + (1 << CEC_LOG_ADDR_RECORD_3)) +#define CEC_LOG_ADDR_MASK_TUNER ((1 << CEC_LOG_ADDR_TUNER_1) | \ + (1 << CEC_LOG_ADDR_TUNER_2) | \ + (1 << CEC_LOG_ADDR_TUNER_3) | \ + (1 << CEC_LOG_ADDR_TUNER_4)) +#define CEC_LOG_ADDR_MASK_PLAYBACK ((1 << CEC_LOG_ADDR_PLAYBACK_1) | \ + (1 << CEC_LOG_ADDR_PLAYBACK_2) | \ + (1 << CEC_LOG_ADDR_PLAYBACK_3)) +#define CEC_LOG_ADDR_MASK_AUDIOSYSTEM (1 << CEC_LOG_ADDR_AUDIOSYSTEM) +#define CEC_LOG_ADDR_MASK_BACKUP ((1 << CEC_LOG_ADDR_BACKUP_1) | \ + (1 << CEC_LOG_ADDR_BACKUP_2)) +#define CEC_LOG_ADDR_MASK_SPECIFIC (1 << CEC_LOG_ADDR_SPECIFIC) +#define CEC_LOG_ADDR_MASK_UNREGISTERED (1 << CEC_LOG_ADDR_UNREGISTERED) + +static inline bool cec_has_tv(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_TV; +} + +static inline bool cec_has_record(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_RECORD; +} + +static inline bool cec_has_tuner(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_TUNER; +} + +static inline bool cec_has_playback(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_PLAYBACK; +} + +static inline bool cec_has_audiosystem(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_AUDIOSYSTEM; +} + +static inline bool cec_has_backup(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_BACKUP; +} + +static inline bool cec_has_specific(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_SPECIFIC; +} + +static inline bool cec_is_unregistered(__u16 log_addr_mask) +{ + return log_addr_mask & CEC_LOG_ADDR_MASK_UNREGISTERED; +} + +static inline bool cec_is_unconfigured(__u16 log_addr_mask) +{ + return log_addr_mask == 0; +} + +/* + * Use this if there is no vendor ID (CEC_G_VENDOR_ID) or if the vendor ID + * should be disabled (CEC_S_VENDOR_ID) + */ +#define CEC_VENDOR_ID_NONE 0xffffffff + +/* The message handling modes */ +/* Modes for initiator */ +#define CEC_MODE_NO_INITIATOR (0x0 << 0) +#define CEC_MODE_INITIATOR (0x1 << 0) +#define CEC_MODE_EXCL_INITIATOR (0x2 << 0) +#define CEC_MODE_INITIATOR_MSK 0x0f + +/* Modes for follower */ +#define CEC_MODE_NO_FOLLOWER (0x0 << 4) +#define CEC_MODE_FOLLOWER (0x1 << 4) +#define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) +#define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4) +#define CEC_MODE_MONITOR (0xe << 4) +#define CEC_MODE_MONITOR_ALL (0xf << 4) +#define CEC_MODE_FOLLOWER_MSK 0xf0 + +/* Userspace has to configure the physical address */ +#define CEC_CAP_PHYS_ADDR (1 << 0) +/* Userspace has to configure the logical addresses */ +#define CEC_CAP_LOG_ADDRS (1 << 1) +/* Userspace can transmit messages (and thus become follower as well) */ +#define CEC_CAP_TRANSMIT (1 << 2) +/* + * Passthrough all messages instead of processing them. + */ +#define CEC_CAP_PASSTHROUGH (1 << 3) +/* Supports remote control */ +#define CEC_CAP_RC (1 << 4) +/* Hardware can monitor all messages, not just directed and broadcast. */ +#define CEC_CAP_MONITOR_ALL (1 << 5) + +/** + * struct cec_caps - CEC capabilities structure. + * @driver: name of the CEC device driver. + * @name: name of the CEC device. @driver + @name must be unique. + * @available_log_addrs: number of available logical addresses. + * @capabilities: capabilities of the CEC adapter. + * @version: version of the CEC adapter framework. + */ +struct cec_caps { + char driver[32]; + char name[32]; + __u32 available_log_addrs; + __u32 capabilities; + __u32 version; +}; + +/** + * struct cec_log_addrs - CEC logical addresses structure. + * @log_addr: the claimed logical addresses. Set by the driver. + * @log_addr_mask: current logical address mask. Set by the driver. + * @cec_version: the CEC version that the adapter should implement. Set by the + * caller. + * @num_log_addrs: how many logical addresses should be claimed. Set by the + * caller. + * @vendor_id: the vendor ID of the device. Set by the caller. + * @flags: flags. + * @osd_name: the OSD name of the device. Set by the caller. + * @primary_device_type: the primary device type for each logical address. + * Set by the caller. + * @log_addr_type: the logical address types. Set by the caller. + * @all_device_types: CEC 2.0: all device types represented by the logical + * address. Set by the caller. + * @features: CEC 2.0: The logical address features. Set by the caller. + */ +struct cec_log_addrs { + __u8 log_addr[CEC_MAX_LOG_ADDRS]; + __u16 log_addr_mask; + __u8 cec_version; + __u8 num_log_addrs; + __u32 vendor_id; + __u32 flags; + char osd_name[15]; + __u8 primary_device_type[CEC_MAX_LOG_ADDRS]; + __u8 log_addr_type[CEC_MAX_LOG_ADDRS]; + + /* CEC 2.0 */ + __u8 all_device_types[CEC_MAX_LOG_ADDRS]; + __u8 features[CEC_MAX_LOG_ADDRS][12]; +}; + +/* Allow a fallback to unregistered */ +#define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) +/* Passthrough RC messages to the input subsystem */ +#define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1) +/* CDC-Only device: supports only CDC messages */ +#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2) + +/* Events */ + +/* Event that occurs when the adapter state changes */ +#define CEC_EVENT_STATE_CHANGE 1 +/* + * This event is sent when messages are lost because the application + * didn't empty the message queue in time + */ +#define CEC_EVENT_LOST_MSGS 2 + +#define CEC_EVENT_FL_INITIAL_STATE (1 << 0) + +/** + * struct cec_event_state_change - used when the CEC adapter changes state. + * @phys_addr: the current physical address + * @log_addr_mask: the current logical address mask + */ +struct cec_event_state_change { + __u16 phys_addr; + __u16 log_addr_mask; +}; + +/** + * struct cec_event_lost_msgs - tells you how many messages were lost due. + * @lost_msgs: how many messages were lost. + */ +struct cec_event_lost_msgs { + __u32 lost_msgs; +}; + +/** + * struct cec_event - CEC event structure + * @ts: the timestamp of when the event was sent. + * @event: the event. + * array. + * @state_change: the event payload for CEC_EVENT_STATE_CHANGE. + * @lost_msgs: the event payload for CEC_EVENT_LOST_MSGS. + * @raw: array to pad the union. + */ +struct cec_event { + __u64 ts; + __u32 event; + __u32 flags; + union { + struct cec_event_state_change state_change; + struct cec_event_lost_msgs lost_msgs; + __u32 raw[16]; + }; +}; + +/* ioctls */ + +/* Adapter capabilities */ +#define CEC_ADAP_G_CAPS _IOWR('a', 0, struct cec_caps) + +/* + * phys_addr is either 0 (if this is the CEC root device) + * or a valid physical address obtained from the sink's EDID + * as read by this CEC device (if this is a source device) + * or a physical address obtained and modified from a sink + * EDID and used for a sink CEC device. + * If nothing is connected, then phys_addr is 0xffff. + * See HDMI 1.4b, section 8.7 (Physical Address). + * + * The CEC_ADAP_S_PHYS_ADDR ioctl may not be available if that is handled + * internally. + */ +#define CEC_ADAP_G_PHYS_ADDR _IOR('a', 1, __u16) +#define CEC_ADAP_S_PHYS_ADDR _IOW('a', 2, __u16) + +/* + * Configure the CEC adapter. It sets the device type and which + * logical types it will try to claim. It will return which + * logical addresses it could actually claim. + * An error is returned if the adapter is disabled or if there + * is no physical address assigned. + */ + +#define CEC_ADAP_G_LOG_ADDRS _IOR('a', 3, struct cec_log_addrs) +#define CEC_ADAP_S_LOG_ADDRS _IOWR('a', 4, struct cec_log_addrs) + +/* Transmit/receive a CEC command */ +#define CEC_TRANSMIT _IOWR('a', 5, struct cec_msg) +#define CEC_RECEIVE _IOWR('a', 6, struct cec_msg) + +/* Dequeue CEC events */ +#define CEC_DQEVENT _IOWR('a', 7, struct cec_event) + +/* + * Get and set the message handling mode for this filehandle. + */ +#define CEC_G_MODE _IOR('a', 8, __u32) +#define CEC_S_MODE _IOW('a', 9, __u32) + +/* + * The remainder of this header defines all CEC messages and operands. + * The format matters since it the cec-ctl utility parses it to generate + * code for implementing all these messages. + * + * Comments ending with 'Feature' group messages for each feature. + * If messages are part of multiple features, then the "Has also" + * comment is used to list the previously defined messages that are + * supported by the feature. + * + * Before operands are defined a comment is added that gives the + * name of the operand and in brackets the variable name of the + * corresponding argument in the cec-funcs.h function. + */ + +/* Messages */ + +/* One Touch Play Feature */ +#define CEC_MSG_ACTIVE_SOURCE 0x82 +#define CEC_MSG_IMAGE_VIEW_ON 0x04 +#define CEC_MSG_TEXT_VIEW_ON 0x0d + + +/* Routing Control Feature */ + +/* + * Has also: + * CEC_MSG_ACTIVE_SOURCE + */ + +#define CEC_MSG_INACTIVE_SOURCE 0x9d +#define CEC_MSG_REQUEST_ACTIVE_SOURCE 0x85 +#define CEC_MSG_ROUTING_CHANGE 0x80 +#define CEC_MSG_ROUTING_INFORMATION 0x81 +#define CEC_MSG_SET_STREAM_PATH 0x86 + + +/* Standby Feature */ +#define CEC_MSG_STANDBY 0x36 + + +/* One Touch Record Feature */ +#define CEC_MSG_RECORD_OFF 0x0b +#define CEC_MSG_RECORD_ON 0x09 +/* Record Source Type Operand (rec_src_type) */ +#define CEC_OP_RECORD_SRC_OWN 1 +#define CEC_OP_RECORD_SRC_DIGITAL 2 +#define CEC_OP_RECORD_SRC_ANALOG 3 +#define CEC_OP_RECORD_SRC_EXT_PLUG 4 +#define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR 5 +/* Service Identification Method Operand (service_id_method) */ +#define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID 0 +#define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL 1 +/* Digital Service Broadcast System Operand (dig_bcast_system) */ +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN 0x00 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN 0x01 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN 0x02 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS 0x08 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS 0x09 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T 0x0a +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE 0x10 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT 0x11 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T 0x12 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C 0x18 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S 0x19 +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2 0x1a +#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T 0x1b +/* Analogue Broadcast Type Operand (ana_bcast_type) */ +#define CEC_OP_ANA_BCAST_TYPE_CABLE 0 +#define CEC_OP_ANA_BCAST_TYPE_SATELLITE 1 +#define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL 2 +/* Broadcast System Operand (bcast_system) */ +#define CEC_OP_BCAST_SYSTEM_PAL_BG 0x00 +#define CEC_OP_BCAST_SYSTEM_SECAM_LQ 0x01 /* SECAM L' */ +#define CEC_OP_BCAST_SYSTEM_PAL_M 0x02 +#define CEC_OP_BCAST_SYSTEM_NTSC_M 0x03 +#define CEC_OP_BCAST_SYSTEM_PAL_I 0x04 +#define CEC_OP_BCAST_SYSTEM_SECAM_DK 0x05 +#define CEC_OP_BCAST_SYSTEM_SECAM_BG 0x06 +#define CEC_OP_BCAST_SYSTEM_SECAM_L 0x07 +#define CEC_OP_BCAST_SYSTEM_PAL_DK 0x08 +#define CEC_OP_BCAST_SYSTEM_OTHER 0x1f +/* Channel Number Format Operand (channel_number_fmt) */ +#define CEC_OP_CHANNEL_NUMBER_FMT_1_PART 0x01 +#define CEC_OP_CHANNEL_NUMBER_FMT_2_PART 0x02 + +#define CEC_MSG_RECORD_STATUS 0x0a +/* Record Status Operand (rec_status) */ +#define CEC_OP_RECORD_STATUS_CUR_SRC 0x01 +#define CEC_OP_RECORD_STATUS_DIG_SERVICE 0x02 +#define CEC_OP_RECORD_STATUS_ANA_SERVICE 0x03 +#define CEC_OP_RECORD_STATUS_EXT_INPUT 0x04 +#define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE 0x05 +#define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE 0x06 +#define CEC_OP_RECORD_STATUS_NO_SERVICE 0x07 +#define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG 0x09 +#define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR 0x0a +#define CEC_OP_RECORD_STATUS_UNSUP_CA 0x0b +#define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS 0x0c +#define CEC_OP_RECORD_STATUS_CANT_COPY_SRC 0x0d +#define CEC_OP_RECORD_STATUS_NO_MORE_COPIES 0x0e +#define CEC_OP_RECORD_STATUS_NO_MEDIA 0x10 +#define CEC_OP_RECORD_STATUS_PLAYING 0x11 +#define CEC_OP_RECORD_STATUS_ALREADY_RECORDING 0x12 +#define CEC_OP_RECORD_STATUS_MEDIA_PROT 0x13 +#define CEC_OP_RECORD_STATUS_NO_SIGNAL 0x14 +#define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM 0x15 +#define CEC_OP_RECORD_STATUS_NO_SPACE 0x16 +#define CEC_OP_RECORD_STATUS_PARENTAL_LOCK 0x17 +#define CEC_OP_RECORD_STATUS_TERMINATED_OK 0x1a +#define CEC_OP_RECORD_STATUS_ALREADY_TERM 0x1b +#define CEC_OP_RECORD_STATUS_OTHER 0x1f + +#define CEC_MSG_RECORD_TV_SCREEN 0x0f + + +/* Timer Programming Feature */ +#define CEC_MSG_CLEAR_ANALOGUE_TIMER 0x33 +/* Recording Sequence Operand (recording_seq) */ +#define CEC_OP_REC_SEQ_SUNDAY 0x01 +#define CEC_OP_REC_SEQ_MONDAY 0x02 +#define CEC_OP_REC_SEQ_TUESDAY 0x04 +#define CEC_OP_REC_SEQ_WEDNESDAY 0x08 +#define CEC_OP_REC_SEQ_THURSDAY 0x10 +#define CEC_OP_REC_SEQ_FRIDAY 0x20 +#define CEC_OP_REC_SEQ_SATERDAY 0x40 +#define CEC_OP_REC_SEQ_ONCE_ONLY 0x00 + +#define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99 + +#define CEC_MSG_CLEAR_EXT_TIMER 0xa1 +/* External Source Specifier Operand (ext_src_spec) */ +#define CEC_OP_EXT_SRC_PLUG 0x04 +#define CEC_OP_EXT_SRC_PHYS_ADDR 0x05 + +#define CEC_MSG_SET_ANALOGUE_TIMER 0x34 +#define CEC_MSG_SET_DIGITAL_TIMER 0x97 +#define CEC_MSG_SET_EXT_TIMER 0xa2 + +#define CEC_MSG_SET_TIMER_PROGRAM_TITLE 0x67 +#define CEC_MSG_TIMER_CLEARED_STATUS 0x43 +/* Timer Cleared Status Data Operand (timer_cleared_status) */ +#define CEC_OP_TIMER_CLR_STAT_RECORDING 0x00 +#define CEC_OP_TIMER_CLR_STAT_NO_MATCHING 0x01 +#define CEC_OP_TIMER_CLR_STAT_NO_INFO 0x02 +#define CEC_OP_TIMER_CLR_STAT_CLEARED 0x80 + +#define CEC_MSG_TIMER_STATUS 0x35 +/* Timer Overlap Warning Operand (timer_overlap_warning) */ +#define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP 0 +#define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP 1 +/* Media Info Operand (media_info) */ +#define CEC_OP_MEDIA_INFO_UNPROT_MEDIA 0 +#define CEC_OP_MEDIA_INFO_PROT_MEDIA 1 +#define CEC_OP_MEDIA_INFO_NO_MEDIA 2 +/* Programmed Indicator Operand (prog_indicator) */ +#define CEC_OP_PROG_IND_NOT_PROGRAMMED 0 +#define CEC_OP_PROG_IND_PROGRAMMED 1 +/* Programmed Info Operand (prog_info) */ +#define CEC_OP_PROG_INFO_ENOUGH_SPACE 0x08 +#define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE 0x09 +#define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE 0x0b +#define CEC_OP_PROG_INFO_NONE_AVAILABLE 0x0a +/* Not Programmed Error Info Operand (prog_error) */ +#define CEC_OP_PROG_ERROR_NO_FREE_TIMER 0x01 +#define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE 0x02 +#define CEC_OP_PROG_ERROR_REC_SEQ_ERROR 0x03 +#define CEC_OP_PROG_ERROR_INV_EXT_PLUG 0x04 +#define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR 0x05 +#define CEC_OP_PROG_ERROR_CA_UNSUPP 0x06 +#define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS 0x07 +#define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP 0x08 +#define CEC_OP_PROG_ERROR_PARENTAL_LOCK 0x09 +#define CEC_OP_PROG_ERROR_CLOCK_FAILURE 0x0a +#define CEC_OP_PROG_ERROR_DUPLICATE 0x0e + + +/* System Information Feature */ +#define CEC_MSG_CEC_VERSION 0x9e +/* CEC Version Operand (cec_version) */ +#define CEC_OP_CEC_VERSION_1_3A 4 +#define CEC_OP_CEC_VERSION_1_4 5 +#define CEC_OP_CEC_VERSION_2_0 6 + +#define CEC_MSG_GET_CEC_VERSION 0x9f +#define CEC_MSG_GIVE_PHYSICAL_ADDR 0x83 +#define CEC_MSG_GET_MENU_LANGUAGE 0x91 +#define CEC_MSG_REPORT_PHYSICAL_ADDR 0x84 +/* Primary Device Type Operand (prim_devtype) */ +#define CEC_OP_PRIM_DEVTYPE_TV 0 +#define CEC_OP_PRIM_DEVTYPE_RECORD 1 +#define CEC_OP_PRIM_DEVTYPE_TUNER 3 +#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4 +#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5 +#define CEC_OP_PRIM_DEVTYPE_SWITCH 6 +#define CEC_OP_PRIM_DEVTYPE_PROCESSOR 7 + +#define CEC_MSG_SET_MENU_LANGUAGE 0x32 +#define CEC_MSG_REPORT_FEATURES 0xa6 /* HDMI 2.0 */ +/* All Device Types Operand (all_device_types) */ +#define CEC_OP_ALL_DEVTYPE_TV 0x80 +#define CEC_OP_ALL_DEVTYPE_RECORD 0x40 +#define CEC_OP_ALL_DEVTYPE_TUNER 0x20 +#define CEC_OP_ALL_DEVTYPE_PLAYBACK 0x10 +#define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM 0x08 +#define CEC_OP_ALL_DEVTYPE_SWITCH 0x04 +/* + * And if you wondering what happened to PROCESSOR devices: those should + * be mapped to a SWITCH. + */ + +/* Valid for RC Profile and Device Feature operands */ +#define CEC_OP_FEAT_EXT 0x80 /* Extension bit */ +/* RC Profile Operand (rc_profile) */ +#define CEC_OP_FEAT_RC_TV_PROFILE_NONE 0x00 +#define CEC_OP_FEAT_RC_TV_PROFILE_1 0x02 +#define CEC_OP_FEAT_RC_TV_PROFILE_2 0x06 +#define CEC_OP_FEAT_RC_TV_PROFILE_3 0x0a +#define CEC_OP_FEAT_RC_TV_PROFILE_4 0x0e +#define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU 0x50 +#define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU 0x48 +#define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU 0x44 +#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU 0x42 +#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU 0x41 +/* Device Feature Operand (dev_features) */ +#define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN 0x40 +#define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING 0x20 +#define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL 0x10 +#define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08 +#define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04 +#define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02 + +#define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */ + + +/* Deck Control Feature */ +#define CEC_MSG_DECK_CONTROL 0x42 +/* Deck Control Mode Operand (deck_control_mode) */ +#define CEC_OP_DECK_CTL_MODE_SKIP_FWD 1 +#define CEC_OP_DECK_CTL_MODE_SKIP_REV 2 +#define CEC_OP_DECK_CTL_MODE_STOP 3 +#define CEC_OP_DECK_CTL_MODE_EJECT 4 + +#define CEC_MSG_DECK_STATUS 0x1b +/* Deck Info Operand (deck_info) */ +#define CEC_OP_DECK_INFO_PLAY 0x11 +#define CEC_OP_DECK_INFO_RECORD 0x12 +#define CEC_OP_DECK_INFO_PLAY_REV 0x13 +#define CEC_OP_DECK_INFO_STILL 0x14 +#define CEC_OP_DECK_INFO_SLOW 0x15 +#define CEC_OP_DECK_INFO_SLOW_REV 0x16 +#define CEC_OP_DECK_INFO_FAST_FWD 0x17 +#define CEC_OP_DECK_INFO_FAST_REV 0x18 +#define CEC_OP_DECK_INFO_NO_MEDIA 0x19 +#define CEC_OP_DECK_INFO_STOP 0x1a +#define CEC_OP_DECK_INFO_SKIP_FWD 0x1b +#define CEC_OP_DECK_INFO_SKIP_REV 0x1c +#define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD 0x1d +#define CEC_OP_DECK_INFO_INDEX_SEARCH_REV 0x1e +#define CEC_OP_DECK_INFO_OTHER 0x1f + +#define CEC_MSG_GIVE_DECK_STATUS 0x1a +/* Status Request Operand (status_req) */ +#define CEC_OP_STATUS_REQ_ON 1 +#define CEC_OP_STATUS_REQ_OFF 2 +#define CEC_OP_STATUS_REQ_ONCE 3 + +#define CEC_MSG_PLAY 0x41 +/* Play Mode Operand (play_mode) */ +#define CEC_OP_PLAY_MODE_PLAY_FWD 0x24 +#define CEC_OP_PLAY_MODE_PLAY_REV 0x20 +#define CEC_OP_PLAY_MODE_PLAY_STILL 0x25 +#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN 0x05 +#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED 0x06 +#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX 0x07 +#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN 0x09 +#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED 0x0a +#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX 0x0b +#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN 0x15 +#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED 0x16 +#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX 0x17 +#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN 0x19 +#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED 0x1a +#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX 0x1b + + +/* Tuner Control Feature */ +#define CEC_MSG_GIVE_TUNER_DEVICE_STATUS 0x08 +#define CEC_MSG_SELECT_ANALOGUE_SERVICE 0x92 +#define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93 +#define CEC_MSG_TUNER_DEVICE_STATUS 0x07 +/* Recording Flag Operand (rec_flag) */ +#define CEC_OP_REC_FLAG_USED 0 +#define CEC_OP_REC_FLAG_NOT_USED 1 +/* Tuner Display Info Operand (tuner_display_info) */ +#define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0 +#define CEC_OP_TUNER_DISPLAY_INFO_NONE 1 +#define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE 2 + +#define CEC_MSG_TUNER_STEP_DECREMENT 0x06 +#define CEC_MSG_TUNER_STEP_INCREMENT 0x05 + + +/* Vendor Specific Commands Feature */ + +/* + * Has also: + * CEC_MSG_CEC_VERSION + * CEC_MSG_GET_CEC_VERSION + */ +#define CEC_MSG_DEVICE_VENDOR_ID 0x87 +#define CEC_MSG_GIVE_DEVICE_VENDOR_ID 0x8c +#define CEC_MSG_VENDOR_COMMAND 0x89 +#define CEC_MSG_VENDOR_COMMAND_WITH_ID 0xa0 +#define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN 0x8a +#define CEC_MSG_VENDOR_REMOTE_BUTTON_UP 0x8b + + +/* OSD Display Feature */ +#define CEC_MSG_SET_OSD_STRING 0x64 +/* Display Control Operand (disp_ctl) */ +#define CEC_OP_DISP_CTL_DEFAULT 0x00 +#define CEC_OP_DISP_CTL_UNTIL_CLEARED 0x40 +#define CEC_OP_DISP_CTL_CLEAR 0x80 + + +/* Device OSD Transfer Feature */ +#define CEC_MSG_GIVE_OSD_NAME 0x46 +#define CEC_MSG_SET_OSD_NAME 0x47 + + +/* Device Menu Control Feature */ +#define CEC_MSG_MENU_REQUEST 0x8d +/* Menu Request Type Operand (menu_req) */ +#define CEC_OP_MENU_REQUEST_ACTIVATE 0x00 +#define CEC_OP_MENU_REQUEST_DEACTIVATE 0x01 +#define CEC_OP_MENU_REQUEST_QUERY 0x02 + +#define CEC_MSG_MENU_STATUS 0x8e +/* Menu State Operand (menu_state) */ +#define CEC_OP_MENU_STATE_ACTIVATED 0x00 +#define CEC_OP_MENU_STATE_DEACTIVATED 0x01 + +#define CEC_MSG_USER_CONTROL_PRESSED 0x44 +/* UI Broadcast Type Operand (ui_bcast_type) */ +#define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL 0x00 +#define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA 0x01 +#define CEC_OP_UI_BCAST_TYPE_ANALOGUE 0x10 +#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T 0x20 +#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE 0x30 +#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT 0x40 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL 0x50 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL_T 0x60 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE 0x70 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT 0x80 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT 0x90 +#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2 0x91 +#define CEC_OP_UI_BCAST_TYPE_IP 0xa0 +/* UI Sound Presentation Control Operand (ui_snd_pres_ctl) */ +#define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO 0x10 +#define CEC_OP_UI_SND_PRES_CTL_KARAOKE 0x20 +#define CEC_OP_UI_SND_PRES_CTL_DOWNMIX 0x80 +#define CEC_OP_UI_SND_PRES_CTL_REVERB 0x90 +#define CEC_OP_UI_SND_PRES_CTL_EQUALIZER 0xa0 +#define CEC_OP_UI_SND_PRES_CTL_BASS_UP 0xb1 +#define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL 0xb2 +#define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN 0xb3 +#define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP 0xc1 +#define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL 0xc2 +#define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN 0xc3 + +#define CEC_MSG_USER_CONTROL_RELEASED 0x45 + + +/* Remote Control Passthrough Feature */ + +/* + * Has also: + * CEC_MSG_USER_CONTROL_PRESSED + * CEC_MSG_USER_CONTROL_RELEASED + */ + + +/* Power Status Feature */ +#define CEC_MSG_GIVE_DEVICE_POWER_STATUS 0x8f +#define CEC_MSG_REPORT_POWER_STATUS 0x90 +/* Power Status Operand (pwr_state) */ +#define CEC_OP_POWER_STATUS_ON 0 +#define CEC_OP_POWER_STATUS_STANDBY 1 +#define CEC_OP_POWER_STATUS_TO_ON 2 +#define CEC_OP_POWER_STATUS_TO_STANDBY 3 + + +/* General Protocol Messages */ +#define CEC_MSG_FEATURE_ABORT 0x00 +/* Abort Reason Operand (reason) */ +#define CEC_OP_ABORT_UNRECOGNIZED_OP 0 +#define CEC_OP_ABORT_INCORRECT_MODE 1 +#define CEC_OP_ABORT_NO_SOURCE 2 +#define CEC_OP_ABORT_INVALID_OP 3 +#define CEC_OP_ABORT_REFUSED 4 +#define CEC_OP_ABORT_UNDETERMINED 5 + +#define CEC_MSG_ABORT 0xff + + +/* System Audio Control Feature */ + +/* + * Has also: + * CEC_MSG_USER_CONTROL_PRESSED + * CEC_MSG_USER_CONTROL_RELEASED + */ +#define CEC_MSG_GIVE_AUDIO_STATUS 0x71 +#define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7d +#define CEC_MSG_REPORT_AUDIO_STATUS 0x7a +/* Audio Mute Status Operand (aud_mute_status) */ +#define CEC_OP_AUD_MUTE_STATUS_OFF 0 +#define CEC_OP_AUD_MUTE_STATUS_ON 1 + +#define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR 0xa3 +#define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR 0xa4 +#define CEC_MSG_SET_SYSTEM_AUDIO_MODE 0x72 +/* System Audio Status Operand (sys_aud_status) */ +#define CEC_OP_SYS_AUD_STATUS_OFF 0 +#define CEC_OP_SYS_AUD_STATUS_ON 1 + +#define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 0x70 +#define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 0x7e +/* Audio Format ID Operand (audio_format_id) */ +#define CEC_OP_AUD_FMT_ID_CEA861 0 +#define CEC_OP_AUD_FMT_ID_CEA861_CXT 1 + + +/* Audio Rate Control Feature */ +#define CEC_MSG_SET_AUDIO_RATE 0x9a +/* Audio Rate Operand (audio_rate) */ +#define CEC_OP_AUD_RATE_OFF 0 +#define CEC_OP_AUD_RATE_WIDE_STD 1 +#define CEC_OP_AUD_RATE_WIDE_FAST 2 +#define CEC_OP_AUD_RATE_WIDE_SLOW 3 +#define CEC_OP_AUD_RATE_NARROW_STD 4 +#define CEC_OP_AUD_RATE_NARROW_FAST 5 +#define CEC_OP_AUD_RATE_NARROW_SLOW 6 + + +/* Audio Return Channel Control Feature */ +#define CEC_MSG_INITIATE_ARC 0xc0 +#define CEC_MSG_REPORT_ARC_INITIATED 0xc1 +#define CEC_MSG_REPORT_ARC_TERMINATED 0xc2 +#define CEC_MSG_REQUEST_ARC_INITIATION 0xc3 +#define CEC_MSG_REQUEST_ARC_TERMINATION 0xc4 +#define CEC_MSG_TERMINATE_ARC 0xc5 + + +/* Dynamic Audio Lipsync Feature */ +/* Only for CEC 2.0 and up */ +#define CEC_MSG_REQUEST_CURRENT_LATENCY 0xa7 +#define CEC_MSG_REPORT_CURRENT_LATENCY 0xa8 +/* Low Latency Mode Operand (low_latency_mode) */ +#define CEC_OP_LOW_LATENCY_MODE_OFF 0 +#define CEC_OP_LOW_LATENCY_MODE_ON 1 +/* Audio Output Compensated Operand (audio_out_compensated) */ +#define CEC_OP_AUD_OUT_COMPENSATED_NA 0 +#define CEC_OP_AUD_OUT_COMPENSATED_DELAY 1 +#define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY 2 +#define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY 3 + + +/* Capability Discovery and Control Feature */ +#define CEC_MSG_CDC_MESSAGE 0xf8 +/* Ethernet-over-HDMI: nobody ever does this... */ +#define CEC_MSG_CDC_HEC_INQUIRE_STATE 0x00 +#define CEC_MSG_CDC_HEC_REPORT_STATE 0x01 +/* HEC Functionality State Operand (hec_func_state) */ +#define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED 0 +#define CEC_OP_HEC_FUNC_STATE_INACTIVE 1 +#define CEC_OP_HEC_FUNC_STATE_ACTIVE 2 +#define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD 3 +/* Host Functionality State Operand (host_func_state) */ +#define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED 0 +#define CEC_OP_HOST_FUNC_STATE_INACTIVE 1 +#define CEC_OP_HOST_FUNC_STATE_ACTIVE 2 +/* ENC Functionality State Operand (enc_func_state) */ +#define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED 0 +#define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE 1 +#define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE 2 +/* CDC Error Code Operand (cdc_errcode) */ +#define CEC_OP_CDC_ERROR_CODE_NONE 0 +#define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED 1 +#define CEC_OP_CDC_ERROR_CODE_WRONG_STATE 2 +#define CEC_OP_CDC_ERROR_CODE_OTHER 3 +/* HEC Support Operand (hec_support) */ +#define CEC_OP_HEC_SUPPORT_NO 0 +#define CEC_OP_HEC_SUPPORT_YES 1 +/* HEC Activation Operand (hec_activation) */ +#define CEC_OP_HEC_ACTIVATION_ON 0 +#define CEC_OP_HEC_ACTIVATION_OFF 1 + +#define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT 0x02 +#define CEC_MSG_CDC_HEC_SET_STATE 0x03 +/* HEC Set State Operand (hec_set_state) */ +#define CEC_OP_HEC_SET_STATE_DEACTIVATE 0 +#define CEC_OP_HEC_SET_STATE_ACTIVATE 1 + +#define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION 0x04 +#define CEC_MSG_CDC_HEC_NOTIFY_ALIVE 0x05 +#define CEC_MSG_CDC_HEC_DISCOVER 0x06 +/* Hotplug Detect messages */ +#define CEC_MSG_CDC_HPD_SET_STATE 0x10 +/* HPD State Operand (hpd_state) */ +#define CEC_OP_HPD_STATE_CP_EDID_DISABLE 0 +#define CEC_OP_HPD_STATE_CP_EDID_ENABLE 1 +#define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE 2 +#define CEC_OP_HPD_STATE_EDID_DISABLE 3 +#define CEC_OP_HPD_STATE_EDID_ENABLE 4 +#define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE 5 +#define CEC_MSG_CDC_HPD_REPORT_STATE 0x11 +/* HPD Error Code Operand (hpd_error) */ +#define CEC_OP_HPD_ERROR_NONE 0 +#define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE 1 +#define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE 2 +#define CEC_OP_HPD_ERROR_OTHER 3 +#define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 4 + +/* End of Messages */ + +/* Helper functions to identify the 'special' CEC devices */ + +static inline bool cec_is_2nd_tv(const struct cec_log_addrs *las) +{ + /* + * It is a second TV if the logical address is 14 or 15 and the + * primary device type is a TV. + */ + return las->num_log_addrs && + las->log_addr[0] >= CEC_LOG_ADDR_SPECIFIC && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_TV; +} + +static inline bool cec_is_processor(const struct cec_log_addrs *las) +{ + /* + * It is a processor if the logical address is 12-15 and the + * primary device type is a Processor. + */ + return las->num_log_addrs && + las->log_addr[0] >= CEC_LOG_ADDR_BACKUP_1 && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_PROCESSOR; +} + +static inline bool cec_is_switch(const struct cec_log_addrs *las) +{ + /* + * It is a switch if the logical address is 15 and the + * primary device type is a Switch and the CDC-Only flag is not set. + */ + return las->num_log_addrs == 1 && + las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && + !(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); +} + +static inline bool cec_is_cdc_only(const struct cec_log_addrs *las) +{ + /* + * It is a CDC-only device if the logical address is 15 and the + * primary device type is a Switch and the CDC-Only flag is set. + */ + return las->num_log_addrs == 1 && + las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && + las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && + (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); +} + +#endif -- cgit v1.2.3 From 7ae2a888eedd5a6b03849614eddd55f31793eeae Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Nov 2016 07:52:11 -0200 Subject: [media] cec: sanitize msg.flags The CEC_MSG_FL_REPLY_TO_FOLLOWERS message flag only makes sense for transmitted messages where you want to wait for the reply. Clear the flag in all other cases. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 4 ++++ drivers/media/cec/cec-api.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 054cd06e2247..bcd19d41c166 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -595,6 +595,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, /* Make sure the timeout isn't 0. */ msg->timeout = 1000; } + if (msg->timeout) + msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; + else + msg->flags = 0; /* Sanity checks */ if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index d4bc4ee2c6e5..597fbb62d829 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -197,7 +197,6 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE)) return -EINVAL; - msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; mutex_lock(&adap->lock); if (!adap->is_configured) err = -ENONET; @@ -282,6 +281,7 @@ static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh, err = cec_receive_msg(fh, &msg, block); if (err) return err; + msg.flags = 0; if (copy_to_user(parg, &msg, sizeof(msg))) return -EFAULT; return 0; -- cgit v1.2.3 From 3145c754aca8182b4cfe301b3cfe6dc8f2cb499c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Nov 2016 08:23:27 -0200 Subject: [media] cec.h/cec-funcs.h: don't use bool in public headers Replace bool by int or __u8 (when used in a struct). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/cec-funcs.h | 70 +++++++++++++++++++++--------------------- include/uapi/linux/cec.h | 37 +++++++++++----------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h index 1a1de2169f48..3cbc327801d6 100644 --- a/include/uapi/linux/cec-funcs.h +++ b/include/uapi/linux/cec-funcs.h @@ -84,7 +84,7 @@ static inline void cec_ops_inactive_source(const struct cec_msg *msg, } static inline void cec_msg_request_active_source(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[0] |= 0xf; /* broadcast */ @@ -109,7 +109,7 @@ static inline void cec_ops_routing_information(const struct cec_msg *msg, } static inline void cec_msg_routing_change(struct cec_msg *msg, - bool reply, + int reply, __u16 orig_phys_addr, __u16 new_phys_addr) { @@ -156,7 +156,7 @@ static inline void cec_msg_standby(struct cec_msg *msg) /* One Touch Record Feature */ -static inline void cec_msg_record_off(struct cec_msg *msg, bool reply) +static inline void cec_msg_record_off(struct cec_msg *msg, int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_RECORD_OFF; @@ -318,7 +318,7 @@ static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg, } static inline void cec_msg_record_on(struct cec_msg *msg, - bool reply, + int reply, const struct cec_op_record_src *rec_src) { switch (rec_src->type) { @@ -385,7 +385,7 @@ static inline void cec_ops_record_status(const struct cec_msg *msg, } static inline void cec_msg_record_tv_screen(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN; @@ -459,7 +459,7 @@ static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg, } static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -514,7 +514,7 @@ static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg, } static inline void cec_msg_clear_digital_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -560,7 +560,7 @@ static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg, } static inline void cec_msg_clear_ext_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -615,7 +615,7 @@ static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg, } static inline void cec_msg_set_analogue_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -670,7 +670,7 @@ static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg, } static inline void cec_msg_set_digital_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -716,7 +716,7 @@ static inline void cec_ops_set_digital_timer(const struct cec_msg *msg, } static inline void cec_msg_set_ext_timer(struct cec_msg *msg, - bool reply, + int reply, __u8 day, __u8 month, __u8 start_hr, @@ -808,7 +808,7 @@ static inline void cec_ops_cec_version(const struct cec_msg *msg, } static inline void cec_msg_get_cec_version(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GET_CEC_VERSION; @@ -834,7 +834,7 @@ static inline void cec_ops_report_physical_addr(const struct cec_msg *msg, } static inline void cec_msg_give_physical_addr(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR; @@ -858,7 +858,7 @@ static inline void cec_ops_set_menu_language(const struct cec_msg *msg, } static inline void cec_msg_get_menu_language(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE; @@ -907,7 +907,7 @@ static inline void cec_ops_report_features(const struct cec_msg *msg, } static inline void cec_msg_give_features(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_FEATURES; @@ -944,7 +944,7 @@ static inline void cec_ops_deck_status(const struct cec_msg *msg, } static inline void cec_msg_give_deck_status(struct cec_msg *msg, - bool reply, + int reply, __u8 status_req) { msg->len = 3; @@ -978,7 +978,7 @@ static inline void cec_ops_play(const struct cec_msg *msg, struct cec_op_tuner_device_info { __u8 rec_flag; __u8 tuner_display_info; - bool is_analog; + __u8 is_analog; union { struct cec_op_digital_service_id digital; struct { @@ -1048,7 +1048,7 @@ static inline void cec_ops_tuner_device_status(const struct cec_msg *msg, } static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg, - bool reply, + int reply, __u8 status_req) { msg->len = 3; @@ -1131,7 +1131,7 @@ static inline void cec_ops_device_vendor_id(const struct cec_msg *msg, } static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID; @@ -1267,7 +1267,7 @@ static inline void cec_ops_set_osd_name(const struct cec_msg *msg, } static inline void cec_msg_give_osd_name(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_OSD_NAME; @@ -1291,7 +1291,7 @@ static inline void cec_ops_menu_status(const struct cec_msg *msg, } static inline void cec_msg_menu_request(struct cec_msg *msg, - bool reply, + int reply, __u8 menu_req) { msg->len = 3; @@ -1308,7 +1308,7 @@ static inline void cec_ops_menu_request(const struct cec_msg *msg, struct cec_op_ui_command { __u8 ui_cmd; - bool has_opt_arg; + __u8 has_opt_arg; union { struct cec_op_channel_data channel_identifier; __u8 ui_broadcast_type; @@ -1354,7 +1354,7 @@ static inline void cec_ops_user_control_pressed(const struct cec_msg *msg, struct cec_op_ui_command *ui_cmd) { ui_cmd->ui_cmd = msg->msg[2]; - ui_cmd->has_opt_arg = false; + ui_cmd->has_opt_arg = 0; if (msg->len == 3) return; switch (ui_cmd->ui_cmd) { @@ -1366,12 +1366,12 @@ static inline void cec_ops_user_control_pressed(const struct cec_msg *msg, case 0x6a: /* The optional operand is one byte for all these ui commands */ ui_cmd->play_mode = msg->msg[3]; - ui_cmd->has_opt_arg = true; + ui_cmd->has_opt_arg = 1; break; case 0x67: if (msg->len < 7) break; - ui_cmd->has_opt_arg = true; + ui_cmd->has_opt_arg = 1; ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2; ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4]; ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6]; @@ -1403,7 +1403,7 @@ static inline void cec_ops_report_power_status(const struct cec_msg *msg, } static inline void cec_msg_give_device_power_status(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS; @@ -1463,7 +1463,7 @@ static inline void cec_ops_report_audio_status(const struct cec_msg *msg, } static inline void cec_msg_give_audio_status(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS; @@ -1485,7 +1485,7 @@ static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg, } static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg, - bool reply, + int reply, __u16 phys_addr) { msg->len = phys_addr == 0xffff ? 2 : 4; @@ -1520,7 +1520,7 @@ static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg, } static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS; @@ -1560,7 +1560,7 @@ static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *m } static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg, - bool reply, + int reply, __u8 num_descriptors, const __u8 *audio_format_id, const __u8 *audio_format_code) @@ -1618,7 +1618,7 @@ static inline void cec_msg_report_arc_initiated(struct cec_msg *msg) } static inline void cec_msg_initiate_arc(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_INITIATE_ARC; @@ -1626,7 +1626,7 @@ static inline void cec_msg_initiate_arc(struct cec_msg *msg, } static inline void cec_msg_request_arc_initiation(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION; @@ -1640,7 +1640,7 @@ static inline void cec_msg_report_arc_terminated(struct cec_msg *msg) } static inline void cec_msg_terminate_arc(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_TERMINATE_ARC; @@ -1648,7 +1648,7 @@ static inline void cec_msg_terminate_arc(struct cec_msg *msg, } static inline void cec_msg_request_arc_termination(struct cec_msg *msg, - bool reply) + int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION; @@ -1690,7 +1690,7 @@ static inline void cec_ops_report_current_latency(const struct cec_msg *msg, } static inline void cec_msg_request_current_latency(struct cec_msg *msg, - bool reply, + int reply, __u16 phys_addr) { msg->len = 4; diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index f4ec0af67707..14b6f24b189e 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -37,6 +37,7 @@ #define _CEC_UAPI_H #include +#include #define CEC_MAX_MSG_SIZE 16 @@ -129,7 +130,7 @@ static inline int cec_msg_opcode(const struct cec_msg *msg) * cec_msg_is_broadcast - return true if this is a broadcast message. * @msg: the message structure */ -static inline bool cec_msg_is_broadcast(const struct cec_msg *msg) +static inline int cec_msg_is_broadcast(const struct cec_msg *msg) { return (msg->msg[0] & 0xf) == 0xf; } @@ -184,14 +185,14 @@ static inline void cec_msg_set_reply_to(struct cec_msg *msg, #define CEC_RX_STATUS_TIMEOUT (1 << 1) #define CEC_RX_STATUS_FEATURE_ABORT (1 << 2) -static inline bool cec_msg_status_is_ok(const struct cec_msg *msg) +static inline int cec_msg_status_is_ok(const struct cec_msg *msg) { if (msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) - return false; + return 0; if (msg->rx_status && !(msg->rx_status & CEC_RX_STATUS_OK)) - return false; + return 0; if (!msg->tx_status && !msg->rx_status) - return false; + return 0; return !(msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT); } @@ -254,47 +255,47 @@ static inline bool cec_msg_status_is_ok(const struct cec_msg *msg) #define CEC_LOG_ADDR_MASK_SPECIFIC (1 << CEC_LOG_ADDR_SPECIFIC) #define CEC_LOG_ADDR_MASK_UNREGISTERED (1 << CEC_LOG_ADDR_UNREGISTERED) -static inline bool cec_has_tv(__u16 log_addr_mask) +static inline int cec_has_tv(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_TV; } -static inline bool cec_has_record(__u16 log_addr_mask) +static inline int cec_has_record(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_RECORD; } -static inline bool cec_has_tuner(__u16 log_addr_mask) +static inline int cec_has_tuner(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_TUNER; } -static inline bool cec_has_playback(__u16 log_addr_mask) +static inline int cec_has_playback(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_PLAYBACK; } -static inline bool cec_has_audiosystem(__u16 log_addr_mask) +static inline int cec_has_audiosystem(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_AUDIOSYSTEM; } -static inline bool cec_has_backup(__u16 log_addr_mask) +static inline int cec_has_backup(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_BACKUP; } -static inline bool cec_has_specific(__u16 log_addr_mask) +static inline int cec_has_specific(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_SPECIFIC; } -static inline bool cec_is_unregistered(__u16 log_addr_mask) +static inline int cec_is_unregistered(__u16 log_addr_mask) { return log_addr_mask & CEC_LOG_ADDR_MASK_UNREGISTERED; } -static inline bool cec_is_unconfigured(__u16 log_addr_mask) +static inline int cec_is_unconfigured(__u16 log_addr_mask) { return log_addr_mask == 0; } @@ -1016,7 +1017,7 @@ struct cec_event { /* Helper functions to identify the 'special' CEC devices */ -static inline bool cec_is_2nd_tv(const struct cec_log_addrs *las) +static inline int cec_is_2nd_tv(const struct cec_log_addrs *las) { /* * It is a second TV if the logical address is 14 or 15 and the @@ -1027,7 +1028,7 @@ static inline bool cec_is_2nd_tv(const struct cec_log_addrs *las) las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_TV; } -static inline bool cec_is_processor(const struct cec_log_addrs *las) +static inline int cec_is_processor(const struct cec_log_addrs *las) { /* * It is a processor if the logical address is 12-15 and the @@ -1038,7 +1039,7 @@ static inline bool cec_is_processor(const struct cec_log_addrs *las) las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_PROCESSOR; } -static inline bool cec_is_switch(const struct cec_log_addrs *las) +static inline int cec_is_switch(const struct cec_log_addrs *las) { /* * It is a switch if the logical address is 15 and the @@ -1050,7 +1051,7 @@ static inline bool cec_is_switch(const struct cec_log_addrs *las) !(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); } -static inline bool cec_is_cdc_only(const struct cec_log_addrs *las) +static inline int cec_is_cdc_only(const struct cec_log_addrs *las) { /* * It is a CDC-only device if the logical address is 15 and the -- cgit v1.2.3 From a161bef04286e1344cd469098213a972af8fa7d6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Nov 2016 10:52:10 -0200 Subject: [media] cec: an inner loop clobbered the outer loop variable An inner for-loop reused the outer loop variable. This was only noticeable with CEC adapters supporting more than one logical address. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index bcd19d41c166..ed76d7050b8a 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1416,6 +1416,7 @@ int __cec_s_log_addrs(struct cec_adapter *adap, const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]); u8 *features = log_addrs->features[i]; bool op_is_dev_features = false; + unsigned j; log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; if (type_mask & (1 << log_addrs->log_addr_type[i])) { @@ -1442,19 +1443,19 @@ int __cec_s_log_addrs(struct cec_adapter *adap, dprintk(1, "unknown logical address type\n"); return -EINVAL; } - for (i = 0; i < feature_sz; i++) { - if ((features[i] & 0x80) == 0) { + for (j = 0; j < feature_sz; j++) { + if ((features[j] & 0x80) == 0) { if (op_is_dev_features) break; op_is_dev_features = true; } } - if (!op_is_dev_features || i == feature_sz) { + if (!op_is_dev_features || j == feature_sz) { dprintk(1, "malformed features\n"); return -EINVAL; } /* Zero unused part of the feature array */ - memset(features + i + 1, 0, feature_sz - i - 1); + memset(features + j + 1, 0, feature_sz - j - 1); } if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) { -- cgit v1.2.3 From aee4c782df24557975c257058f69ac130f6f42bc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Nov 2016 08:34:53 -0200 Subject: [media] pulse8-cec: move out of staging Now that the CEC framework has been moved out of staging and into the mainline kernel we can do the same for the pulse8-cec driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/Kconfig | 5 + drivers/media/usb/Makefile | 1 + drivers/media/usb/pulse8-cec/Kconfig | 10 + drivers/media/usb/pulse8-cec/Makefile | 1 + drivers/media/usb/pulse8-cec/pulse8-cec.c | 761 ++++++++++++++++++++++++++ drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/pulse8-cec/Kconfig | 10 - drivers/staging/media/pulse8-cec/Makefile | 1 - drivers/staging/media/pulse8-cec/TODO | 52 -- drivers/staging/media/pulse8-cec/pulse8-cec.c | 761 -------------------------- 11 files changed, 778 insertions(+), 827 deletions(-) create mode 100644 drivers/media/usb/pulse8-cec/Kconfig create mode 100644 drivers/media/usb/pulse8-cec/Makefile create mode 100644 drivers/media/usb/pulse8-cec/pulse8-cec.c delete mode 100644 drivers/staging/media/pulse8-cec/Kconfig delete mode 100644 drivers/staging/media/pulse8-cec/Makefile delete mode 100644 drivers/staging/media/pulse8-cec/TODO delete mode 100644 drivers/staging/media/pulse8-cec/pulse8-cec.c diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig index 7496f332f3f5..c9644b62f91a 100644 --- a/drivers/media/usb/Kconfig +++ b/drivers/media/usb/Kconfig @@ -60,5 +60,10 @@ source "drivers/media/usb/hackrf/Kconfig" source "drivers/media/usb/msi2500/Kconfig" endif +if MEDIA_CEC_SUPPORT + comment "USB HDMI CEC adapters" +source "drivers/media/usb/pulse8-cec/Kconfig" +endif + endif #MEDIA_USB_SUPPORT endif #USB diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile index 8874ba774a34..0f15e3351ddc 100644 --- a/drivers/media/usb/Makefile +++ b/drivers/media/usb/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ obj-$(CONFIG_VIDEO_USBTV) += usbtv/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_DVB_AS102) += as102/ +obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig new file mode 100644 index 000000000000..6ffc407de62f --- /dev/null +++ b/drivers/media/usb/pulse8-cec/Kconfig @@ -0,0 +1,10 @@ +config USB_PULSE8_CEC + tristate "Pulse Eight HDMI CEC" + depends on USB_ACM && MEDIA_CEC_SUPPORT + select SERIO + select SERIO_SERPORT + ---help--- + This is a cec driver for the Pulse Eight HDMI CEC device. + + To compile this driver as a module, choose M here: the + module will be called pulse8-cec. diff --git a/drivers/media/usb/pulse8-cec/Makefile b/drivers/media/usb/pulse8-cec/Makefile new file mode 100644 index 000000000000..9800690bc25a --- /dev/null +++ b/drivers/media/usb/pulse8-cec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c new file mode 100644 index 000000000000..9092494bb43c --- /dev/null +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -0,0 +1,761 @@ +/* + * Pulse Eight HDMI CEC driver + * + * Copyright 2016 Hans Verkuil ["Power On"], ["Power] or ["Power Toggle"], or if it + * receives with its own physical address. It also does this + * if it receives [0x03 0x00] from an LG TV. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("Hans Verkuil "); +MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver"); +MODULE_LICENSE("GPL"); + +static int debug; +static int persistent_config = 1; +module_param(debug, int, 0644); +module_param(persistent_config, int, 0644); +MODULE_PARM_DESC(debug, "debug level (0-1)"); +MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)"); + +enum pulse8_msgcodes { + MSGCODE_NOTHING = 0, + MSGCODE_PING, + MSGCODE_TIMEOUT_ERROR, + MSGCODE_HIGH_ERROR, + MSGCODE_LOW_ERROR, + MSGCODE_FRAME_START, + MSGCODE_FRAME_DATA, + MSGCODE_RECEIVE_FAILED, + MSGCODE_COMMAND_ACCEPTED, /* 0x08 */ + MSGCODE_COMMAND_REJECTED, + MSGCODE_SET_ACK_MASK, + MSGCODE_TRANSMIT, + MSGCODE_TRANSMIT_EOM, + MSGCODE_TRANSMIT_IDLETIME, + MSGCODE_TRANSMIT_ACK_POLARITY, + MSGCODE_TRANSMIT_LINE_TIMEOUT, + MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */ + MSGCODE_TRANSMIT_FAILED_LINE, + MSGCODE_TRANSMIT_FAILED_ACK, + MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA, + MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE, + MSGCODE_FIRMWARE_VERSION, + MSGCODE_START_BOOTLOADER, + MSGCODE_GET_BUILDDATE, + MSGCODE_SET_CONTROLLED, /* 0x18 */ + MSGCODE_GET_AUTO_ENABLED, + MSGCODE_SET_AUTO_ENABLED, + MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS, + MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, + MSGCODE_GET_LOGICAL_ADDRESS_MASK, + MSGCODE_SET_LOGICAL_ADDRESS_MASK, + MSGCODE_GET_PHYSICAL_ADDRESS, + MSGCODE_SET_PHYSICAL_ADDRESS, /* 0x20 */ + MSGCODE_GET_DEVICE_TYPE, + MSGCODE_SET_DEVICE_TYPE, + MSGCODE_GET_HDMI_VERSION, + MSGCODE_SET_HDMI_VERSION, + MSGCODE_GET_OSD_NAME, + MSGCODE_SET_OSD_NAME, + MSGCODE_WRITE_EEPROM, + MSGCODE_GET_ADAPTER_TYPE, /* 0x28 */ + MSGCODE_SET_ACTIVE_SOURCE, + + MSGCODE_FRAME_EOM = 0x80, + MSGCODE_FRAME_ACK = 0x40, +}; + +#define MSGSTART 0xff +#define MSGEND 0xfe +#define MSGESC 0xfd +#define MSGOFFSET 3 + +#define DATA_SIZE 256 + +#define PING_PERIOD (15 * HZ) + +struct pulse8 { + struct device *dev; + struct serio *serio; + struct cec_adapter *adap; + unsigned int vers; + struct completion cmd_done; + struct work_struct work; + struct delayed_work ping_eeprom_work; + struct cec_msg rx_msg; + u8 data[DATA_SIZE]; + unsigned int len; + u8 buf[DATA_SIZE]; + unsigned int idx; + bool escape; + bool started; + struct mutex config_lock; + struct mutex write_lock; + bool config_pending; + bool restoring_config; + bool autonomous; +}; + +static void pulse8_ping_eeprom_work_handler(struct work_struct *work); + +static void pulse8_irq_work_handler(struct work_struct *work) +{ + struct pulse8 *pulse8 = + container_of(work, struct pulse8, work); + + switch (pulse8->data[0] & 0x3f) { + case MSGCODE_FRAME_DATA: + cec_received_msg(pulse8->adap, &pulse8->rx_msg); + break; + case MSGCODE_TRANSMIT_SUCCEEDED: + cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK, + 0, 0, 0, 0); + break; + case MSGCODE_TRANSMIT_FAILED_ACK: + cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK, + 0, 1, 0, 0); + break; + case MSGCODE_TRANSMIT_FAILED_LINE: + case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: + case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: + cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR, + 0, 0, 0, 1); + break; + } +} + +static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, + unsigned int flags) +{ + struct pulse8 *pulse8 = serio_get_drvdata(serio); + + if (!pulse8->started && data != MSGSTART) + return IRQ_HANDLED; + if (data == MSGESC) { + pulse8->escape = true; + return IRQ_HANDLED; + } + if (pulse8->escape) { + data += MSGOFFSET; + pulse8->escape = false; + } else if (data == MSGEND) { + struct cec_msg *msg = &pulse8->rx_msg; + + if (debug) + dev_info(pulse8->dev, "received: %*ph\n", + pulse8->idx, pulse8->buf); + pulse8->data[0] = pulse8->buf[0]; + switch (pulse8->buf[0] & 0x3f) { + case MSGCODE_FRAME_START: + msg->len = 1; + msg->msg[0] = pulse8->buf[1]; + break; + case MSGCODE_FRAME_DATA: + if (msg->len == CEC_MAX_MSG_SIZE) + break; + msg->msg[msg->len++] = pulse8->buf[1]; + if (pulse8->buf[0] & MSGCODE_FRAME_EOM) + schedule_work(&pulse8->work); + break; + case MSGCODE_TRANSMIT_SUCCEEDED: + case MSGCODE_TRANSMIT_FAILED_LINE: + case MSGCODE_TRANSMIT_FAILED_ACK: + case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: + case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: + schedule_work(&pulse8->work); + break; + case MSGCODE_HIGH_ERROR: + case MSGCODE_LOW_ERROR: + case MSGCODE_RECEIVE_FAILED: + case MSGCODE_TIMEOUT_ERROR: + break; + case MSGCODE_COMMAND_ACCEPTED: + case MSGCODE_COMMAND_REJECTED: + default: + if (pulse8->idx == 0) + break; + memcpy(pulse8->data, pulse8->buf, pulse8->idx); + pulse8->len = pulse8->idx; + complete(&pulse8->cmd_done); + break; + } + pulse8->idx = 0; + pulse8->started = false; + return IRQ_HANDLED; + } else if (data == MSGSTART) { + pulse8->idx = 0; + pulse8->started = true; + return IRQ_HANDLED; + } + + if (pulse8->idx >= DATA_SIZE) { + dev_dbg(pulse8->dev, + "throwing away %d bytes of garbage\n", pulse8->idx); + pulse8->idx = 0; + } + pulse8->buf[pulse8->idx++] = data; + return IRQ_HANDLED; +} + +static void pulse8_disconnect(struct serio *serio) +{ + struct pulse8 *pulse8 = serio_get_drvdata(serio); + + cec_unregister_adapter(pulse8->adap); + cancel_delayed_work_sync(&pulse8->ping_eeprom_work); + dev_info(&serio->dev, "disconnected\n"); + serio_close(serio); + serio_set_drvdata(serio, NULL); + kfree(pulse8); +} + +static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) +{ + int err = 0; + + err = serio_write(serio, MSGSTART); + if (err) + return err; + for (; !err && cmd_len; command++, cmd_len--) { + if (*command >= MSGESC) { + err = serio_write(serio, MSGESC); + if (!err) + err = serio_write(serio, *command - MSGOFFSET); + } else { + err = serio_write(serio, *command); + } + } + if (!err) + err = serio_write(serio, MSGEND); + + return err; +} + +static int pulse8_send_and_wait_once(struct pulse8 *pulse8, + const u8 *cmd, u8 cmd_len, + u8 response, u8 size) +{ + int err; + + /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/ + init_completion(&pulse8->cmd_done); + + err = pulse8_send(pulse8->serio, cmd, cmd_len); + if (err) + return err; + + if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) + return -ETIMEDOUT; + if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && + cmd[0] != MSGCODE_SET_CONTROLLED && + cmd[0] != MSGCODE_SET_AUTO_ENABLED && + cmd[0] != MSGCODE_GET_BUILDDATE) + return -ENOTTY; + if (response && + ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { + dev_info(pulse8->dev, "transmit: failed %02x\n", + pulse8->data[0] & 0x3f); + return -EIO; + } + return 0; +} + +static int pulse8_send_and_wait(struct pulse8 *pulse8, + const u8 *cmd, u8 cmd_len, u8 response, u8 size) +{ + u8 cmd_sc[2]; + int err; + + mutex_lock(&pulse8->write_lock); + err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); + + if (err == -ENOTTY) { + cmd_sc[0] = MSGCODE_SET_CONTROLLED; + cmd_sc[1] = 1; + err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + if (err) + goto unlock; + err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, + response, size); + } + +unlock: + mutex_unlock(&pulse8->write_lock); + return err == -ENOTTY ? -EIO : err; +} + +static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, + struct cec_log_addrs *log_addrs, u16 *pa) +{ + u8 *data = pulse8->data + 1; + u8 cmd[2]; + int err; + struct tm tm; + time_t date; + + pulse8->vers = 0; + + cmd[0] = MSGCODE_FIRMWARE_VERSION; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); + if (err) + return err; + pulse8->vers = (data[0] << 8) | data[1]; + dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers); + if (pulse8->vers < 2) { + *pa = CEC_PHYS_ADDR_INVALID; + return 0; + } + + cmd[0] = MSGCODE_GET_BUILDDATE; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); + if (err) + return err; + date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + time_to_tm(date, 0, &tm); + dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + + dev_dbg(pulse8->dev, "Persistent config:\n"); + cmd[0] = MSGCODE_GET_AUTO_ENABLED; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); + if (err) + return err; + pulse8->autonomous = data[0]; + dev_dbg(pulse8->dev, "Autonomous mode: %s", + data[0] ? "on" : "off"); + + cmd[0] = MSGCODE_GET_DEVICE_TYPE; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); + if (err) + return err; + log_addrs->primary_device_type[0] = data[0]; + dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]); + switch (log_addrs->primary_device_type[0]) { + case CEC_OP_PRIM_DEVTYPE_TV: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; + break; + case CEC_OP_PRIM_DEVTYPE_RECORD: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; + break; + case CEC_OP_PRIM_DEVTYPE_TUNER: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; + break; + case CEC_OP_PRIM_DEVTYPE_PLAYBACK: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; + break; + case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; + break; + case CEC_OP_PRIM_DEVTYPE_SWITCH: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; + break; + case CEC_OP_PRIM_DEVTYPE_PROCESSOR: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; + break; + default: + log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; + log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; + dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n", + log_addrs->primary_device_type[0]); + break; + } + + cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); + if (err) + return err; + log_addrs->log_addr_mask = (data[0] << 8) | data[1]; + dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n", + log_addrs->log_addr_mask); + if (log_addrs->log_addr_mask) + log_addrs->num_log_addrs = 1; + + cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); + if (err) + return err; + *pa = (data[0] << 8) | data[1]; + dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n", + cec_phys_addr_exp(*pa)); + + cmd[0] = MSGCODE_GET_HDMI_VERSION; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); + if (err) + return err; + log_addrs->cec_version = data[0]; + dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version); + + cmd[0] = MSGCODE_GET_OSD_NAME; + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); + if (err) + return err; + strncpy(log_addrs->osd_name, data, 13); + dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); + + return 0; +} + +static int pulse8_apply_persistent_config(struct pulse8 *pulse8, + struct cec_log_addrs *log_addrs, + u16 pa) +{ + int err; + + err = cec_s_log_addrs(pulse8->adap, log_addrs, false); + if (err) + return err; + + cec_s_phys_addr(pulse8->adap, pa, false); + + return 0; +} + +static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct pulse8 *pulse8 = adap->priv; + u8 cmd[16]; + int err; + + cmd[0] = MSGCODE_SET_CONTROLLED; + cmd[1] = enable; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + return enable ? err : 0; +} + +static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +{ + struct pulse8 *pulse8 = adap->priv; + u16 mask = 0; + u16 pa = adap->phys_addr; + u8 cmd[16]; + int err = 0; + + mutex_lock(&pulse8->config_lock); + if (log_addr != CEC_LOG_ADDR_INVALID) + mask = 1 << log_addr; + cmd[0] = MSGCODE_SET_ACK_MASK; + cmd[1] = mask >> 8; + cmd[2] = mask & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); + if ((err && mask != 0) || pulse8->restoring_config) + goto unlock; + + cmd[0] = MSGCODE_SET_AUTO_ENABLED; + cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + pulse8->autonomous = cmd[1]; + if (log_addr == CEC_LOG_ADDR_INVALID) + goto unlock; + + cmd[0] = MSGCODE_SET_DEVICE_TYPE; + cmd[1] = adap->log_addrs.primary_device_type[0]; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + switch (adap->log_addrs.primary_device_type[0]) { + case CEC_OP_PRIM_DEVTYPE_TV: + mask = CEC_LOG_ADDR_MASK_TV; + break; + case CEC_OP_PRIM_DEVTYPE_RECORD: + mask = CEC_LOG_ADDR_MASK_RECORD; + break; + case CEC_OP_PRIM_DEVTYPE_TUNER: + mask = CEC_LOG_ADDR_MASK_TUNER; + break; + case CEC_OP_PRIM_DEVTYPE_PLAYBACK: + mask = CEC_LOG_ADDR_MASK_PLAYBACK; + break; + case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: + mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; + break; + case CEC_OP_PRIM_DEVTYPE_SWITCH: + mask = CEC_LOG_ADDR_MASK_UNREGISTERED; + break; + case CEC_OP_PRIM_DEVTYPE_PROCESSOR: + mask = CEC_LOG_ADDR_MASK_SPECIFIC; + break; + default: + mask = 0; + break; + } + cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; + cmd[1] = mask >> 8; + cmd[2] = mask & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; + cmd[1] = log_addr; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; + cmd[1] = pa >> 8; + cmd[2] = pa & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + cmd[0] = MSGCODE_SET_HDMI_VERSION; + cmd[1] = adap->log_addrs.cec_version; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + if (adap->log_addrs.osd_name[0]) { + size_t osd_len = strlen(adap->log_addrs.osd_name); + char *osd_str = cmd + 1; + + cmd[0] = MSGCODE_SET_OSD_NAME; + strncpy(cmd + 1, adap->log_addrs.osd_name, 13); + if (osd_len < 4) { + memset(osd_str + osd_len, ' ', 4 - osd_len); + osd_len = 4; + osd_str[osd_len] = '\0'; + strcpy(adap->log_addrs.osd_name, osd_str); + } + err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + } + +unlock: + if (pulse8->restoring_config) + pulse8->restoring_config = false; + else + pulse8->config_pending = true; + mutex_unlock(&pulse8->config_lock); + return err; +} + +static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct pulse8 *pulse8 = adap->priv; + u8 cmd[2]; + unsigned int i; + int err; + + cmd[0] = MSGCODE_TRANSMIT_IDLETIME; + cmd[1] = signal_free_time; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; + cmd[1] = cec_msg_is_broadcast(msg); + if (!err) + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; + cmd[1] = msg->msg[0]; + if (!err) + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + if (!err && msg->len > 1) { + cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM : + MSGCODE_TRANSMIT; + cmd[1] = msg->msg[1]; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + for (i = 0; !err && i + 2 < msg->len; i++) { + cmd[0] = (i + 2 == msg->len - 1) ? + MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; + cmd[1] = msg->msg[i + 2]; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + } + } + + return err; +} + +static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg) +{ + return -ENOMSG; +} + +static const struct cec_adap_ops pulse8_cec_adap_ops = { + .adap_enable = pulse8_cec_adap_enable, + .adap_log_addr = pulse8_cec_adap_log_addr, + .adap_transmit = pulse8_cec_adap_transmit, + .received = pulse8_received, +}; + +static int pulse8_connect(struct serio *serio, struct serio_driver *drv) +{ + u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | + CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + struct pulse8 *pulse8; + int err = -ENOMEM; + struct cec_log_addrs log_addrs = {}; + u16 pa = CEC_PHYS_ADDR_INVALID; + + pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL); + + if (!pulse8) + return -ENOMEM; + + pulse8->serio = serio; + pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, + "HDMI CEC", caps, 1, &serio->dev); + err = PTR_ERR_OR_ZERO(pulse8->adap); + if (err < 0) + goto free_device; + + pulse8->dev = &serio->dev; + serio_set_drvdata(serio, pulse8); + INIT_WORK(&pulse8->work, pulse8_irq_work_handler); + mutex_init(&pulse8->write_lock); + mutex_init(&pulse8->config_lock); + pulse8->config_pending = false; + + err = serio_open(serio, drv); + if (err) + goto delete_adap; + + err = pulse8_setup(pulse8, serio, &log_addrs, &pa); + if (err) + goto close_serio; + + err = cec_register_adapter(pulse8->adap); + if (err < 0) + goto close_serio; + + pulse8->dev = &pulse8->adap->devnode.dev; + + if (persistent_config && pulse8->autonomous) { + err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa); + if (err) + goto close_serio; + pulse8->restoring_config = true; + } + + INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, + pulse8_ping_eeprom_work_handler); + schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); + + return 0; + +close_serio: + serio_close(serio); +delete_adap: + cec_delete_adapter(pulse8->adap); + serio_set_drvdata(serio, NULL); +free_device: + kfree(pulse8); + return err; +} + +static void pulse8_ping_eeprom_work_handler(struct work_struct *work) +{ + struct pulse8 *pulse8 = + container_of(work, struct pulse8, ping_eeprom_work.work); + u8 cmd; + + schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); + cmd = MSGCODE_PING; + pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0); + + if (pulse8->vers < 2) + return; + + mutex_lock(&pulse8->config_lock); + if (pulse8->config_pending && persistent_config) { + dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); + cmd = MSGCODE_WRITE_EEPROM; + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) + dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); + else + pulse8->config_pending = false; + } + mutex_unlock(&pulse8->config_lock); +} + +static struct serio_device_id pulse8_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_PULSE8_CEC, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, pulse8_serio_ids); + +static struct serio_driver pulse8_drv = { + .driver = { + .name = "pulse8-cec", + }, + .description = "Pulse Eight HDMI CEC driver", + .id_table = pulse8_serio_ids, + .interrupt = pulse8_interrupt, + .connect = pulse8_connect, + .disconnect = pulse8_disconnect, +}; + +module_serio_driver(pulse8_drv); diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 0abe5ffb4934..ffb8fa72c3da 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -27,8 +27,6 @@ source "drivers/staging/media/davinci_vpfe/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" -source "drivers/staging/media/pulse8-cec/Kconfig" - source "drivers/staging/media/s5p-cec/Kconfig" # Keep LIRC at the end, as it has sub-menus diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 246299eff80d..a28e82cf6447 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -4,5 +4,4 @@ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ -obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += st-cec/ diff --git a/drivers/staging/media/pulse8-cec/Kconfig b/drivers/staging/media/pulse8-cec/Kconfig deleted file mode 100644 index 6ffc407de62f..000000000000 --- a/drivers/staging/media/pulse8-cec/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config USB_PULSE8_CEC - tristate "Pulse Eight HDMI CEC" - depends on USB_ACM && MEDIA_CEC_SUPPORT - select SERIO - select SERIO_SERPORT - ---help--- - This is a cec driver for the Pulse Eight HDMI CEC device. - - To compile this driver as a module, choose M here: the - module will be called pulse8-cec. diff --git a/drivers/staging/media/pulse8-cec/Makefile b/drivers/staging/media/pulse8-cec/Makefile deleted file mode 100644 index 9800690bc25a..000000000000 --- a/drivers/staging/media/pulse8-cec/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o diff --git a/drivers/staging/media/pulse8-cec/TODO b/drivers/staging/media/pulse8-cec/TODO deleted file mode 100644 index fa6660245e5f..000000000000 --- a/drivers/staging/media/pulse8-cec/TODO +++ /dev/null @@ -1,52 +0,0 @@ -This driver needs to mature a bit more and another round of -code cleanups. - -Otherwise it looks to be in good shape. And of course the fact -that the CEC framework is in staging at the moment also prevents -this driver from being mainlined. - -Some notes: - -1) Regarding the "autonomous" mode of the Pulse-Eight: currently this -is disabled, but the idea is that this allows basic functionality -when the PC is off, and it can wake-up the PC through USB. - -To prevent the device to go into autonomous mode the driver would -have to send MSGCODE_SET_CONTROLLED 1 and then send a ping every -30 seconds (in practice once every 15 seconds would be good). When -powering off or going to standby send MSGCODE_SET_CONTROLLED 0 to -turn the autonomous mode back on. - -This needs to be implemented in the driver. Autonomous mode was -added in firmware v2. - -2) Writing to the EEPROM can only be done once every 10 seconds. - -3) To use this driver you also need to patch the inputattach utility, -this patch will be submitted once this driver is moved out of staging. - -diff -urN linuxconsoletools-1.4.9/utils/inputattach.c linuxconsoletools-1.4.9.new/utils/inputattach.c ---- linuxconsoletools-1.4.9/utils/inputattach.c 2016-01-09 16:27:02.000000000 +0100 -+++ linuxconsoletools-1.4.9.new/utils/inputattach.c 2016-03-20 11:35:31.707788967 +0100 -@@ -861,6 +861,9 @@ - { "--wacom_iv", "-wacom_iv", "Wacom protocol IV tablet", - B9600, CS8 | CRTSCTS, - SERIO_WACOM_IV, 0x00, 0x00, 0, wacom_iv_init }, -+{ "--pulse8-cec", "-pulse8-cec", "Pulse Eight HDMI CEC dongle", -+ B9600, CS8, -+ SERIO_PULSE8_CEC, 0x00, 0x00, 0, NULL }, - { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL } - }; - -diff -urN linuxconsoletools-1.4.9/utils/serio-ids.h linuxconsoletools-1.4.9.new/utils/serio-ids.h ---- linuxconsoletools-1.4.9/utils/serio-ids.h 2015-04-26 18:29:42.000000000 +0200 -+++ linuxconsoletools-1.4.9.new/utils/serio-ids.h 2016-03-20 11:41:00.153558539 +0100 -@@ -131,5 +131,8 @@ - #ifndef SERIO_EASYPEN - # define SERIO_EASYPEN 0x3f - #endif -+#ifndef SERIO_PULSE8_CEC -+# define SERIO_PULSE8_CEC 0x40 -+#endif - - #endif diff --git a/drivers/staging/media/pulse8-cec/pulse8-cec.c b/drivers/staging/media/pulse8-cec/pulse8-cec.c deleted file mode 100644 index 9092494bb43c..000000000000 --- a/drivers/staging/media/pulse8-cec/pulse8-cec.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - * Pulse Eight HDMI CEC driver - * - * Copyright 2016 Hans Verkuil ["Power On"], ["Power] or ["Power Toggle"], or if it - * receives with its own physical address. It also does this - * if it receives [0x03 0x00] from an LG TV. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -MODULE_AUTHOR("Hans Verkuil "); -MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver"); -MODULE_LICENSE("GPL"); - -static int debug; -static int persistent_config = 1; -module_param(debug, int, 0644); -module_param(persistent_config, int, 0644); -MODULE_PARM_DESC(debug, "debug level (0-1)"); -MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)"); - -enum pulse8_msgcodes { - MSGCODE_NOTHING = 0, - MSGCODE_PING, - MSGCODE_TIMEOUT_ERROR, - MSGCODE_HIGH_ERROR, - MSGCODE_LOW_ERROR, - MSGCODE_FRAME_START, - MSGCODE_FRAME_DATA, - MSGCODE_RECEIVE_FAILED, - MSGCODE_COMMAND_ACCEPTED, /* 0x08 */ - MSGCODE_COMMAND_REJECTED, - MSGCODE_SET_ACK_MASK, - MSGCODE_TRANSMIT, - MSGCODE_TRANSMIT_EOM, - MSGCODE_TRANSMIT_IDLETIME, - MSGCODE_TRANSMIT_ACK_POLARITY, - MSGCODE_TRANSMIT_LINE_TIMEOUT, - MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */ - MSGCODE_TRANSMIT_FAILED_LINE, - MSGCODE_TRANSMIT_FAILED_ACK, - MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA, - MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE, - MSGCODE_FIRMWARE_VERSION, - MSGCODE_START_BOOTLOADER, - MSGCODE_GET_BUILDDATE, - MSGCODE_SET_CONTROLLED, /* 0x18 */ - MSGCODE_GET_AUTO_ENABLED, - MSGCODE_SET_AUTO_ENABLED, - MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS, - MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, - MSGCODE_GET_LOGICAL_ADDRESS_MASK, - MSGCODE_SET_LOGICAL_ADDRESS_MASK, - MSGCODE_GET_PHYSICAL_ADDRESS, - MSGCODE_SET_PHYSICAL_ADDRESS, /* 0x20 */ - MSGCODE_GET_DEVICE_TYPE, - MSGCODE_SET_DEVICE_TYPE, - MSGCODE_GET_HDMI_VERSION, - MSGCODE_SET_HDMI_VERSION, - MSGCODE_GET_OSD_NAME, - MSGCODE_SET_OSD_NAME, - MSGCODE_WRITE_EEPROM, - MSGCODE_GET_ADAPTER_TYPE, /* 0x28 */ - MSGCODE_SET_ACTIVE_SOURCE, - - MSGCODE_FRAME_EOM = 0x80, - MSGCODE_FRAME_ACK = 0x40, -}; - -#define MSGSTART 0xff -#define MSGEND 0xfe -#define MSGESC 0xfd -#define MSGOFFSET 3 - -#define DATA_SIZE 256 - -#define PING_PERIOD (15 * HZ) - -struct pulse8 { - struct device *dev; - struct serio *serio; - struct cec_adapter *adap; - unsigned int vers; - struct completion cmd_done; - struct work_struct work; - struct delayed_work ping_eeprom_work; - struct cec_msg rx_msg; - u8 data[DATA_SIZE]; - unsigned int len; - u8 buf[DATA_SIZE]; - unsigned int idx; - bool escape; - bool started; - struct mutex config_lock; - struct mutex write_lock; - bool config_pending; - bool restoring_config; - bool autonomous; -}; - -static void pulse8_ping_eeprom_work_handler(struct work_struct *work); - -static void pulse8_irq_work_handler(struct work_struct *work) -{ - struct pulse8 *pulse8 = - container_of(work, struct pulse8, work); - - switch (pulse8->data[0] & 0x3f) { - case MSGCODE_FRAME_DATA: - cec_received_msg(pulse8->adap, &pulse8->rx_msg); - break; - case MSGCODE_TRANSMIT_SUCCEEDED: - cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK, - 0, 0, 0, 0); - break; - case MSGCODE_TRANSMIT_FAILED_ACK: - cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK, - 0, 1, 0, 0); - break; - case MSGCODE_TRANSMIT_FAILED_LINE: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: - cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR, - 0, 0, 0, 1); - break; - } -} - -static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) -{ - struct pulse8 *pulse8 = serio_get_drvdata(serio); - - if (!pulse8->started && data != MSGSTART) - return IRQ_HANDLED; - if (data == MSGESC) { - pulse8->escape = true; - return IRQ_HANDLED; - } - if (pulse8->escape) { - data += MSGOFFSET; - pulse8->escape = false; - } else if (data == MSGEND) { - struct cec_msg *msg = &pulse8->rx_msg; - - if (debug) - dev_info(pulse8->dev, "received: %*ph\n", - pulse8->idx, pulse8->buf); - pulse8->data[0] = pulse8->buf[0]; - switch (pulse8->buf[0] & 0x3f) { - case MSGCODE_FRAME_START: - msg->len = 1; - msg->msg[0] = pulse8->buf[1]; - break; - case MSGCODE_FRAME_DATA: - if (msg->len == CEC_MAX_MSG_SIZE) - break; - msg->msg[msg->len++] = pulse8->buf[1]; - if (pulse8->buf[0] & MSGCODE_FRAME_EOM) - schedule_work(&pulse8->work); - break; - case MSGCODE_TRANSMIT_SUCCEEDED: - case MSGCODE_TRANSMIT_FAILED_LINE: - case MSGCODE_TRANSMIT_FAILED_ACK: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: - schedule_work(&pulse8->work); - break; - case MSGCODE_HIGH_ERROR: - case MSGCODE_LOW_ERROR: - case MSGCODE_RECEIVE_FAILED: - case MSGCODE_TIMEOUT_ERROR: - break; - case MSGCODE_COMMAND_ACCEPTED: - case MSGCODE_COMMAND_REJECTED: - default: - if (pulse8->idx == 0) - break; - memcpy(pulse8->data, pulse8->buf, pulse8->idx); - pulse8->len = pulse8->idx; - complete(&pulse8->cmd_done); - break; - } - pulse8->idx = 0; - pulse8->started = false; - return IRQ_HANDLED; - } else if (data == MSGSTART) { - pulse8->idx = 0; - pulse8->started = true; - return IRQ_HANDLED; - } - - if (pulse8->idx >= DATA_SIZE) { - dev_dbg(pulse8->dev, - "throwing away %d bytes of garbage\n", pulse8->idx); - pulse8->idx = 0; - } - pulse8->buf[pulse8->idx++] = data; - return IRQ_HANDLED; -} - -static void pulse8_disconnect(struct serio *serio) -{ - struct pulse8 *pulse8 = serio_get_drvdata(serio); - - cec_unregister_adapter(pulse8->adap); - cancel_delayed_work_sync(&pulse8->ping_eeprom_work); - dev_info(&serio->dev, "disconnected\n"); - serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(pulse8); -} - -static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) -{ - int err = 0; - - err = serio_write(serio, MSGSTART); - if (err) - return err; - for (; !err && cmd_len; command++, cmd_len--) { - if (*command >= MSGESC) { - err = serio_write(serio, MSGESC); - if (!err) - err = serio_write(serio, *command - MSGOFFSET); - } else { - err = serio_write(serio, *command); - } - } - if (!err) - err = serio_write(serio, MSGEND); - - return err; -} - -static int pulse8_send_and_wait_once(struct pulse8 *pulse8, - const u8 *cmd, u8 cmd_len, - u8 response, u8 size) -{ - int err; - - /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/ - init_completion(&pulse8->cmd_done); - - err = pulse8_send(pulse8->serio, cmd, cmd_len); - if (err) - return err; - - if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) - return -ETIMEDOUT; - if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && - cmd[0] != MSGCODE_SET_CONTROLLED && - cmd[0] != MSGCODE_SET_AUTO_ENABLED && - cmd[0] != MSGCODE_GET_BUILDDATE) - return -ENOTTY; - if (response && - ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { - dev_info(pulse8->dev, "transmit: failed %02x\n", - pulse8->data[0] & 0x3f); - return -EIO; - } - return 0; -} - -static int pulse8_send_and_wait(struct pulse8 *pulse8, - const u8 *cmd, u8 cmd_len, u8 response, u8 size) -{ - u8 cmd_sc[2]; - int err; - - mutex_lock(&pulse8->write_lock); - err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); - - if (err == -ENOTTY) { - cmd_sc[0] = MSGCODE_SET_CONTROLLED; - cmd_sc[1] = 1; - err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - if (err) - goto unlock; - err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, - response, size); - } - -unlock: - mutex_unlock(&pulse8->write_lock); - return err == -ENOTTY ? -EIO : err; -} - -static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, - struct cec_log_addrs *log_addrs, u16 *pa) -{ - u8 *data = pulse8->data + 1; - u8 cmd[2]; - int err; - struct tm tm; - time_t date; - - pulse8->vers = 0; - - cmd[0] = MSGCODE_FIRMWARE_VERSION; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); - if (err) - return err; - pulse8->vers = (data[0] << 8) | data[1]; - dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers); - if (pulse8->vers < 2) { - *pa = CEC_PHYS_ADDR_INVALID; - return 0; - } - - cmd[0] = MSGCODE_GET_BUILDDATE; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); - if (err) - return err; - date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - time_to_tm(date, 0, &tm); - dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - - dev_dbg(pulse8->dev, "Persistent config:\n"); - cmd[0] = MSGCODE_GET_AUTO_ENABLED; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); - if (err) - return err; - pulse8->autonomous = data[0]; - dev_dbg(pulse8->dev, "Autonomous mode: %s", - data[0] ? "on" : "off"); - - cmd[0] = MSGCODE_GET_DEVICE_TYPE; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); - if (err) - return err; - log_addrs->primary_device_type[0] = data[0]; - dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]); - switch (log_addrs->primary_device_type[0]) { - case CEC_OP_PRIM_DEVTYPE_TV: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; - break; - case CEC_OP_PRIM_DEVTYPE_RECORD: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; - break; - case CEC_OP_PRIM_DEVTYPE_TUNER: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; - break; - case CEC_OP_PRIM_DEVTYPE_PLAYBACK: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; - break; - case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; - break; - case CEC_OP_PRIM_DEVTYPE_SWITCH: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; - break; - case CEC_OP_PRIM_DEVTYPE_PROCESSOR: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; - break; - default: - log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; - log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; - dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n", - log_addrs->primary_device_type[0]); - break; - } - - cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); - if (err) - return err; - log_addrs->log_addr_mask = (data[0] << 8) | data[1]; - dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n", - log_addrs->log_addr_mask); - if (log_addrs->log_addr_mask) - log_addrs->num_log_addrs = 1; - - cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); - if (err) - return err; - *pa = (data[0] << 8) | data[1]; - dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n", - cec_phys_addr_exp(*pa)); - - cmd[0] = MSGCODE_GET_HDMI_VERSION; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); - if (err) - return err; - log_addrs->cec_version = data[0]; - dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version); - - cmd[0] = MSGCODE_GET_OSD_NAME; - err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); - if (err) - return err; - strncpy(log_addrs->osd_name, data, 13); - dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); - - return 0; -} - -static int pulse8_apply_persistent_config(struct pulse8 *pulse8, - struct cec_log_addrs *log_addrs, - u16 pa) -{ - int err; - - err = cec_s_log_addrs(pulse8->adap, log_addrs, false); - if (err) - return err; - - cec_s_phys_addr(pulse8->adap, pa, false); - - return 0; -} - -static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) -{ - struct pulse8 *pulse8 = adap->priv; - u8 cmd[16]; - int err; - - cmd[0] = MSGCODE_SET_CONTROLLED; - cmd[1] = enable; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - return enable ? err : 0; -} - -static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) -{ - struct pulse8 *pulse8 = adap->priv; - u16 mask = 0; - u16 pa = adap->phys_addr; - u8 cmd[16]; - int err = 0; - - mutex_lock(&pulse8->config_lock); - if (log_addr != CEC_LOG_ADDR_INVALID) - mask = 1 << log_addr; - cmd[0] = MSGCODE_SET_ACK_MASK; - cmd[1] = mask >> 8; - cmd[2] = mask & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if ((err && mask != 0) || pulse8->restoring_config) - goto unlock; - - cmd[0] = MSGCODE_SET_AUTO_ENABLED; - cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - pulse8->autonomous = cmd[1]; - if (log_addr == CEC_LOG_ADDR_INVALID) - goto unlock; - - cmd[0] = MSGCODE_SET_DEVICE_TYPE; - cmd[1] = adap->log_addrs.primary_device_type[0]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - switch (adap->log_addrs.primary_device_type[0]) { - case CEC_OP_PRIM_DEVTYPE_TV: - mask = CEC_LOG_ADDR_MASK_TV; - break; - case CEC_OP_PRIM_DEVTYPE_RECORD: - mask = CEC_LOG_ADDR_MASK_RECORD; - break; - case CEC_OP_PRIM_DEVTYPE_TUNER: - mask = CEC_LOG_ADDR_MASK_TUNER; - break; - case CEC_OP_PRIM_DEVTYPE_PLAYBACK: - mask = CEC_LOG_ADDR_MASK_PLAYBACK; - break; - case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: - mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; - break; - case CEC_OP_PRIM_DEVTYPE_SWITCH: - mask = CEC_LOG_ADDR_MASK_UNREGISTERED; - break; - case CEC_OP_PRIM_DEVTYPE_PROCESSOR: - mask = CEC_LOG_ADDR_MASK_SPECIFIC; - break; - default: - mask = 0; - break; - } - cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; - cmd[1] = mask >> 8; - cmd[2] = mask & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; - cmd[1] = log_addr; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; - cmd[1] = pa >> 8; - cmd[2] = pa & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - cmd[0] = MSGCODE_SET_HDMI_VERSION; - cmd[1] = adap->log_addrs.cec_version; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - if (adap->log_addrs.osd_name[0]) { - size_t osd_len = strlen(adap->log_addrs.osd_name); - char *osd_str = cmd + 1; - - cmd[0] = MSGCODE_SET_OSD_NAME; - strncpy(cmd + 1, adap->log_addrs.osd_name, 13); - if (osd_len < 4) { - memset(osd_str + osd_len, ' ', 4 - osd_len); - osd_len = 4; - osd_str[osd_len] = '\0'; - strcpy(adap->log_addrs.osd_name, osd_str); - } - err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - } - -unlock: - if (pulse8->restoring_config) - pulse8->restoring_config = false; - else - pulse8->config_pending = true; - mutex_unlock(&pulse8->config_lock); - return err; -} - -static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg) -{ - struct pulse8 *pulse8 = adap->priv; - u8 cmd[2]; - unsigned int i; - int err; - - cmd[0] = MSGCODE_TRANSMIT_IDLETIME; - cmd[1] = signal_free_time; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; - cmd[1] = cec_msg_is_broadcast(msg); - if (!err) - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; - cmd[1] = msg->msg[0]; - if (!err) - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - if (!err && msg->len > 1) { - cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM : - MSGCODE_TRANSMIT; - cmd[1] = msg->msg[1]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - for (i = 0; !err && i + 2 < msg->len; i++) { - cmd[0] = (i + 2 == msg->len - 1) ? - MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; - cmd[1] = msg->msg[i + 2]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - } - } - - return err; -} - -static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg) -{ - return -ENOMSG; -} - -static const struct cec_adap_ops pulse8_cec_adap_ops = { - .adap_enable = pulse8_cec_adap_enable, - .adap_log_addr = pulse8_cec_adap_log_addr, - .adap_transmit = pulse8_cec_adap_transmit, - .received = pulse8_received, -}; - -static int pulse8_connect(struct serio *serio, struct serio_driver *drv) -{ - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; - struct pulse8 *pulse8; - int err = -ENOMEM; - struct cec_log_addrs log_addrs = {}; - u16 pa = CEC_PHYS_ADDR_INVALID; - - pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL); - - if (!pulse8) - return -ENOMEM; - - pulse8->serio = serio; - pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, - "HDMI CEC", caps, 1, &serio->dev); - err = PTR_ERR_OR_ZERO(pulse8->adap); - if (err < 0) - goto free_device; - - pulse8->dev = &serio->dev; - serio_set_drvdata(serio, pulse8); - INIT_WORK(&pulse8->work, pulse8_irq_work_handler); - mutex_init(&pulse8->write_lock); - mutex_init(&pulse8->config_lock); - pulse8->config_pending = false; - - err = serio_open(serio, drv); - if (err) - goto delete_adap; - - err = pulse8_setup(pulse8, serio, &log_addrs, &pa); - if (err) - goto close_serio; - - err = cec_register_adapter(pulse8->adap); - if (err < 0) - goto close_serio; - - pulse8->dev = &pulse8->adap->devnode.dev; - - if (persistent_config && pulse8->autonomous) { - err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa); - if (err) - goto close_serio; - pulse8->restoring_config = true; - } - - INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, - pulse8_ping_eeprom_work_handler); - schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); - - return 0; - -close_serio: - serio_close(serio); -delete_adap: - cec_delete_adapter(pulse8->adap); - serio_set_drvdata(serio, NULL); -free_device: - kfree(pulse8); - return err; -} - -static void pulse8_ping_eeprom_work_handler(struct work_struct *work) -{ - struct pulse8 *pulse8 = - container_of(work, struct pulse8, ping_eeprom_work.work); - u8 cmd; - - schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); - cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); - - if (pulse8->vers < 2) - return; - - mutex_lock(&pulse8->config_lock); - if (pulse8->config_pending && persistent_config) { - dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); - cmd = MSGCODE_WRITE_EEPROM; - if (pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0)) - dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); - else - pulse8->config_pending = false; - } - mutex_unlock(&pulse8->config_lock); -} - -static struct serio_device_id pulse8_serio_ids[] = { - { - .type = SERIO_RS232, - .proto = SERIO_PULSE8_CEC, - .id = SERIO_ANY, - .extra = SERIO_ANY, - }, - { 0 } -}; - -MODULE_DEVICE_TABLE(serio, pulse8_serio_ids); - -static struct serio_driver pulse8_drv = { - .driver = { - .name = "pulse8-cec", - }, - .description = "Pulse Eight HDMI CEC driver", - .id_table = pulse8_serio_ids, - .interrupt = pulse8_interrupt, - .connect = pulse8_connect, - .disconnect = pulse8_disconnect, -}; - -module_serio_driver(pulse8_drv); -- cgit v1.2.3 From 764040c49cbb58857815b0ebaae97273faad3143 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Nov 2016 08:37:15 -0200 Subject: [media] s5p-cec/st-cec: update TODOs Update the TODOs explaining why these two drivers remain in staging. The reason is that these drivers rely on userspace to set the physical address, but that should come from the HDMI output driver. This in turn needs the upcoming HDMI notifier framework. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/s5p-cec/TODO | 12 ++++++------ drivers/staging/media/st-cec/TODO | 7 +++++++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 drivers/staging/media/st-cec/TODO diff --git a/drivers/staging/media/s5p-cec/TODO b/drivers/staging/media/s5p-cec/TODO index f51d5268ac40..64f21bab38f5 100644 --- a/drivers/staging/media/s5p-cec/TODO +++ b/drivers/staging/media/s5p-cec/TODO @@ -1,7 +1,7 @@ -This driver depends on the CEC framework, which is currently in -staging, so therefor this driver is in staging as well. +This driver requires that userspace sets the physical address. +However, this should be passed on from the corresponding +Samsung HDMI driver. -In addition, this driver requires that userspace sets the physical -address. However, this should be passed on from the corresponding -samsung HDMI driver. It is very annoying if userspace has to do this, -and other than USB CEC adapters this must be handled automatically. +We have to wait until the HDMI notifier framework has been merged +in order to handle this gracefully, until that time this driver +has to remain in staging. diff --git a/drivers/staging/media/st-cec/TODO b/drivers/staging/media/st-cec/TODO new file mode 100644 index 000000000000..c61289742c5c --- /dev/null +++ b/drivers/staging/media/st-cec/TODO @@ -0,0 +1,7 @@ +This driver requires that userspace sets the physical address. +However, this should be passed on from the corresponding +ST HDMI driver. + +We have to wait until the HDMI notifier framework has been merged +in order to handle this gracefully, until that time this driver +has to remain in staging. -- cgit v1.2.3 From 104eda6d7e3e31fc1beb2c109c5566220d602245 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Nov 2016 08:47:16 -0200 Subject: [media] MAINTAINERS: update paths The cec framework and the pulse8-cec driver have been moved out of staging, so update the MAINTAINERS paths. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 93e9f4227c53..5106590190f5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2958,15 +2958,15 @@ L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git W: http://linuxtv.org S: Supported -F: Documentation/cec.txt +F: Documentation/media/kapi/cec-core.rst F: Documentation/media/uapi/cec -F: drivers/staging/media/cec/ +F: drivers/media/cec/ F: drivers/media/cec-edid.c F: drivers/media/rc/keymaps/rc-cec.c F: include/media/cec.h F: include/media/cec-edid.h -F: include/linux/cec.h -F: include/linux/cec-funcs.h +F: include/uapi/linux/cec.h +F: include/uapi/linux/cec-funcs.h CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann @@ -9783,7 +9783,7 @@ M: Hans Verkuil L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained -F: drivers/staging/media/pulse8-cec +F: drivers/media/usb/pulse8-cec/* PVRUSB2 VIDEO4LINUX DRIVER M: Mike Isely -- cgit v1.2.3 From 8991a63d1a8a01938932319c8b98f5a3420a0bb2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 9 Nov 2016 12:10:59 -0200 Subject: [media] cec: zero counters in cec_received_msg() Make sure the TX counters are zeroed in the cec_msg struct. Non-zero TX counters make no sense when a message is received, and applications should not see non-zero values here. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index ed76d7050b8a..d9c6f2c1c6fa 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -874,6 +874,10 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) msg->sequence = msg->reply = msg->timeout = 0; msg->tx_status = 0; msg->tx_ts = 0; + msg->tx_arb_lost_cnt = 0; + msg->tx_nack_cnt = 0; + msg->tx_low_drive_cnt = 0; + msg->tx_error_cnt = 0; msg->flags = 0; memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); -- cgit v1.2.3 From 71334ae42d6b450efeac656dbb254bcf787f5ac7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 15:59:14 -0200 Subject: [media] cec-ioc-adap-g-log-addrs.rst: describe CEC_LOG_ADDRS_FL_CDC_ONLY The CEC_LOG_ADDRS_FL_CDC_ONLY flag is missing at the documentation, causing this warning: Documentation/output/cec.h.rst:6: WARNING: undefined label: cec-log-addrs-fl-cdc-only (if the link has no caption the label must precede a section header) Add a documentation for it, based on the commit that introduced the flag. Fixes: a69a168a1bd4 ("[media] cec: add proper support for CDC-Only CEC devices") Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index 571ae57b75ae..b878637e91b3 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -176,6 +176,15 @@ logical address types are already defined will return with error ``EBUSY``. and will appear as keystrokes. This features needs to be enabled explicitly. If CEC is used to enter e.g. passwords, then you may not want to enable this to avoid trivial snooping of the keystrokes. + * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: + + - `CEC_LOG_ADDRS_FL_CDC_ONLY` + - 4 + - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices + are CEC devices that can only handle CDC messages. + + All other messages are ignored. + .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| -- cgit v1.2.3 From 03c47aaeffec8e91ff4207d4814061a24fe51afb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 7 Nov 2016 18:15:47 -0200 Subject: [media] uvcvideo: add support for Oculus Rift Sensor The Rift CV1 Sensor has bInterfaceClass set to vendor specific, so we need an entry in uvc_ids to probe it. Just as the Rift DK2 IR tracker, it misreports the pixel format as YUYV instead of Y8. The sensor is configured with a low exposure time and high black level by default, so that only bright IR sources can be seen. Signed-off-by: Philipp Zabel Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 87b2fc3b0ac2..11744f92097b 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2670,6 +2670,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_FORCE_Y8 }, + /* Oculus VR Rift Sensor */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x2833, + .idProduct = 0x0211, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FORCE_Y8 }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, -- cgit v1.2.3 From 04b96d1a6954309eb562ef2736c019b3cf2dad2a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Sep 2016 05:41:24 -0300 Subject: [media] v4l: omap3isp: Fix OF node double put when parsing OF graph When parsing the graph the driver loops over all endpoints using of_graph_get_next_endpoint(). The function handles reference counting of the passed and returned nodes, so the returned node's reference count must not be decreased manually in the normal path. Move the offending of_node_put() call to the error path that requires manual reference count handling. Reported-by: H. Nikolaus Schaller Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 2e1b17ef82a3..084ecf4aa9a4 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2117,23 +2117,18 @@ static int isp_of_parse_nodes(struct device *dev, struct isp_async_subdev *isd; isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL); - if (!isd) { - of_node_put(node); - return -ENOMEM; - } + if (!isd) + goto error; notifier->subdevs[notifier->num_subdevs] = &isd->asd; - if (isp_of_parse_node(dev, node, isd)) { - of_node_put(node); - return -EINVAL; - } + if (isp_of_parse_node(dev, node, isd)) + goto error; isd->asd.match.of.node = of_graph_get_remote_port_parent(node); - of_node_put(node); if (!isd->asd.match.of.node) { dev_warn(dev, "bad remote port parent\n"); - return -EINVAL; + goto error; } isd->asd.match_type = V4L2_ASYNC_MATCH_OF; @@ -2141,6 +2136,10 @@ static int isp_of_parse_nodes(struct device *dev, } return notifier->num_subdevs; + +error: + of_node_put(node); + return -EINVAL; } static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, -- cgit v1.2.3 From a9943f6b6b77cf974d8d602be9cc92863e46b5f4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Nov 2016 05:58:02 -0200 Subject: [media] v4l: omap3isp: Use dma_request_chan_by_mask() to request the DMA channel When requesting the DMA channel it was mandatory that we do not have DMA resource nor valid DMA channel via DT. In this case the dma_request_slave_channel_compat() would fall back and request any channel with SW trigger. The same can be achieved with the dma_request_chan_by_mask() without the misleading use of the DMAengine API - implying that the omap3isp does need to have DMA resource or valid dma binding in DT. Signed-off-by: Peter Ujfalusi Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isphist.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c index 7138b043a4aa..a4ed5d140d48 100644 --- a/drivers/media/platform/omap3isp/isphist.c +++ b/drivers/media/platform/omap3isp/isphist.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -486,27 +485,30 @@ int omap3isp_hist_init(struct isp_device *isp) hist->isp = isp; if (HIST_CONFIG_DMA) { - struct platform_device *pdev = to_platform_device(isp->dev); - struct resource *res; - unsigned int sig = 0; dma_cap_mask_t mask; + /* + * We need slave capable channel without DMA request line for + * reading out the data. + * For this we can use dma_request_chan_by_mask() as we are + * happy with any channel as long as it is capable of slave + * configuration. + */ dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); + hist->dma_ch = dma_request_chan_by_mask(&mask); + if (IS_ERR(hist->dma_ch)) { + ret = PTR_ERR(hist->dma_ch); + if (ret == -EPROBE_DEFER) + return ret; - res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - "hist"); - if (res) - sig = res->start; - - hist->dma_ch = dma_request_slave_channel_compat(mask, - omap_dma_filter_fn, &sig, isp->dev, "hist"); - if (!hist->dma_ch) + hist->dma_ch = NULL; dev_warn(isp->dev, "hist: DMA channel request failed, using PIO\n"); - else + } else { dev_dbg(isp->dev, "hist: using DMA channel %s\n", dma_chan_name(hist->dma_ch)); + } } hist->ops = &hist_ops; -- cgit v1.2.3 From 446e412597217e937d33296e77eeba7379ab3008 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 4 Aug 2016 13:14:02 -0300 Subject: [media] v4l: ctrls: Add deinterlacing mode control The menu control selects the operation mode of a video deinterlacer. The menu entries are driver specific. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/extended-controls.rst | 4 ++++ Documentation/media/v4l-drivers/index.rst | 2 ++ drivers/media/v4l2-core/v4l2-ctrls.c | 2 ++ include/uapi/linux/v4l2-controls.h | 1 + 4 files changed, 9 insertions(+) diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 7725c33d8b69..40071ea5d90e 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -3017,6 +3017,10 @@ Image Process Control IDs test pattern images. These hardware specific test patterns can be used to test if a device is working properly. +``V4L2_CID_DEINTERLACING_MODE (menu)`` + The video deinterlacing mode (such as Bob, Weave, ...). The menu items are + driver specific and are documented in :ref:`v4l-drivers`. + .. _dv-controls: diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index aac566f88833..acde3ed7860f 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -2,6 +2,8 @@ .. include:: +.. _v4l-drivers: + ################################################ Video4Linux (V4L) driver-specific documentation ################################################ diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index adc2147fcff7..47001e25fd9e 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -885,6 +885,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_LINK_FREQ: return "Link Frequency"; case V4L2_CID_PIXEL_RATE: return "Pixel Rate"; case V4L2_CID_TEST_PATTERN: return "Test Pattern"; + case V4L2_CID_DEINTERLACING_MODE: return "Deinterlacing Mode"; /* DV controls */ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ @@ -1058,6 +1059,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_DV_RX_RGB_RANGE: case V4L2_CID_DV_RX_IT_CONTENT_TYPE: case V4L2_CID_TEST_PATTERN: + case V4L2_CID_DEINTERLACING_MODE: case V4L2_CID_TUNE_DEEMPHASIS: case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: case V4L2_CID_DETECT_MD_MODE: diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index b6a357a5f053..0d2e1e01fbd5 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -892,6 +892,7 @@ enum v4l2_jpeg_chroma_subsampling { #define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1) #define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2) #define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3) +#define V4L2_CID_DEINTERLACING_MODE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 4) /* DV-class control IDs defined by V4L2 */ -- cgit v1.2.3 From 3547d32be04506ad23346eca6ce8b745ef146fab Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Thu, 30 Jun 2016 13:50:30 -0300 Subject: [media] dt-bindings: Add Renesas R-Car FDP1 bindings The FDP1 is a de-interlacing module which converts interlaced video to progressive video. It is also capable of performing pixel format conversion between YCbCr/YUV formats and RGB formats. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Acked-by: Rob Herring Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/renesas,fdp1.txt | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,fdp1.txt diff --git a/Documentation/devicetree/bindings/media/renesas,fdp1.txt b/Documentation/devicetree/bindings/media/renesas,fdp1.txt new file mode 100644 index 000000000000..8dd1007bb573 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,fdp1.txt @@ -0,0 +1,37 @@ +Renesas R-Car Fine Display Processor (FDP1) +------------------------------------------- + +The FDP1 is a de-interlacing module which converts interlaced video to +progressive video. It is capable of performing pixel format conversion between +YCbCr/YUV formats and RGB formats. Only YCbCr/YUV formats are supported as +an input to the module. + +Required properties: + + - compatible: must be "renesas,fdp1" + - reg: the register base and size for the device registers + - interrupts : interrupt specifier for the FDP1 instance + - clocks: reference to the functional clock + +Optional properties: + + - power-domains: reference to the power domain that the FDP1 belongs to, if + any. + - renesas,fcp: a phandle referencing the FCP that handles memory accesses + for the FDP1. Not needed on Gen2, mandatory on Gen3. + +Please refer to the binding documentation for the clock and/or power domain +providers for more details. + + +Device node example +------------------- + + fdp1@fe940000 { + compatible = "renesas,fdp1"; + reg = <0 0xfe940000 0 0x2400>; + interrupts = ; + clocks = <&cpg CPG_MOD 119>; + power-domains = <&sysc R8A7795_PD_A3VP>; + renesas,fcp = <&fcpf0>; + }; -- cgit v1.2.3 From 4710b752e029f3f82dd4a84d9dc61fe72c97bf82 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Thu, 30 Jun 2016 10:41:23 -0300 Subject: [media] v4l: Add Renesas R-Car FDP1 Driver The FDP1 driver performs advanced de-interlacing on a memory 2 memory based video stream, and supports conversion from YCbCr/YUV to RGB pixel formats Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/v4l-drivers/index.rst | 1 + Documentation/media/v4l-drivers/rcar-fdp1.rst | 37 + MAINTAINERS | 9 + drivers/media/platform/Kconfig | 13 + drivers/media/platform/Makefile | 1 + drivers/media/platform/rcar_fdp1.c | 2445 +++++++++++++++++++++++++ 6 files changed, 2506 insertions(+) create mode 100644 Documentation/media/v4l-drivers/rcar-fdp1.rst create mode 100644 drivers/media/platform/rcar_fdp1.c diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index acde3ed7860f..a606d1cdac13 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -48,6 +48,7 @@ For more details see the file COPYING in the source distribution of Linux. pvrusb2 pxa_camera radiotrack + rcar-fdp1 saa7134 sh_mobile_ceu_camera si470x diff --git a/Documentation/media/v4l-drivers/rcar-fdp1.rst b/Documentation/media/v4l-drivers/rcar-fdp1.rst new file mode 100644 index 000000000000..a59b1e8e3e9c --- /dev/null +++ b/Documentation/media/v4l-drivers/rcar-fdp1.rst @@ -0,0 +1,37 @@ +Renesas R-Car Fine Display Processor (FDP1) Driver +================================================== + +The R-Car FDP1 driver implements driver-specific controls as follows. + +``V4L2_CID_DEINTERLACING_MODE (menu)`` + The video deinterlacing mode (such as Bob, Weave, ...). The R-Car FDP1 + driver implements the following modes. + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 4 + + * - ``"Progressive" (0)`` + - The input image video stream is progressive (not interlaced). No + deinterlacing is performed. Apart from (optional) format and encoding + conversion output frames are identical to the input frames. + * - ``"Adaptive 2D/3D" (1)`` + - Motion adaptive version of 2D and 3D deinterlacing. Use 3D deinterlacing + in the presence of fast motion and 2D deinterlacing with diagonal + interpolation otherwise. + * - ``"Fixed 2D" (2)`` + - The current field is scaled vertically by averaging adjacent lines to + recover missing lines. This method is also known as blending or Line + Averaging (LAV). + * - ``"Fixed 3D" (3)`` + - The previous and next fields are averaged to recover lines missing from + the current field. This method is also known as Field Averaging (FAV). + * - ``"Previous field" (4)`` + - The current field is weaved with the previous field, i.e. the previous + field is used to fill missing lines from the current field. This method + is also known as weave deinterlacing. + * - ``"Next field" (5)`` + - The current field is weaved with the next field, i.e. the next field is + used to fill missing lines from the current field. This method is also + known as weave deinterlacing. diff --git a/MAINTAINERS b/MAINTAINERS index 5106590190f5..78ec26e84c5b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7712,6 +7712,15 @@ F: Documentation/devicetree/bindings/media/renesas,fcp.txt F: drivers/media/platform/rcar-fcp.c F: include/media/rcar-fcp.h +MEDIA DRIVERS FOR RENESAS - FDP1 +M: Kieran Bingham +L: linux-media@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +S: Supported +F: Documentation/devicetree/bindings/media/renesas,fdp1.txt +F: drivers/media/platform/rcar_fdp1.c + MEDIA DRIVERS FOR RENESAS - VIN M: Niklas Söderlund L: linux-media@vger.kernel.org diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 754edbf1a326..84f44098dc99 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -307,6 +307,19 @@ config VIDEO_SH_VEU Support for the Video Engine Unit (VEU) on SuperH and SH-Mobile SoCs. +config VIDEO_RENESAS_FDP1 + tristate "Renesas Fine Display Processor" + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA + depends on ARCH_SHMOBILE || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + ---help--- + This is a V4L2 driver for the Renesas Fine Display Processor + providing colour space conversion, and de-interlacing features. + + To compile this driver as a module, choose M here: the module + will be called rcar_fdp1. + config VIDEO_RENESAS_JPU tristate "Renesas JPEG Processing Unit" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index f842933d17de..5b3cb271d2b8 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o obj-$(CONFIG_SOC_CAMERA) += soc_camera/ obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o +obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c new file mode 100644 index 000000000000..dd1a6ea17f22 --- /dev/null +++ b/drivers/media/platform/rcar_fdp1.c @@ -0,0 +1,2445 @@ +/* + * Renesas RCar Fine Display Processor + * + * Video format converter and frame deinterlacer device. + * + * Author: Kieran Bingham, + * Copyright (c) 2016 Renesas Electronics Corporation. + * + * This code is developed and inspired from the vim2m, rcar_jpu, + * m2m-deinterlace, and vsp1 drivers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the + * License, or (at your option) any later version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "activate debug info"); + +/* Minimum and maximum frame width/height */ +#define FDP1_MIN_W 80U +#define FDP1_MIN_H 80U + +#define FDP1_MAX_W 3840U +#define FDP1_MAX_H 2160U + +#define FDP1_MAX_PLANES 3U +#define FDP1_MAX_STRIDE 8190U + +/* Flags that indicate a format can be used for capture/output */ +#define FDP1_CAPTURE BIT(0) +#define FDP1_OUTPUT BIT(1) + +#define DRIVER_NAME "rcar_fdp1" + +/* Number of Job's to have available on the processing queue */ +#define FDP1_NUMBER_JOBS 8 + +#define dprintk(fdp1, fmt, arg...) \ + v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg) + +/* + * FDP1 registers and bits + */ + +/* FDP1 start register - Imm */ +#define FD1_CTL_CMD 0x0000 +#define FD1_CTL_CMD_STRCMD BIT(0) + +/* Sync generator register - Imm */ +#define FD1_CTL_SGCMD 0x0004 +#define FD1_CTL_SGCMD_SGEN BIT(0) + +/* Register set end register - Imm */ +#define FD1_CTL_REGEND 0x0008 +#define FD1_CTL_REGEND_REGEND BIT(0) + +/* Channel activation register - Vupdt */ +#define FD1_CTL_CHACT 0x000c +#define FD1_CTL_CHACT_SMW BIT(9) +#define FD1_CTL_CHACT_WR BIT(8) +#define FD1_CTL_CHACT_SMR BIT(3) +#define FD1_CTL_CHACT_RD2 BIT(2) +#define FD1_CTL_CHACT_RD1 BIT(1) +#define FD1_CTL_CHACT_RD0 BIT(0) + +/* Operation Mode Register - Vupdt */ +#define FD1_CTL_OPMODE 0x0010 +#define FD1_CTL_OPMODE_PRG BIT(4) +#define FD1_CTL_OPMODE_VIMD_INTERRUPT (0 << 0) +#define FD1_CTL_OPMODE_VIMD_BESTEFFORT (1 << 0) +#define FD1_CTL_OPMODE_VIMD_NOINTERRUPT (2 << 0) + +#define FD1_CTL_VPERIOD 0x0014 +#define FD1_CTL_CLKCTRL 0x0018 +#define FD1_CTL_CLKCTRL_CSTP_N BIT(0) + +/* Software reset register */ +#define FD1_CTL_SRESET 0x001c +#define FD1_CTL_SRESET_SRST BIT(0) + +/* Control status register (V-update-status) */ +#define FD1_CTL_STATUS 0x0024 +#define FD1_CTL_STATUS_VINT_CNT_MASK GENMASK(31, 16) +#define FD1_CTL_STATUS_VINT_CNT_SHIFT 16 +#define FD1_CTL_STATUS_SGREGSET BIT(10) +#define FD1_CTL_STATUS_SGVERR BIT(9) +#define FD1_CTL_STATUS_SGFREND BIT(8) +#define FD1_CTL_STATUS_BSY BIT(0) + +#define FD1_CTL_VCYCLE_STAT 0x0028 + +/* Interrupt enable register */ +#define FD1_CTL_IRQENB 0x0038 +/* Interrupt status register */ +#define FD1_CTL_IRQSTA 0x003c +/* Interrupt control register */ +#define FD1_CTL_IRQFSET 0x0040 + +/* Common IRQ Bit settings */ +#define FD1_CTL_IRQ_VERE BIT(16) +#define FD1_CTL_IRQ_VINTE BIT(4) +#define FD1_CTL_IRQ_FREE BIT(0) +#define FD1_CTL_IRQ_MASK (FD1_CTL_IRQ_VERE | \ + FD1_CTL_IRQ_VINTE | \ + FD1_CTL_IRQ_FREE) + +/* RPF */ +#define FD1_RPF_SIZE 0x0060 +#define FD1_RPF_SIZE_MASK GENMASK(12, 0) +#define FD1_RPF_SIZE_H_SHIFT 16 +#define FD1_RPF_SIZE_V_SHIFT 0 + +#define FD1_RPF_FORMAT 0x0064 +#define FD1_RPF_FORMAT_CIPM BIT(16) +#define FD1_RPF_FORMAT_RSPYCS BIT(13) +#define FD1_RPF_FORMAT_RSPUVS BIT(12) +#define FD1_RPF_FORMAT_CF BIT(8) + +#define FD1_RPF_PSTRIDE 0x0068 +#define FD1_RPF_PSTRIDE_Y_SHIFT 16 +#define FD1_RPF_PSTRIDE_C_SHIFT 0 + +/* RPF0 Source Component Y Address register */ +#define FD1_RPF0_ADDR_Y 0x006c + +/* RPF1 Current Picture Registers */ +#define FD1_RPF1_ADDR_Y 0x0078 +#define FD1_RPF1_ADDR_C0 0x007c +#define FD1_RPF1_ADDR_C1 0x0080 + +/* RPF2 next picture register */ +#define FD1_RPF2_ADDR_Y 0x0084 + +#define FD1_RPF_SMSK_ADDR 0x0090 +#define FD1_RPF_SWAP 0x0094 + +/* WPF */ +#define FD1_WPF_FORMAT 0x00c0 +#define FD1_WPF_FORMAT_PDV_SHIFT 24 +#define FD1_WPF_FORMAT_FCNL BIT(20) +#define FD1_WPF_FORMAT_WSPYCS BIT(15) +#define FD1_WPF_FORMAT_WSPUVS BIT(14) +#define FD1_WPF_FORMAT_WRTM_601_16 (0 << 9) +#define FD1_WPF_FORMAT_WRTM_601_0 (1 << 9) +#define FD1_WPF_FORMAT_WRTM_709_16 (2 << 9) +#define FD1_WPF_FORMAT_CSC BIT(8) + +#define FD1_WPF_RNDCTL 0x00c4 +#define FD1_WPF_RNDCTL_CBRM BIT(28) +#define FD1_WPF_RNDCTL_CLMD_NOCLIP (0 << 12) +#define FD1_WPF_RNDCTL_CLMD_CLIP_16_235 (1 << 12) +#define FD1_WPF_RNDCTL_CLMD_CLIP_1_254 (2 << 12) + +#define FD1_WPF_PSTRIDE 0x00c8 +#define FD1_WPF_PSTRIDE_Y_SHIFT 16 +#define FD1_WPF_PSTRIDE_C_SHIFT 0 + +/* WPF Destination picture */ +#define FD1_WPF_ADDR_Y 0x00cc +#define FD1_WPF_ADDR_C0 0x00d0 +#define FD1_WPF_ADDR_C1 0x00d4 +#define FD1_WPF_SWAP 0x00d8 +#define FD1_WPF_SWAP_OSWAP_SHIFT 0 +#define FD1_WPF_SWAP_SSWAP_SHIFT 4 + +/* WPF/RPF Common */ +#define FD1_RWPF_SWAP_BYTE BIT(0) +#define FD1_RWPF_SWAP_WORD BIT(1) +#define FD1_RWPF_SWAP_LWRD BIT(2) +#define FD1_RWPF_SWAP_LLWD BIT(3) + +/* IPC */ +#define FD1_IPC_MODE 0x0100 +#define FD1_IPC_MODE_DLI BIT(8) +#define FD1_IPC_MODE_DIM_ADAPT2D3D (0 << 0) +#define FD1_IPC_MODE_DIM_FIXED2D (1 << 0) +#define FD1_IPC_MODE_DIM_FIXED3D (2 << 0) +#define FD1_IPC_MODE_DIM_PREVFIELD (3 << 0) +#define FD1_IPC_MODE_DIM_NEXTFIELD (4 << 0) + +#define FD1_IPC_SMSK_THRESH 0x0104 +#define FD1_IPC_SMSK_THRESH_CONST 0x00010002 + +#define FD1_IPC_COMB_DET 0x0108 +#define FD1_IPC_COMB_DET_CONST 0x00200040 + +#define FD1_IPC_MOTDEC 0x010c +#define FD1_IPC_MOTDEC_CONST 0x00008020 + +/* DLI registers */ +#define FD1_IPC_DLI_BLEND 0x0120 +#define FD1_IPC_DLI_BLEND_CONST 0x0080ff02 + +#define FD1_IPC_DLI_HGAIN 0x0124 +#define FD1_IPC_DLI_HGAIN_CONST 0x001000ff + +#define FD1_IPC_DLI_SPRS 0x0128 +#define FD1_IPC_DLI_SPRS_CONST 0x009004ff + +#define FD1_IPC_DLI_ANGLE 0x012c +#define FD1_IPC_DLI_ANGLE_CONST 0x0004080c + +#define FD1_IPC_DLI_ISOPIX0 0x0130 +#define FD1_IPC_DLI_ISOPIX0_CONST 0xff10ff10 + +#define FD1_IPC_DLI_ISOPIX1 0x0134 +#define FD1_IPC_DLI_ISOPIX1_CONST 0x0000ff10 + +/* Sensor registers */ +#define FD1_IPC_SENSOR_TH0 0x0140 +#define FD1_IPC_SENSOR_TH0_CONST 0x20208080 + +#define FD1_IPC_SENSOR_TH1 0x0144 +#define FD1_IPC_SENSOR_TH1_CONST 0 + +#define FD1_IPC_SENSOR_CTL0 0x0170 +#define FD1_IPC_SENSOR_CTL0_CONST 0x00002201 + +#define FD1_IPC_SENSOR_CTL1 0x0174 +#define FD1_IPC_SENSOR_CTL1_CONST 0 + +#define FD1_IPC_SENSOR_CTL2 0x0178 +#define FD1_IPC_SENSOR_CTL2_X_SHIFT 16 +#define FD1_IPC_SENSOR_CTL2_Y_SHIFT 0 + +#define FD1_IPC_SENSOR_CTL3 0x017c +#define FD1_IPC_SENSOR_CTL3_0_SHIFT 16 +#define FD1_IPC_SENSOR_CTL3_1_SHIFT 0 + +/* Line memory pixel number register */ +#define FD1_IPC_LMEM 0x01e0 +#define FD1_IPC_LMEM_LINEAR 1024 +#define FD1_IPC_LMEM_TILE 960 + +/* Internal Data (HW Version) */ +#define FD1_IP_INTDATA 0x0800 +#define FD1_IP_H3 0x02010101 +#define FD1_IP_M3W 0x02010202 + +/* LUTs */ +#define FD1_LUT_DIF_ADJ 0x1000 +#define FD1_LUT_SAD_ADJ 0x1400 +#define FD1_LUT_BLD_GAIN 0x1800 +#define FD1_LUT_DIF_GAIN 0x1c00 +#define FD1_LUT_MDET 0x2000 + +/** + * struct fdp1_fmt - The FDP1 internal format data + * @fourcc: the fourcc code, to match the V4L2 API + * @bpp: bits per pixel per plane + * @num_planes: number of planes + * @hsub: horizontal subsampling factor + * @vsub: vertical subsampling factor + * @fmt: 7-bit format code for the fdp1 hardware + * @swap_yc: the Y and C components are swapped (Y comes before C) + * @swap_uv: the U and V components are swapped (V comes before U) + * @swap: swap register control + * @types: types of queue this format is applicable to + */ +struct fdp1_fmt { + u32 fourcc; + u8 bpp[3]; + u8 num_planes; + u8 hsub; + u8 vsub; + u8 fmt; + bool swap_yc; + bool swap_uv; + u8 swap; + u8 types; +}; + +static const struct fdp1_fmt fdp1_formats[] = { + /* RGB formats are only supported by the Write Pixel Formatter */ + + { V4L2_PIX_FMT_RGB332, { 8, 0, 0 }, 1, 1, 1, 0x00, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_XRGB444, { 16, 0, 0 }, 1, 1, 1, 0x01, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_XRGB555, { 16, 0, 0 }, 1, 1, 1, 0x04, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_RGB565, { 16, 0, 0 }, 1, 1, 1, 0x06, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_ABGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_XBGR32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_ARGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_XRGB32, { 32, 0, 0 }, 1, 1, 1, 0x13, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_RGB24, { 24, 0, 0 }, 1, 1, 1, 0x15, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_BGR24, { 24, 0, 0 }, 1, 1, 1, 0x18, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_ARGB444, { 16, 0, 0 }, 1, 1, 1, 0x19, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD, + FDP1_CAPTURE }, + { V4L2_PIX_FMT_ARGB555, { 16, 0, 0 }, 1, 1, 1, 0x1b, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD, + FDP1_CAPTURE }, + + /* YUV Formats are supported by Read and Write Pixel Formatters */ + + { V4L2_PIX_FMT_NV16M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_NV61M, { 8, 16, 0 }, 2, 2, 1, 0x41, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_NV12M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_NV21M, { 8, 16, 0 }, 2, 2, 2, 0x42, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_UYVY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_VYUY, { 16, 0, 0 }, 1, 2, 1, 0x47, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YUYV, { 16, 0, 0 }, 1, 2, 1, 0x47, true, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YVYU, { 16, 0, 0 }, 1, 2, 1, 0x47, true, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YUV444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YVU444M, { 8, 8, 8 }, 3, 1, 1, 0x4a, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YUV422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YVU422M, { 8, 8, 8 }, 3, 2, 1, 0x4b, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YUV420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, false, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, + { V4L2_PIX_FMT_YVU420M, { 8, 8, 8 }, 3, 2, 2, 0x4c, false, true, + FD1_RWPF_SWAP_LLWD | FD1_RWPF_SWAP_LWRD | + FD1_RWPF_SWAP_WORD | FD1_RWPF_SWAP_BYTE, + FDP1_CAPTURE | FDP1_OUTPUT }, +}; + +static int fdp1_fmt_is_rgb(const struct fdp1_fmt *fmt) +{ + return fmt->fmt <= 0x1b; /* Last RGB code */ +} + +/* + * FDP1 Lookup tables range from 0...255 only + * + * Each table must be less than 256 entries, and all tables + * are padded out to 256 entries by duplicating the last value. + */ +static const u8 fdp1_diff_adj[] = { + 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf, + 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3, + 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, +}; + +static const u8 fdp1_sad_adj[] = { + 0x00, 0x24, 0x43, 0x5e, 0x76, 0x8c, 0x9e, 0xaf, + 0xbd, 0xc9, 0xd4, 0xdd, 0xe4, 0xea, 0xef, 0xf3, + 0xf6, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, +}; + +static const u8 fdp1_bld_gain[] = { + 0x80, +}; + +static const u8 fdp1_dif_gain[] = { + 0x80, +}; + +static const u8 fdp1_mdet[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +/* Per-queue, driver-specific private data */ +struct fdp1_q_data { + const struct fdp1_fmt *fmt; + struct v4l2_pix_format_mplane format; + + unsigned int vsize; + unsigned int stride_y; + unsigned int stride_c; +}; + +static const struct fdp1_fmt *fdp1_find_format(u32 pixelformat) +{ + const struct fdp1_fmt *fmt; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fdp1_formats); i++) { + fmt = &fdp1_formats[i]; + if (fmt->fourcc == pixelformat) + return fmt; + } + + return NULL; +} + +enum fdp1_deint_mode { + FDP1_PROGRESSIVE = 0, /* Must be zero when !deinterlacing */ + FDP1_ADAPT2D3D, + FDP1_FIXED2D, + FDP1_FIXED3D, + FDP1_PREVFIELD, + FDP1_NEXTFIELD, +}; + +#define FDP1_DEINT_MODE_USES_NEXT(mode) \ + (mode == FDP1_ADAPT2D3D || \ + mode == FDP1_FIXED3D || \ + mode == FDP1_NEXTFIELD) + +#define FDP1_DEINT_MODE_USES_PREV(mode) \ + (mode == FDP1_ADAPT2D3D || \ + mode == FDP1_FIXED3D || \ + mode == FDP1_PREVFIELD) + +/* + * FDP1 operates on potentially 3 fields, which are tracked + * from the VB buffers using this context structure. + * Will always be a field or a full frame, never two fields. + */ +struct fdp1_field_buffer { + struct vb2_v4l2_buffer *vb; + dma_addr_t addrs[3]; + + /* Should be NONE:TOP:BOTTOM only */ + enum v4l2_field field; + + /* Flag to indicate this is the last field in the vb */ + bool last_field; + + /* Buffer queue lists */ + struct list_head list; +}; + +struct fdp1_buffer { + struct v4l2_m2m_buffer m2m_buf; + struct fdp1_field_buffer fields[2]; + unsigned int num_fields; +}; + +static inline struct fdp1_buffer *to_fdp1_buffer(struct vb2_v4l2_buffer *vb) +{ + return container_of(vb, struct fdp1_buffer, m2m_buf.vb); +} + +struct fdp1_job { + struct fdp1_field_buffer *previous; + struct fdp1_field_buffer *active; + struct fdp1_field_buffer *next; + struct fdp1_field_buffer *dst; + + /* A job can only be on one list at a time */ + struct list_head list; +}; + +struct fdp1_dev { + struct v4l2_device v4l2_dev; + struct video_device vfd; + + struct mutex dev_mutex; + spinlock_t irqlock; + spinlock_t device_process_lock; + + void __iomem *regs; + unsigned int irq; + struct device *dev; + + /* Job Queues */ + struct fdp1_job jobs[FDP1_NUMBER_JOBS]; + struct list_head free_job_list; + struct list_head queued_job_list; + struct list_head hw_job_list; + + unsigned int clk_rate; + + struct rcar_fcp_device *fcp; + struct v4l2_m2m_dev *m2m_dev; +}; + +struct fdp1_ctx { + struct v4l2_fh fh; + struct fdp1_dev *fdp1; + + struct v4l2_ctrl_handler hdl; + unsigned int sequence; + + /* Processed buffers in this transaction */ + u8 num_processed; + + /* Transaction length (i.e. how many buffers per transaction) */ + u32 translen; + + /* Abort requested by m2m */ + int aborting; + + /* Deinterlace processing mode */ + enum fdp1_deint_mode deint_mode; + + /* + * Adaptive 2D/3D mode uses a shared mask + * This is allocated at streamon, if the ADAPT2D3D mode + * is requested + */ + unsigned int smsk_size; + dma_addr_t smsk_addr[2]; + void *smsk_cpu; + + /* Capture pipeline, can specify an alpha value + * for supported formats. 0-255 only + */ + unsigned char alpha; + + /* Source and destination queue data */ + struct fdp1_q_data out_q; /* HW Source */ + struct fdp1_q_data cap_q; /* HW Destination */ + + /* + * Field Queues + * Interlaced fields are used on 3 occasions, and tracked in this list. + * + * V4L2 Buffers are tracked inside the fdp1_buffer + * and released when the last 'field' completes + */ + struct list_head fields_queue; + unsigned int buffers_queued; + + /* + * For de-interlacing we need to track our previous buffer + * while preparing our job lists. + */ + struct fdp1_field_buffer *previous; +}; + +static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh) +{ + return container_of(fh, struct fdp1_ctx, fh); +} + +static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx, + enum v4l2_buf_type type) +{ + if (V4L2_TYPE_IS_OUTPUT(type)) + return &ctx->out_q; + else + return &ctx->cap_q; +} + +/* + * list_remove_job: Take the first item off the specified job list + * + * Returns: pointer to a job, or NULL if the list is empty. + */ +static struct fdp1_job *list_remove_job(struct fdp1_dev *fdp1, + struct list_head *list) +{ + struct fdp1_job *job; + unsigned long flags; + + spin_lock_irqsave(&fdp1->irqlock, flags); + job = list_first_entry_or_null(list, struct fdp1_job, list); + if (job) + list_del(&job->list); + spin_unlock_irqrestore(&fdp1->irqlock, flags); + + return job; +} + +/* + * list_add_job: Add a job to the specified job list + * + * Returns: void - always succeeds + */ +static void list_add_job(struct fdp1_dev *fdp1, + struct list_head *list, + struct fdp1_job *job) +{ + unsigned long flags; + + spin_lock_irqsave(&fdp1->irqlock, flags); + list_add_tail(&job->list, list); + spin_unlock_irqrestore(&fdp1->irqlock, flags); +} + +static struct fdp1_job *fdp1_job_alloc(struct fdp1_dev *fdp1) +{ + return list_remove_job(fdp1, &fdp1->free_job_list); +} + +static void fdp1_job_free(struct fdp1_dev *fdp1, struct fdp1_job *job) +{ + /* Ensure that all residue from previous jobs is gone */ + memset(job, 0, sizeof(struct fdp1_job)); + + list_add_job(fdp1, &fdp1->free_job_list, job); +} + +static void queue_job(struct fdp1_dev *fdp1, struct fdp1_job *job) +{ + list_add_job(fdp1, &fdp1->queued_job_list, job); +} + +static struct fdp1_job *get_queued_job(struct fdp1_dev *fdp1) +{ + return list_remove_job(fdp1, &fdp1->queued_job_list); +} + +static void queue_hw_job(struct fdp1_dev *fdp1, struct fdp1_job *job) +{ + list_add_job(fdp1, &fdp1->hw_job_list, job); +} + +static struct fdp1_job *get_hw_queued_job(struct fdp1_dev *fdp1) +{ + return list_remove_job(fdp1, &fdp1->hw_job_list); +} + +/* + * Buffer lists handling + */ +static void fdp1_field_complete(struct fdp1_ctx *ctx, + struct fdp1_field_buffer *fbuf) +{ + /* job->previous may be on the first field */ + if (!fbuf) + return; + + if (fbuf->last_field) + v4l2_m2m_buf_done(fbuf->vb, VB2_BUF_STATE_DONE); +} + +static void fdp1_queue_field(struct fdp1_ctx *ctx, + struct fdp1_field_buffer *fbuf) +{ + unsigned long flags; + + spin_lock_irqsave(&ctx->fdp1->irqlock, flags); + list_add_tail(&fbuf->list, &ctx->fields_queue); + spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); + + ctx->buffers_queued++; +} + +static struct fdp1_field_buffer *fdp1_dequeue_field(struct fdp1_ctx *ctx) +{ + struct fdp1_field_buffer *fbuf; + unsigned long flags; + + ctx->buffers_queued--; + + spin_lock_irqsave(&ctx->fdp1->irqlock, flags); + fbuf = list_first_entry_or_null(&ctx->fields_queue, + struct fdp1_field_buffer, list); + if (fbuf) + list_del(&fbuf->list); + spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); + + return fbuf; +} + +/* + * Return the next field in the queue - or NULL, + * without removing the item from the list + */ +static struct fdp1_field_buffer *fdp1_peek_queued_field(struct fdp1_ctx *ctx) +{ + struct fdp1_field_buffer *fbuf; + unsigned long flags; + + spin_lock_irqsave(&ctx->fdp1->irqlock, flags); + fbuf = list_first_entry_or_null(&ctx->fields_queue, + struct fdp1_field_buffer, list); + spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); + + return fbuf; +} + +static u32 fdp1_read(struct fdp1_dev *fdp1, unsigned int reg) +{ + u32 value = ioread32(fdp1->regs + reg); + + if (debug >= 2) + dprintk(fdp1, "Read 0x%08x from 0x%04x\n", value, reg); + + return value; +} + +static void fdp1_write(struct fdp1_dev *fdp1, u32 val, unsigned int reg) +{ + if (debug >= 2) + dprintk(fdp1, "Write 0x%08x to 0x%04x\n", val, reg); + + iowrite32(val, fdp1->regs + reg); +} + +/* IPC registers are to be programmed with constant values */ +static void fdp1_set_ipc_dli(struct fdp1_ctx *ctx) +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + + fdp1_write(fdp1, FD1_IPC_SMSK_THRESH_CONST, FD1_IPC_SMSK_THRESH); + fdp1_write(fdp1, FD1_IPC_COMB_DET_CONST, FD1_IPC_COMB_DET); + fdp1_write(fdp1, FD1_IPC_MOTDEC_CONST, FD1_IPC_MOTDEC); + + fdp1_write(fdp1, FD1_IPC_DLI_BLEND_CONST, FD1_IPC_DLI_BLEND); + fdp1_write(fdp1, FD1_IPC_DLI_HGAIN_CONST, FD1_IPC_DLI_HGAIN); + fdp1_write(fdp1, FD1_IPC_DLI_SPRS_CONST, FD1_IPC_DLI_SPRS); + fdp1_write(fdp1, FD1_IPC_DLI_ANGLE_CONST, FD1_IPC_DLI_ANGLE); + fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX0_CONST, FD1_IPC_DLI_ISOPIX0); + fdp1_write(fdp1, FD1_IPC_DLI_ISOPIX1_CONST, FD1_IPC_DLI_ISOPIX1); +} + + +static void fdp1_set_ipc_sensor(struct fdp1_ctx *ctx) +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + struct fdp1_q_data *src_q_data = &ctx->out_q; + unsigned int x0, x1; + unsigned int hsize = src_q_data->format.width; + unsigned int vsize = src_q_data->format.height; + + x0 = hsize / 3; + x1 = 2 * hsize / 3; + + fdp1_write(fdp1, FD1_IPC_SENSOR_TH0_CONST, FD1_IPC_SENSOR_TH0); + fdp1_write(fdp1, FD1_IPC_SENSOR_TH1_CONST, FD1_IPC_SENSOR_TH1); + fdp1_write(fdp1, FD1_IPC_SENSOR_CTL0_CONST, FD1_IPC_SENSOR_CTL0); + fdp1_write(fdp1, FD1_IPC_SENSOR_CTL1_CONST, FD1_IPC_SENSOR_CTL1); + + fdp1_write(fdp1, ((hsize - 1) << FD1_IPC_SENSOR_CTL2_X_SHIFT) | + ((vsize - 1) << FD1_IPC_SENSOR_CTL2_Y_SHIFT), + FD1_IPC_SENSOR_CTL2); + + fdp1_write(fdp1, (x0 << FD1_IPC_SENSOR_CTL3_0_SHIFT) | + (x1 << FD1_IPC_SENSOR_CTL3_1_SHIFT), + FD1_IPC_SENSOR_CTL3); +} + +/* + * fdp1_write_lut: Write a padded LUT to the hw + * + * FDP1 uses constant data for de-interlacing processing, + * with large tables. These hardware tables are all 256 bytes + * long, however they often contain repeated data at the end. + * + * The last byte of the table is written to all remaining entries. + */ +static void fdp1_write_lut(struct fdp1_dev *fdp1, const u8 *lut, + unsigned int len, unsigned int base) +{ + unsigned int i; + u8 pad; + + /* Tables larger than the hw are clipped */ + len = min(len, 256u); + + for (i = 0; i < len; i++) + fdp1_write(fdp1, lut[i], base + (i*4)); + + /* Tables are padded with the last entry */ + pad = lut[i-1]; + + for (; i < 256; i++) + fdp1_write(fdp1, pad, base + (i*4)); +} + +static void fdp1_set_lut(struct fdp1_dev *fdp1) +{ + fdp1_write_lut(fdp1, fdp1_diff_adj, ARRAY_SIZE(fdp1_diff_adj), + FD1_LUT_DIF_ADJ); + fdp1_write_lut(fdp1, fdp1_sad_adj, ARRAY_SIZE(fdp1_sad_adj), + FD1_LUT_SAD_ADJ); + fdp1_write_lut(fdp1, fdp1_bld_gain, ARRAY_SIZE(fdp1_bld_gain), + FD1_LUT_BLD_GAIN); + fdp1_write_lut(fdp1, fdp1_dif_gain, ARRAY_SIZE(fdp1_dif_gain), + FD1_LUT_DIF_GAIN); + fdp1_write_lut(fdp1, fdp1_mdet, ARRAY_SIZE(fdp1_mdet), + FD1_LUT_MDET); +} + +static void fdp1_configure_rpf(struct fdp1_ctx *ctx, + struct fdp1_job *job) +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + u32 picture_size; + u32 pstride; + u32 format; + u32 smsk_addr; + + struct fdp1_q_data *q_data = &ctx->out_q; + + /* Picture size is common to Source and Destination frames */ + picture_size = (q_data->format.width << FD1_RPF_SIZE_H_SHIFT) + | (q_data->vsize << FD1_RPF_SIZE_V_SHIFT); + + /* Strides */ + pstride = q_data->stride_y << FD1_RPF_PSTRIDE_Y_SHIFT; + if (q_data->format.num_planes > 1) + pstride |= q_data->stride_c << FD1_RPF_PSTRIDE_C_SHIFT; + + /* Format control */ + format = q_data->fmt->fmt; + if (q_data->fmt->swap_yc) + format |= FD1_RPF_FORMAT_RSPYCS; + + if (q_data->fmt->swap_uv) + format |= FD1_RPF_FORMAT_RSPUVS; + + if (job->active->field == V4L2_FIELD_BOTTOM) { + format |= FD1_RPF_FORMAT_CF; /* Set for Bottom field */ + smsk_addr = ctx->smsk_addr[0]; + } else { + smsk_addr = ctx->smsk_addr[1]; + } + + /* Deint mode is non-zero when deinterlacing */ + if (ctx->deint_mode) + format |= FD1_RPF_FORMAT_CIPM; + + fdp1_write(fdp1, format, FD1_RPF_FORMAT); + fdp1_write(fdp1, q_data->fmt->swap, FD1_RPF_SWAP); + fdp1_write(fdp1, picture_size, FD1_RPF_SIZE); + fdp1_write(fdp1, pstride, FD1_RPF_PSTRIDE); + fdp1_write(fdp1, smsk_addr, FD1_RPF_SMSK_ADDR); + + /* Previous Field Channel (CH0) */ + if (job->previous) + fdp1_write(fdp1, job->previous->addrs[0], FD1_RPF0_ADDR_Y); + + /* Current Field Channel (CH1) */ + fdp1_write(fdp1, job->active->addrs[0], FD1_RPF1_ADDR_Y); + fdp1_write(fdp1, job->active->addrs[1], FD1_RPF1_ADDR_C0); + fdp1_write(fdp1, job->active->addrs[2], FD1_RPF1_ADDR_C1); + + /* Next Field Channel (CH2) */ + if (job->next) + fdp1_write(fdp1, job->next->addrs[0], FD1_RPF2_ADDR_Y); +} + +static void fdp1_configure_wpf(struct fdp1_ctx *ctx, + struct fdp1_job *job) +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + struct fdp1_q_data *src_q_data = &ctx->out_q; + struct fdp1_q_data *q_data = &ctx->cap_q; + u32 pstride; + u32 format; + u32 swap; + u32 rndctl; + + pstride = q_data->format.plane_fmt[0].bytesperline + << FD1_WPF_PSTRIDE_Y_SHIFT; + + if (q_data->format.num_planes > 1) + pstride |= q_data->format.plane_fmt[1].bytesperline + << FD1_WPF_PSTRIDE_C_SHIFT; + + format = q_data->fmt->fmt; /* Output Format Code */ + + if (q_data->fmt->swap_yc) + format |= FD1_WPF_FORMAT_WSPYCS; + + if (q_data->fmt->swap_uv) + format |= FD1_WPF_FORMAT_WSPUVS; + + if (fdp1_fmt_is_rgb(q_data->fmt)) { + /* Enable Colour Space conversion */ + format |= FD1_WPF_FORMAT_CSC; + + /* Set WRTM */ + if (src_q_data->format.ycbcr_enc == V4L2_YCBCR_ENC_709) + format |= FD1_WPF_FORMAT_WRTM_709_16; + else if (src_q_data->format.quantization == + V4L2_QUANTIZATION_FULL_RANGE) + format |= FD1_WPF_FORMAT_WRTM_601_0; + else + format |= FD1_WPF_FORMAT_WRTM_601_16; + } + + /* Set an alpha value into the Pad Value */ + format |= ctx->alpha << FD1_WPF_FORMAT_PDV_SHIFT; + + /* Determine picture rounding and clipping */ + rndctl = FD1_WPF_RNDCTL_CBRM; /* Rounding Off */ + rndctl |= FD1_WPF_RNDCTL_CLMD_NOCLIP; + + /* WPF Swap needs both ISWAP and OSWAP setting */ + swap = q_data->fmt->swap << FD1_WPF_SWAP_OSWAP_SHIFT; + swap |= src_q_data->fmt->swap << FD1_WPF_SWAP_SSWAP_SHIFT; + + fdp1_write(fdp1, format, FD1_WPF_FORMAT); + fdp1_write(fdp1, rndctl, FD1_WPF_RNDCTL); + fdp1_write(fdp1, swap, FD1_WPF_SWAP); + fdp1_write(fdp1, pstride, FD1_WPF_PSTRIDE); + + fdp1_write(fdp1, job->dst->addrs[0], FD1_WPF_ADDR_Y); + fdp1_write(fdp1, job->dst->addrs[1], FD1_WPF_ADDR_C0); + fdp1_write(fdp1, job->dst->addrs[2], FD1_WPF_ADDR_C1); +} + +static void fdp1_configure_deint_mode(struct fdp1_ctx *ctx, + struct fdp1_job *job) +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + u32 opmode = FD1_CTL_OPMODE_VIMD_NOINTERRUPT; + u32 ipcmode = FD1_IPC_MODE_DLI; /* Always set */ + u32 channels = FD1_CTL_CHACT_WR | FD1_CTL_CHACT_RD1; /* Always on */ + + /* De-interlacing Mode */ + switch (ctx->deint_mode) { + default: + case FDP1_PROGRESSIVE: + dprintk(fdp1, "Progressive Mode\n"); + opmode |= FD1_CTL_OPMODE_PRG; + ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; + break; + case FDP1_ADAPT2D3D: + dprintk(fdp1, "Adapt2D3D Mode\n"); + if (ctx->sequence == 0 || ctx->aborting) + ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; + else + ipcmode |= FD1_IPC_MODE_DIM_ADAPT2D3D; + + if (ctx->sequence > 1) { + channels |= FD1_CTL_CHACT_SMW; + channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2; + } + + if (ctx->sequence > 2) + channels |= FD1_CTL_CHACT_SMR; + + break; + case FDP1_FIXED3D: + dprintk(fdp1, "Fixed 3D Mode\n"); + ipcmode |= FD1_IPC_MODE_DIM_FIXED3D; + /* Except for first and last frame, enable all channels */ + if (!(ctx->sequence == 0 || ctx->aborting)) + channels |= FD1_CTL_CHACT_RD0 | FD1_CTL_CHACT_RD2; + break; + case FDP1_FIXED2D: + dprintk(fdp1, "Fixed 2D Mode\n"); + ipcmode |= FD1_IPC_MODE_DIM_FIXED2D; + /* No extra channels enabled */ + break; + case FDP1_PREVFIELD: + dprintk(fdp1, "Previous Field Mode\n"); + ipcmode |= FD1_IPC_MODE_DIM_PREVFIELD; + channels |= FD1_CTL_CHACT_RD0; /* Previous */ + break; + case FDP1_NEXTFIELD: + dprintk(fdp1, "Next Field Mode\n"); + ipcmode |= FD1_IPC_MODE_DIM_NEXTFIELD; + channels |= FD1_CTL_CHACT_RD2; /* Next */ + break; + } + + fdp1_write(fdp1, channels, FD1_CTL_CHACT); + fdp1_write(fdp1, opmode, FD1_CTL_OPMODE); + fdp1_write(fdp1, ipcmode, FD1_IPC_MODE); +} + +/* + * fdp1_device_process() - Run the hardware + * + * Configure and start the hardware to generate a single frame + * of output given our input parameters. + */ +static int fdp1_device_process(struct fdp1_ctx *ctx) + +{ + struct fdp1_dev *fdp1 = ctx->fdp1; + struct fdp1_job *job; + unsigned long flags; + + spin_lock_irqsave(&fdp1->device_process_lock, flags); + + /* Get a job to process */ + job = get_queued_job(fdp1); + if (!job) { + /* + * VINT can call us to see if we can queue another job. + * If we have no work to do, we simply return. + */ + spin_unlock_irqrestore(&fdp1->device_process_lock, flags); + return 0; + } + + /* First Frame only? ... */ + fdp1_write(fdp1, FD1_CTL_CLKCTRL_CSTP_N, FD1_CTL_CLKCTRL); + + /* Set the mode, and configuration */ + fdp1_configure_deint_mode(ctx, job); + + /* DLI Static Configuration */ + fdp1_set_ipc_dli(ctx); + + /* Sensor Configuration */ + fdp1_set_ipc_sensor(ctx); + + /* Setup the source picture */ + fdp1_configure_rpf(ctx, job); + + /* Setup the destination picture */ + fdp1_configure_wpf(ctx, job); + + /* Line Memory Pixel Number Register for linear access */ + fdp1_write(fdp1, FD1_IPC_LMEM_LINEAR, FD1_IPC_LMEM); + + /* Enable Interrupts */ + fdp1_write(fdp1, FD1_CTL_IRQ_MASK, FD1_CTL_IRQENB); + + /* Finally, the Immediate Registers */ + + /* This job is now in the HW queue */ + queue_hw_job(fdp1, job); + + /* Start the command */ + fdp1_write(fdp1, FD1_CTL_CMD_STRCMD, FD1_CTL_CMD); + + /* Registers will update to HW at next VINT */ + fdp1_write(fdp1, FD1_CTL_REGEND_REGEND, FD1_CTL_REGEND); + + /* Enable VINT Generator */ + fdp1_write(fdp1, FD1_CTL_SGCMD_SGEN, FD1_CTL_SGCMD); + + spin_unlock_irqrestore(&fdp1->device_process_lock, flags); + + return 0; +} + +/* + * mem2mem callbacks + */ + +/** + * job_ready() - check whether an instance is ready to be scheduled to run + */ +static int fdp1_m2m_job_ready(void *priv) +{ + struct fdp1_ctx *ctx = priv; + struct fdp1_q_data *src_q_data = &ctx->out_q; + int srcbufs = 1; + int dstbufs = 1; + + dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n", + v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx), + v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)); + + /* One output buffer is required for each field */ + if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) + dstbufs = 2; + + if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < srcbufs + || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < dstbufs) { + dprintk(ctx->fdp1, "Not enough buffers available\n"); + return 0; + } + + return 1; +} + +static void fdp1_m2m_job_abort(void *priv) +{ + struct fdp1_ctx *ctx = priv; + + dprintk(ctx->fdp1, "+\n"); + + /* Will cancel the transaction in the next interrupt handler */ + ctx->aborting = 1; + + /* Immediate abort sequence */ + fdp1_write(ctx->fdp1, 0, FD1_CTL_SGCMD); + fdp1_write(ctx->fdp1, FD1_CTL_SRESET_SRST, FD1_CTL_SRESET); +} + +/* + * fdp1_prepare_job: Prepare and queue a new job for a single action of work + * + * Prepare the next field, (or frame in progressive) and an output + * buffer for the hardware to perform a single operation. + */ +static struct fdp1_job *fdp1_prepare_job(struct fdp1_ctx *ctx) +{ + struct vb2_v4l2_buffer *vbuf; + struct fdp1_buffer *fbuf; + struct fdp1_dev *fdp1 = ctx->fdp1; + struct fdp1_job *job; + unsigned int buffers_required = 1; + + dprintk(fdp1, "+\n"); + + if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) + buffers_required = 2; + + if (ctx->buffers_queued < buffers_required) + return NULL; + + job = fdp1_job_alloc(fdp1); + if (!job) { + dprintk(fdp1, "No free jobs currently available\n"); + return NULL; + } + + job->active = fdp1_dequeue_field(ctx); + if (!job->active) { + /* Buffer check should prevent this ever happening */ + dprintk(fdp1, "No input buffers currently available\n"); + + fdp1_job_free(fdp1, job); + return NULL; + } + + dprintk(fdp1, "+ Buffer en-route...\n"); + + /* Source buffers have been prepared on our buffer_queue + * Prepare our Output buffer + */ + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + fbuf = to_fdp1_buffer(vbuf); + job->dst = &fbuf->fields[0]; + + job->active->vb->sequence = ctx->sequence; + job->dst->vb->sequence = ctx->sequence; + ctx->sequence++; + + if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) { + job->previous = ctx->previous; + + /* Active buffer becomes the next job's previous buffer */ + ctx->previous = job->active; + } + + if (FDP1_DEINT_MODE_USES_NEXT(ctx->deint_mode)) { + /* Must be called after 'active' is dequeued */ + job->next = fdp1_peek_queued_field(ctx); + } + + /* Transfer timestamps and flags from src->dst */ + + job->dst->vb->vb2_buf.timestamp = job->active->vb->vb2_buf.timestamp; + + job->dst->vb->flags = job->active->vb->flags & + V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + + /* Ideally, the frame-end function will just 'check' to see + * if there are more jobs instead + */ + ctx->translen++; + + /* Finally, Put this job on the processing queue */ + queue_job(fdp1, job); + + dprintk(fdp1, "Job Queued translen = %d\n", ctx->translen); + + return job; +} + +/* fdp1_m2m_device_run() - prepares and starts the device for an M2M task + * + * A single input buffer is taken and serialised into our fdp1_buffer + * queue. The queue is then processed to create as many jobs as possible + * from our available input. + */ +static void fdp1_m2m_device_run(void *priv) +{ + struct fdp1_ctx *ctx = priv; + struct fdp1_dev *fdp1 = ctx->fdp1; + struct vb2_v4l2_buffer *src_vb; + struct fdp1_buffer *buf; + unsigned int i; + + dprintk(fdp1, "+\n"); + + ctx->translen = 0; + + /* Get our incoming buffer of either one or two fields, or one frame */ + src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + buf = to_fdp1_buffer(src_vb); + + for (i = 0; i < buf->num_fields; i++) { + struct fdp1_field_buffer *fbuf = &buf->fields[i]; + + fdp1_queue_field(ctx, fbuf); + dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n", + i, fbuf->last_field); + } + + /* Queue as many jobs as our data provides for */ + while (fdp1_prepare_job(ctx)) + ; + + if (ctx->translen == 0) { + dprintk(fdp1, "No jobs were processed. M2M action complete\n"); + v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx); + return; + } + + /* Kick the job processing action */ + fdp1_device_process(ctx); +} + +/* + * device_frame_end: + * + * Handles the M2M level after a buffer completion event. + */ +static void device_frame_end(struct fdp1_dev *fdp1, + enum vb2_buffer_state state) +{ + struct fdp1_ctx *ctx; + unsigned long flags; + struct fdp1_job *job = get_hw_queued_job(fdp1); + + dprintk(fdp1, "+\n"); + + ctx = v4l2_m2m_get_curr_priv(fdp1->m2m_dev); + + if (ctx == NULL) { + v4l2_err(&fdp1->v4l2_dev, + "Instance released before the end of transaction\n"); + return; + } + + ctx->num_processed++; + + /* + * fdp1_field_complete will call buf_done only when the last vb2_buffer + * reference is complete + */ + if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) + fdp1_field_complete(ctx, job->previous); + else + fdp1_field_complete(ctx, job->active); + + spin_lock_irqsave(&fdp1->irqlock, flags); + v4l2_m2m_buf_done(job->dst->vb, state); + job->dst = NULL; + spin_unlock_irqrestore(&fdp1->irqlock, flags); + + /* Move this job back to the free job list */ + fdp1_job_free(fdp1, job); + + dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n", + ctx->num_processed, ctx->translen); + + if (ctx->num_processed == ctx->translen || + ctx->aborting) { + dprintk(ctx->fdp1, "Finishing transaction\n"); + ctx->num_processed = 0; + v4l2_m2m_job_finish(fdp1->m2m_dev, ctx->fh.m2m_ctx); + } else { + /* + * For pipelined performance support, this would + * be called from a VINT handler + */ + fdp1_device_process(ctx); + } +} + +/* + * video ioctls + */ +static int fdp1_vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); + strlcpy(cap->card, DRIVER_NAME, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s", DRIVER_NAME); + return 0; +} + +static int fdp1_enum_fmt(struct v4l2_fmtdesc *f, u32 type) +{ + unsigned int i, num; + + num = 0; + + for (i = 0; i < ARRAY_SIZE(fdp1_formats); ++i) { + if (fdp1_formats[i].types & type) { + if (num == f->index) + break; + ++num; + } + } + + /* Format not found */ + if (i >= ARRAY_SIZE(fdp1_formats)) + return -EINVAL; + + /* Format found */ + f->pixelformat = fdp1_formats[i].fourcc; + + return 0; +} + +static int fdp1_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return fdp1_enum_fmt(f, FDP1_CAPTURE); +} + +static int fdp1_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return fdp1_enum_fmt(f, FDP1_OUTPUT); +} + +static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f) +{ + struct fdp1_q_data *q_data; + struct fdp1_ctx *ctx = fh_to_ctx(priv); + + if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type)) + return -EINVAL; + + q_data = get_q_data(ctx, f->type); + f->fmt.pix_mp = q_data->format; + + return 0; +} + +static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix, + const struct fdp1_fmt *fmt) +{ + unsigned int i; + + /* Compute and clamp the stride and image size. */ + for (i = 0; i < min_t(unsigned int, fmt->num_planes, 2U); ++i) { + unsigned int hsub = i > 0 ? fmt->hsub : 1; + unsigned int vsub = i > 0 ? fmt->vsub : 1; + /* From VSP : TODO: Confirm alignment limits for FDP1 */ + unsigned int align = 128; + unsigned int bpl; + + bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline, + pix->width / hsub * fmt->bpp[i] / 8, + round_down(FDP1_MAX_STRIDE, align)); + + pix->plane_fmt[i].bytesperline = round_up(bpl, align); + pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline + * pix->height / vsub; + + memset(pix->plane_fmt[i].reserved, 0, + sizeof(pix->plane_fmt[i].reserved)); + } + + if (fmt->num_planes == 3) { + /* The two chroma planes must have the same stride. */ + pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline; + pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage; + + memset(pix->plane_fmt[2].reserved, 0, + sizeof(pix->plane_fmt[2].reserved)); + } +} + +static void fdp1_try_fmt_output(struct fdp1_ctx *ctx, + const struct fdp1_fmt **fmtinfo, + struct v4l2_pix_format_mplane *pix) +{ + const struct fdp1_fmt *fmt; + unsigned int width; + unsigned int height; + + /* Validate the pixel format to ensure the output queue supports it. */ + fmt = fdp1_find_format(pix->pixelformat); + if (!fmt || !(fmt->types & FDP1_OUTPUT)) + fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV); + + if (fmtinfo) + *fmtinfo = fmt; + + pix->pixelformat = fmt->fourcc; + pix->num_planes = fmt->num_planes; + + /* + * Progressive video and all interlaced field orders are acceptable. + * Default to V4L2_FIELD_INTERLACED. + */ + if (pix->field != V4L2_FIELD_NONE && + pix->field != V4L2_FIELD_ALTERNATE && + !V4L2_FIELD_HAS_BOTH(pix->field)) + pix->field = V4L2_FIELD_INTERLACED; + + /* + * The deinterlacer doesn't care about the colorspace, accept all values + * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion + * at the output of the deinterlacer supports a subset of encodings and + * quantization methods and will only be available when the colorspace + * allows it. + */ + if (pix->colorspace == V4L2_COLORSPACE_DEFAULT) + pix->colorspace = V4L2_COLORSPACE_SMPTE170M; + + /* + * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp + * them to the supported frame size range. The height boundary are + * related to the full frame, divide them by two when the format passes + * fields in separate buffers. + */ + width = round_down(pix->width, fmt->hsub); + pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W); + + height = round_down(pix->height, fmt->vsub); + if (pix->field == V4L2_FIELD_ALTERNATE) + pix->height = clamp(height, FDP1_MIN_H / 2, FDP1_MAX_H / 2); + else + pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H); + + fdp1_compute_stride(pix, fmt); +} + +static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx, + const struct fdp1_fmt **fmtinfo, + struct v4l2_pix_format_mplane *pix) +{ + struct fdp1_q_data *src_data = &ctx->out_q; + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + const struct fdp1_fmt *fmt; + bool allow_rgb; + + /* + * Validate the pixel format. We can only accept RGB output formats if + * the input encoding and quantization are compatible with the format + * conversions supported by the hardware. The supported combinations are + * + * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE + * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE + * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE + */ + colorspace = src_data->format.colorspace; + + ycbcr_enc = src_data->format.ycbcr_enc; + if (ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) + ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace); + + quantization = src_data->format.quantization; + if (quantization == V4L2_QUANTIZATION_DEFAULT) + quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace, + ycbcr_enc); + + allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 || + (ycbcr_enc == V4L2_YCBCR_ENC_709 && + quantization == V4L2_QUANTIZATION_LIM_RANGE); + + fmt = fdp1_find_format(pix->pixelformat); + if (!fmt || (!allow_rgb && fdp1_fmt_is_rgb(fmt))) + fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV); + + if (fmtinfo) + *fmtinfo = fmt; + + pix->pixelformat = fmt->fourcc; + pix->num_planes = fmt->num_planes; + pix->field = V4L2_FIELD_NONE; + + /* + * The colorspace on the capture queue is copied from the output queue + * as the hardware can't change the colorspace. It can convert YCbCr to + * RGB though, in which case the encoding and quantization are set to + * default values as anything else wouldn't make sense. + */ + pix->colorspace = src_data->format.colorspace; + pix->xfer_func = src_data->format.xfer_func; + + if (fdp1_fmt_is_rgb(fmt)) { + pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + pix->quantization = V4L2_QUANTIZATION_DEFAULT; + } else { + pix->ycbcr_enc = src_data->format.ycbcr_enc; + pix->quantization = src_data->format.quantization; + } + + /* + * The frame width is identical to the output queue, and the height is + * either doubled or identical depending on whether the output queue + * field order contains one or two fields per frame. + */ + pix->width = src_data->format.width; + if (src_data->format.field == V4L2_FIELD_ALTERNATE) + pix->height = 2 * src_data->format.height; + else + pix->height = src_data->format.height; + + fdp1_compute_stride(pix, fmt); +} + +static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f) +{ + struct fdp1_ctx *ctx = fh_to_ctx(priv); + + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp); + else + fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp); + + dprintk(ctx->fdp1, "Try %s format: %4s (0x%08x) %ux%u field %u\n", + V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture", + (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat, + f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field); + + return 0; +} + +static void fdp1_set_format(struct fdp1_ctx *ctx, + struct v4l2_pix_format_mplane *pix, + enum v4l2_buf_type type) +{ + struct fdp1_q_data *q_data = get_q_data(ctx, type); + const struct fdp1_fmt *fmtinfo; + + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + fdp1_try_fmt_output(ctx, &fmtinfo, pix); + else + fdp1_try_fmt_capture(ctx, &fmtinfo, pix); + + q_data->fmt = fmtinfo; + q_data->format = *pix; + + q_data->vsize = pix->height; + if (pix->field != V4L2_FIELD_NONE) + q_data->vsize /= 2; + + q_data->stride_y = pix->plane_fmt[0].bytesperline; + q_data->stride_c = pix->plane_fmt[1].bytesperline; + + /* Adjust strides for interleaved buffers */ + if (pix->field == V4L2_FIELD_INTERLACED || + pix->field == V4L2_FIELD_INTERLACED_TB || + pix->field == V4L2_FIELD_INTERLACED_BT) { + q_data->stride_y *= 2; + q_data->stride_c *= 2; + } + + /* Propagate the format from the output node to the capture node. */ + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + struct fdp1_q_data *dst_data = &ctx->cap_q; + + /* + * Copy the format, clear the per-plane bytes per line and image + * size, override the field and double the height if needed. + */ + dst_data->format = q_data->format; + memset(dst_data->format.plane_fmt, 0, + sizeof(dst_data->format.plane_fmt)); + + dst_data->format.field = V4L2_FIELD_NONE; + if (pix->field == V4L2_FIELD_ALTERNATE) + dst_data->format.height *= 2; + + fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format); + + dst_data->vsize = dst_data->format.height; + dst_data->stride_y = dst_data->format.plane_fmt[0].bytesperline; + dst_data->stride_c = dst_data->format.plane_fmt[1].bytesperline; + } +} + +static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f) +{ + struct fdp1_ctx *ctx = fh_to_ctx(priv); + struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; + struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type); + + if (vb2_is_busy(vq)) { + v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__); + return -EBUSY; + } + + fdp1_set_format(ctx, &f->fmt.pix_mp, f->type); + + dprintk(ctx->fdp1, "Set %s format: %4s (0x%08x) %ux%u field %u\n", + V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture", + (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat, + f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field); + + return 0; +} + +static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl) +{ + struct fdp1_ctx *ctx = + container_of(ctrl->handler, struct fdp1_ctx, hdl); + struct fdp1_q_data *src_q_data = &ctx->out_q; + + switch (ctrl->id) { + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) + ctrl->val = 2; + else + ctrl->val = 1; + return 0; + } + + return 1; +} + +static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct fdp1_ctx *ctx = + container_of(ctrl->handler, struct fdp1_ctx, hdl); + + switch (ctrl->id) { + case V4L2_CID_ALPHA_COMPONENT: + ctx->alpha = ctrl->val; + break; + + case V4L2_CID_DEINTERLACING_MODE: + ctx->deint_mode = ctrl->val; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops fdp1_ctrl_ops = { + .s_ctrl = fdp1_s_ctrl, + .g_volatile_ctrl = fdp1_g_ctrl, +}; + +static const char * const fdp1_ctrl_deint_menu[] = { + "Progressive", + "Adaptive 2D/3D", + "Fixed 2D", + "Fixed 3D", + "Previous field", + "Next field", + NULL +}; + +static const struct v4l2_ioctl_ops fdp1_ioctl_ops = { + .vidioc_querycap = fdp1_vidioc_querycap, + + .vidioc_enum_fmt_vid_cap_mplane = fdp1_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out_mplane = fdp1_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap_mplane = fdp1_g_fmt, + .vidioc_g_fmt_vid_out_mplane = fdp1_g_fmt, + .vidioc_try_fmt_vid_cap_mplane = fdp1_try_fmt, + .vidioc_try_fmt_vid_out_mplane = fdp1_try_fmt, + .vidioc_s_fmt_vid_cap_mplane = fdp1_s_fmt, + .vidioc_s_fmt_vid_out_mplane = fdp1_s_fmt, + + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +/* + * Queue operations + */ + +static int fdp1_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], + struct device *alloc_ctxs[]) +{ + struct fdp1_ctx *ctx = vb2_get_drv_priv(vq); + struct fdp1_q_data *q_data; + unsigned int i; + + q_data = get_q_data(ctx, vq->type); + + if (*nplanes) { + if (*nplanes > FDP1_MAX_PLANES) + return -EINVAL; + + return 0; + } + + *nplanes = q_data->format.num_planes; + + for (i = 0; i < *nplanes; i++) + sizes[i] = q_data->format.plane_fmt[i].sizeimage; + + return 0; +} + +static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data, + struct vb2_v4l2_buffer *vbuf, + unsigned int field_num) +{ + struct fdp1_buffer *buf = to_fdp1_buffer(vbuf); + struct fdp1_field_buffer *fbuf = &buf->fields[field_num]; + unsigned int num_fields; + unsigned int i; + + num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1; + + fbuf->vb = vbuf; + fbuf->last_field = (field_num + 1) == num_fields; + + for (i = 0; i < vbuf->vb2_buf.num_planes; ++i) + fbuf->addrs[i] = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, i); + + switch (vbuf->field) { + case V4L2_FIELD_INTERLACED: + /* + * Interlaced means bottom-top for 60Hz TV standards (NTSC) and + * top-bottom for 50Hz. As TV standards are not applicable to + * the mem-to-mem API, use the height as a heuristic. + */ + fbuf->field = (q_data->format.height < 576) == field_num + ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + break; + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_SEQ_TB: + fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP; + break; + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_SEQ_BT: + fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + break; + default: + fbuf->field = vbuf->field; + break; + } + + /* Buffer is completed */ + if (!field_num) + return; + + /* Adjust buffer addresses for second field */ + switch (vbuf->field) { + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + for (i = 0; i < vbuf->vb2_buf.num_planes; i++) + fbuf->addrs[i] += + (i == 0 ? q_data->stride_y : q_data->stride_c); + break; + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + for (i = 0; i < vbuf->vb2_buf.num_planes; i++) + fbuf->addrs[i] += q_data->vsize * + (i == 0 ? q_data->stride_y : q_data->stride_c); + break; + } +} + +static int fdp1_buf_prepare(struct vb2_buffer *vb) +{ + struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct fdp1_q_data *q_data = get_q_data(ctx, vb->vb2_queue->type); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct fdp1_buffer *buf = to_fdp1_buffer(vbuf); + unsigned int i; + + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + bool field_valid = true; + + /* Validate the buffer field. */ + switch (q_data->format.field) { + case V4L2_FIELD_NONE: + if (vbuf->field != V4L2_FIELD_NONE) + field_valid = false; + break; + + case V4L2_FIELD_ALTERNATE: + if (vbuf->field != V4L2_FIELD_TOP && + vbuf->field != V4L2_FIELD_BOTTOM) + field_valid = false; + break; + + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + if (vbuf->field != q_data->format.field) + field_valid = false; + break; + } + + if (!field_valid) { + dprintk(ctx->fdp1, + "buffer field %u invalid for format field %u\n", + vbuf->field, q_data->format.field); + return -EINVAL; + } + } else { + vbuf->field = V4L2_FIELD_NONE; + } + + /* Validate the planes sizes. */ + for (i = 0; i < q_data->format.num_planes; i++) { + unsigned long size = q_data->format.plane_fmt[i].sizeimage; + + if (vb2_plane_size(vb, i) < size) { + dprintk(ctx->fdp1, + "data will not fit into plane [%u/%u] (%lu < %lu)\n", + i, q_data->format.num_planes, + vb2_plane_size(vb, i), size); + return -EINVAL; + } + + /* We have known size formats all around */ + vb2_set_plane_payload(vb, i, size); + } + + buf->num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1; + for (i = 0; i < buf->num_fields; ++i) + fdp1_buf_prepare_field(q_data, vbuf, i); + + return 0; +} + +static void fdp1_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); +} + +static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct fdp1_ctx *ctx = vb2_get_drv_priv(q); + struct fdp1_q_data *q_data = get_q_data(ctx, q->type); + + if (V4L2_TYPE_IS_OUTPUT(q->type)) { + /* + * Force our deint_mode when we are progressive, + * ignoring any setting on the device from the user, + * Otherwise, lock in the requested de-interlace mode. + */ + if (q_data->format.field == V4L2_FIELD_NONE) + ctx->deint_mode = FDP1_PROGRESSIVE; + + if (ctx->deint_mode == FDP1_ADAPT2D3D) { + u32 stride; + dma_addr_t smsk_base; + const u32 bpp = 2; /* bytes per pixel */ + + stride = round_up(q_data->format.width, 8); + + ctx->smsk_size = bpp * stride * q_data->vsize; + + ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev, + ctx->smsk_size, &smsk_base, GFP_KERNEL); + + if (ctx->smsk_cpu == NULL) { + dprintk(ctx->fdp1, "Failed to alloc smsk\n"); + return -ENOMEM; + } + + ctx->smsk_addr[0] = smsk_base; + ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2); + } + } + + return 0; +} + +static void fdp1_stop_streaming(struct vb2_queue *q) +{ + struct fdp1_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vbuf; + unsigned long flags; + + while (1) { + if (V4L2_TYPE_IS_OUTPUT(q->type)) + vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + if (vbuf == NULL) + break; + spin_lock_irqsave(&ctx->fdp1->irqlock, flags); + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags); + } + + /* Empty Output queues */ + if (V4L2_TYPE_IS_OUTPUT(q->type)) { + /* Empty our internal queues */ + struct fdp1_field_buffer *fbuf; + + /* Free any queued buffers */ + fbuf = fdp1_dequeue_field(ctx); + while (fbuf != NULL) { + fdp1_field_complete(ctx, fbuf); + fbuf = fdp1_dequeue_field(ctx); + } + + /* Free smsk_data */ + if (ctx->smsk_cpu) { + dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size, + ctx->smsk_cpu, ctx->smsk_addr[0]); + ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0; + ctx->smsk_cpu = NULL; + } + + WARN(!list_empty(&ctx->fields_queue), + "Buffer queue not empty"); + } else { + /* Empty Capture queues (Jobs) */ + struct fdp1_job *job; + + job = get_queued_job(ctx->fdp1); + while (job) { + if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode)) + fdp1_field_complete(ctx, job->previous); + else + fdp1_field_complete(ctx, job->active); + + v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR); + job->dst = NULL; + + job = get_queued_job(ctx->fdp1); + } + + /* Free any held buffer in the ctx */ + fdp1_field_complete(ctx, ctx->previous); + + WARN(!list_empty(&ctx->fdp1->queued_job_list), + "Queued Job List not empty"); + + WARN(!list_empty(&ctx->fdp1->hw_job_list), + "HW Job list not empty"); + } +} + +static struct vb2_ops fdp1_qops = { + .queue_setup = fdp1_queue_setup, + .buf_prepare = fdp1_buf_prepare, + .buf_queue = fdp1_buf_queue, + .start_streaming = fdp1_start_streaming, + .stop_streaming = fdp1_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +static int queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct fdp1_ctx *ctx = priv; + int ret; + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->buf_struct_size = sizeof(struct fdp1_buffer); + src_vq->ops = &fdp1_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->fdp1->dev_mutex; + src_vq->dev = ctx->fdp1->dev; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->buf_struct_size = sizeof(struct fdp1_buffer); + dst_vq->ops = &fdp1_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->fdp1->dev_mutex; + dst_vq->dev = ctx->fdp1->dev; + + return vb2_queue_init(dst_vq); +} + +/* + * File operations + */ +static int fdp1_open(struct file *file) +{ + struct fdp1_dev *fdp1 = video_drvdata(file); + struct v4l2_pix_format_mplane format; + struct fdp1_ctx *ctx = NULL; + struct v4l2_ctrl *ctrl; + int ret = 0; + + if (mutex_lock_interruptible(&fdp1->dev_mutex)) + return -ERESTARTSYS; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + ret = -ENOMEM; + goto done; + } + + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; + ctx->fdp1 = fdp1; + + /* Initialise Queues */ + INIT_LIST_HEAD(&ctx->fields_queue); + + ctx->translen = 1; + ctx->sequence = 0; + + /* Initialise controls */ + + v4l2_ctrl_handler_init(&ctx->hdl, 3); + v4l2_ctrl_new_std_menu_items(&ctx->hdl, &fdp1_ctrl_ops, + V4L2_CID_DEINTERLACING_MODE, + FDP1_NEXTFIELD, BIT(0), FDP1_FIXED3D, + fdp1_ctrl_deint_menu); + + ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, + V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1); + if (ctrl) + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + + v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, + V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); + + if (ctx->hdl.error) { + ret = ctx->hdl.error; + v4l2_ctrl_handler_free(&ctx->hdl); + goto done; + } + + ctx->fh.ctrl_handler = &ctx->hdl; + v4l2_ctrl_handler_setup(&ctx->hdl); + + /* Configure default parameters. */ + memset(&format, 0, sizeof(format)); + fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init); + + if (IS_ERR(ctx->fh.m2m_ctx)) { + ret = PTR_ERR(ctx->fh.m2m_ctx); + + v4l2_ctrl_handler_free(&ctx->hdl); + kfree(ctx); + goto done; + } + + /* Perform any power management required */ + pm_runtime_get_sync(fdp1->dev); + + v4l2_fh_add(&ctx->fh); + + dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n", + ctx, ctx->fh.m2m_ctx); + +done: + mutex_unlock(&fdp1->dev_mutex); + return ret; +} + +static int fdp1_release(struct file *file) +{ + struct fdp1_dev *fdp1 = video_drvdata(file); + struct fdp1_ctx *ctx = fh_to_ctx(file->private_data); + + dprintk(fdp1, "Releasing instance %p\n", ctx); + + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->hdl); + mutex_lock(&fdp1->dev_mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&fdp1->dev_mutex); + kfree(ctx); + + pm_runtime_put(fdp1->dev); + + return 0; +} + +static const struct v4l2_file_operations fdp1_fops = { + .owner = THIS_MODULE, + .open = fdp1_open, + .release = fdp1_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static const struct video_device fdp1_videodev = { + .name = DRIVER_NAME, + .vfl_dir = VFL_DIR_M2M, + .fops = &fdp1_fops, + .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, + .ioctl_ops = &fdp1_ioctl_ops, + .minor = -1, + .release = video_device_release_empty, +}; + +static const struct v4l2_m2m_ops m2m_ops = { + .device_run = fdp1_m2m_device_run, + .job_ready = fdp1_m2m_job_ready, + .job_abort = fdp1_m2m_job_abort, +}; + +static irqreturn_t fdp1_irq_handler(int irq, void *dev_id) +{ + struct fdp1_dev *fdp1 = dev_id; + u32 int_status; + u32 ctl_status; + u32 vint_cnt; + u32 cycles; + + int_status = fdp1_read(fdp1, FD1_CTL_IRQSTA); + cycles = fdp1_read(fdp1, FD1_CTL_VCYCLE_STAT); + ctl_status = fdp1_read(fdp1, FD1_CTL_STATUS); + vint_cnt = (ctl_status & FD1_CTL_STATUS_VINT_CNT_MASK) >> + FD1_CTL_STATUS_VINT_CNT_SHIFT; + + /* Clear interrupts */ + fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA); + + if (debug >= 2) { + dprintk(fdp1, "IRQ: 0x%x %s%s%s\n", int_status, + int_status & FD1_CTL_IRQ_VERE ? "[Error]" : "[!E]", + int_status & FD1_CTL_IRQ_VINTE ? "[VSync]" : "[!V]", + int_status & FD1_CTL_IRQ_FREE ? "[FrameEnd]" : "[!F]"); + + dprintk(fdp1, "CycleStatus = %d (%dms)\n", + cycles, cycles/(fdp1->clk_rate/1000)); + + dprintk(fdp1, + "Control Status = 0x%08x : VINT_CNT = %d %s:%s:%s:%s\n", + ctl_status, vint_cnt, + ctl_status & FD1_CTL_STATUS_SGREGSET ? "RegSet" : "", + ctl_status & FD1_CTL_STATUS_SGVERR ? "Vsync Error" : "", + ctl_status & FD1_CTL_STATUS_SGFREND ? "FrameEnd" : "", + ctl_status & FD1_CTL_STATUS_BSY ? "Busy" : ""); + dprintk(fdp1, "***********************************\n"); + } + + /* Spurious interrupt */ + if (!(FD1_CTL_IRQ_MASK & int_status)) + return IRQ_NONE; + + /* Work completed, release the frame */ + if (FD1_CTL_IRQ_VERE & int_status) + device_frame_end(fdp1, VB2_BUF_STATE_ERROR); + else if (FD1_CTL_IRQ_FREE & int_status) + device_frame_end(fdp1, VB2_BUF_STATE_DONE); + + return IRQ_HANDLED; +} + +static int fdp1_probe(struct platform_device *pdev) +{ + struct fdp1_dev *fdp1; + struct video_device *vfd; + struct device_node *fcp_node; + struct resource *res; + struct clk *clk; + unsigned int i; + + int ret; + int hw_version; + + fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL); + if (!fdp1) + return -ENOMEM; + + INIT_LIST_HEAD(&fdp1->free_job_list); + INIT_LIST_HEAD(&fdp1->queued_job_list); + INIT_LIST_HEAD(&fdp1->hw_job_list); + + /* Initialise the jobs on the free list */ + for (i = 0; i < ARRAY_SIZE(fdp1->jobs); i++) + list_add(&fdp1->jobs[i].list, &fdp1->free_job_list); + + mutex_init(&fdp1->dev_mutex); + + spin_lock_init(&fdp1->irqlock); + spin_lock_init(&fdp1->device_process_lock); + fdp1->dev = &pdev->dev; + platform_set_drvdata(pdev, fdp1); + + /* Memory-mapped registers */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + fdp1->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(fdp1->regs)) + return PTR_ERR(fdp1->regs); + + /* Interrupt service routine registration */ + fdp1->irq = ret = platform_get_irq(pdev, 0); + if (ret < 0) { + dev_err(&pdev->dev, "cannot find IRQ\n"); + return ret; + } + + ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0, + dev_name(&pdev->dev), fdp1); + if (ret) { + dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq); + return ret; + } + + /* FCP */ + fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); + if (fcp_node) { + fdp1->fcp = rcar_fcp_get(fcp_node); + of_node_put(fcp_node); + if (IS_ERR(fdp1->fcp)) { + dev_err(&pdev->dev, "FCP not found (%ld)\n", + PTR_ERR(fdp1->fcp)); + return PTR_ERR(fdp1->fcp); + } + } + + /* Determine our clock rate */ + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + fdp1->clk_rate = clk_get_rate(clk); + clk_put(clk); + + /* V4L2 device registration */ + ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev); + if (ret) { + v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); + return ret; + } + + /* M2M registration */ + fdp1->m2m_dev = v4l2_m2m_init(&m2m_ops); + if (IS_ERR(fdp1->m2m_dev)) { + v4l2_err(&fdp1->v4l2_dev, "Failed to init mem2mem device\n"); + ret = PTR_ERR(fdp1->m2m_dev); + goto unreg_dev; + } + + /* Video registration */ + fdp1->vfd = fdp1_videodev; + vfd = &fdp1->vfd; + vfd->lock = &fdp1->dev_mutex; + vfd->v4l2_dev = &fdp1->v4l2_dev; + video_set_drvdata(vfd, fdp1); + strlcpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name)); + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); + goto release_m2m; + } + + v4l2_info(&fdp1->v4l2_dev, + "Device registered as /dev/video%d\n", vfd->num); + + /* Power up the cells to read HW */ + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(fdp1->dev); + + hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); + switch (hw_version) { + case FD1_IP_H3: + dprintk(fdp1, "FDP1 Version R-Car H3\n"); + break; + case FD1_IP_M3W: + dprintk(fdp1, "FDP1 Version R-Car M3-W\n"); + break; + default: + dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n", + hw_version); + } + + /* Allow the hw to sleep until an open call puts it to use */ + pm_runtime_put(fdp1->dev); + + return 0; + +release_m2m: + v4l2_m2m_release(fdp1->m2m_dev); + +unreg_dev: + v4l2_device_unregister(&fdp1->v4l2_dev); + + return ret; +} + +static int fdp1_remove(struct platform_device *pdev) +{ + struct fdp1_dev *fdp1 = platform_get_drvdata(pdev); + + v4l2_m2m_release(fdp1->m2m_dev); + video_unregister_device(&fdp1->vfd); + v4l2_device_unregister(&fdp1->v4l2_dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int fdp1_pm_runtime_suspend(struct device *dev) +{ + struct fdp1_dev *fdp1 = dev_get_drvdata(dev); + + rcar_fcp_disable(fdp1->fcp); + + return 0; +} + +static int fdp1_pm_runtime_resume(struct device *dev) +{ + struct fdp1_dev *fdp1 = dev_get_drvdata(dev); + + /* Program in the static LUTs */ + fdp1_set_lut(fdp1); + + return rcar_fcp_enable(fdp1->fcp); +} + +static const struct dev_pm_ops fdp1_pm_ops = { + SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend, + fdp1_pm_runtime_resume, + NULL) +}; + +static const struct of_device_id fdp1_dt_ids[] = { + { .compatible = "renesas,fdp1" }, + { }, +}; +MODULE_DEVICE_TABLE(of, fdp1_dt_ids); + +static struct platform_driver fdp1_pdrv = { + .probe = fdp1_probe, + .remove = fdp1_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = fdp1_dt_ids, + .pm = &fdp1_pm_ops, + }, +}; + +module_platform_driver(fdp1_pdrv); + +MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver"); +MODULE_AUTHOR("Kieran Bingham "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); -- cgit v1.2.3 From 90b4c9c65ab41d4d20ab5121dd0a536f84565ad5 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 26 Mar 2014 19:48:39 -0300 Subject: [media] exynos4-is: fimc: Roundup imagesize to row size for tiled formats For tiled format, we need to allocated a multiple of the row size. A good example is for 1280x720, wich get adjusted to 1280x736. In tiles, this mean Y plane is 20x23 and UV plane 20x12. Because of the rounding, the previous code would only have enough space to fit half of the last row. [mchehab@s-opensource.com: fix coding style] Signed-off-by: Nicolas Dufresne Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index 8f89ca21b631..099c735a39b7 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -736,6 +736,7 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, for (i = 0; i < pix->num_planes; ++i) { struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i]; u32 bpl = plane_fmt->bytesperline; + u32 sizeimage; if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) bpl = pix->width; /* Planar */ @@ -755,8 +756,17 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, bytesperline /= 2; plane_fmt->bytesperline = bytesperline; - plane_fmt->sizeimage = max((pix->width * pix->height * - fmt->depth[i]) / 8, plane_fmt->sizeimage); + sizeimage = pix->width * pix->height * fmt->depth[i] / 8; + + /* Ensure full last row for tiled formats */ + if (tiled_fmt(fmt)) { + /* 64 * 32 * plane_fmt->bytesperline / 64 */ + u32 row_size = plane_fmt->bytesperline * 32; + + sizeimage = roundup(sizeimage, row_size); + } + + plane_fmt->sizeimage = max(sizeimage, plane_fmt->sizeimage); } } -- cgit v1.2.3 From 0f7a55b4e09fc51413cb9175ee6e701aa6878308 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Tue, 18 Oct 2016 21:28:22 -0200 Subject: [media] s5p-mfc: Collapse two error message into one s5p_mfc_alloc_priv_buf() prints two message to report invalid memory configuration error. Collapse them into a single message. Signed-off-by: Shuah Khan Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c index 1e7250260a9a..f0f5e8ce5416 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c @@ -50,8 +50,7 @@ int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, } if (b->dma < base) { - mfc_err("Invaling memory configuration!\n"); - mfc_err("Allocated buffer (%pad) is lower than memory base address (%pad)\n", + mfc_err("Invalid memory configuration - buffer (%pad) is below base memory address(%pad)\n", &b->dma, &base); dma_free_coherent(dev, b->size, b->virt, b->dma); return -ENOMEM; -- cgit v1.2.3 From def2cc8c4094d89db8289c51decf5a0b00569c16 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 30 Sep 2016 18:16:41 -0300 Subject: [media] exynos-gsc: change spamming try_fmt log message to debug The driver try_fmt handler prints a message each time that the image size has been changed due the maximum and minimum width and height. Since user-space can try different format and sizes, this logs a lot of unnecessary messages. Change the message log level to debug and while being there, also add a new line to the message. Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 787bd16c19e5..fac0c0246ad4 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -441,7 +441,7 @@ int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f) v4l_bound_align_image(&pix_mp->width, min_w, max_w, mod_x, &pix_mp->height, min_h, max_h, mod_y, 0); if (tmp_w != pix_mp->width || tmp_h != pix_mp->height) - pr_info("Image size has been modified from %dx%d to %dx%d", + pr_debug("Image size has been modified from %dx%d to %dx%d\n", tmp_w, tmp_h, pix_mp->width, pix_mp->height); pix_mp->num_planes = fmt->num_planes; -- cgit v1.2.3 From daba4dfbd298ac76e4064a97b88c717cacf43a6f Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 30 Sep 2016 18:16:42 -0300 Subject: [media] exynos-gsc: don't clear format when freeing buffers with REQBUFS(0) User-space applications can use the VIDIOC_REQBUFS ioctl to determine if a memory mapped, user pointer or DMABUF based I/O is supported by a driver. For example, GStreamer attempts to determine the I/O methods supported by the driver by doing many VIDIOC_REQBUFS ioctl calls with different memory types and count 0. And then the real VIDIOC_REQBUFS call with count == n is be made to allocate the buffers. But for count 0, the driver not only frees the buffers but also clears the format set before with VIDIOC_S_FMT. This is a problem since STREAMON fails if a format isn't set but GStreamer first sets a format and then tries to determine the supported I/O methods, so the format will be cleared on REQBUFS(0), before the call to STREAMON. To avoid this issue, only free the buffers on VIDIOC_REQBUFS(0) but don't clear the format. Since is completely valid to set the format and then do different calls to REQBUFS before a call to STREAMON. Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index 9f03b791b711..e2a16b52f87d 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -365,14 +365,8 @@ static int gsc_m2m_reqbufs(struct file *file, void *fh, max_cnt = (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? gsc->variant->in_buf_cnt : gsc->variant->out_buf_cnt; - if (reqbufs->count > max_cnt) { + if (reqbufs->count > max_cnt) return -EINVAL; - } else if (reqbufs->count == 0) { - if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - gsc_ctx_state_lock_clear(GSC_SRC_FMT, ctx); - else - gsc_ctx_state_lock_clear(GSC_DST_FMT, ctx); - } return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); } -- cgit v1.2.3 From 8a661745b7adb0e3680af3840d4e5dac54afa3d8 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 30 Sep 2016 18:16:43 -0300 Subject: [media] exynos-gsc: fix supported RGB pixel format The driver exposes 32-bit A/XRGB 8-8-8-8 as supported format but testing shows that using this format produces frames with wrong colors. The test was done with the following GStreamer pipeline: $ gst-launch-1.0 videotestsrc num-buffers=20 ! video/x-raw,format=UYVY \ ! v4l2video3convert ! video/x-raw,format=xRGB ! videoconvert ! kmssink The manual seems to state that the Pixel Format are in Little Endianness so instead use the 32-bit BGRA/X 8-8-8-8 pixel format. This format works correctly when using the following pipeline: $ gst-launch-1.0 videotestsrc num-buffers=20 ! video/x-raw,format=UYVY \ ! v4l2video3convert ! video/x-raw,format=BGRx ! kmssink This change is similar to commit 7f2816e51ea1 ("[media] s5p-fimc: Changed RGB32 to BGR32") that fixed the same issue on a different Samsung driver. Suggested-by: Nicolas Dufresne Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index fac0c0246ad4..8bb1d2be7234 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -39,8 +39,8 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 1, }, { - .name = "XRGB-8-8-8-8, 32 bpp", - .pixelformat = V4L2_PIX_FMT_RGB32, + .name = "BGRX-8-8-8-8, 32 bpp", + .pixelformat = V4L2_PIX_FMT_BGR32, .depth = { 32 }, .color = GSC_RGB, .num_planes = 1, -- cgit v1.2.3 From 652bb68018a557c795db9a24cf8e84280340b38e Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 30 Sep 2016 18:16:44 -0300 Subject: [media] exynos-gsc: do proper bytesperline and sizeimage calculation The driver don't take into account the differences between packed, semi planar and multi planar formats when calculating the pixel format bytes per lines and image size values. This makes GStreamer to fail when the following formats are used NV12, NV21, NV16, NV61, YV12, I420 and Y42B: "gst_video_frame_map_id: failed to map video frame plane 1" Nicolas suggested to use the logic found in the Exynos FIMC v4l2 driver since does this correctly. So this patch changes the bytes per line and image size calculation according to what's done in this media driver. After this patch most supported formats work correctly. There are still issues with the NV21 and NV61 formats, but that seems to be a separate problem since NV12 and NV16 work and these formats use the same values. So this can be fixed as a follow-up and shouldn't be a blocker for this change that improves the driver's support. Suggested-by: Nicolas Dufresne Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 8bb1d2be7234..a6c47deba3b7 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -451,12 +451,25 @@ int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f) else /* SD */ pix_mp->colorspace = V4L2_COLORSPACE_SMPTE170M; - for (i = 0; i < pix_mp->num_planes; ++i) { - int bpl = (pix_mp->width * fmt->depth[i]) >> 3; - pix_mp->plane_fmt[i].bytesperline = bpl; - pix_mp->plane_fmt[i].sizeimage = bpl * pix_mp->height; + struct v4l2_plane_pix_format *plane_fmt = &pix_mp->plane_fmt[i]; + u32 bpl = plane_fmt->bytesperline; + + if (fmt->num_comp == 1 && /* Packed */ + (bpl == 0 || (bpl * 8 / fmt->depth[i]) < pix_mp->width)) + bpl = pix_mp->width * fmt->depth[i] / 8; + + if (fmt->num_comp > 1 && /* Planar */ + (bpl == 0 || bpl < pix_mp->width)) + bpl = pix_mp->width; + + if (i != 0 && fmt->num_comp == 3) + bpl /= 2; + plane_fmt->bytesperline = bpl; + plane_fmt->sizeimage = max(pix_mp->width * pix_mp->height * + fmt->depth[i] / 8, + plane_fmt->sizeimage); pr_debug("[%d]: bpl: %d, sizeimage: %d", i, bpl, pix_mp->plane_fmt[i].sizeimage); } -- cgit v1.2.3 From f4ca5030b3a34bc7017c195e89181deaa5ee9a42 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 7 Oct 2016 17:39:17 -0300 Subject: [media] exynos-gsc: don't release a non-dynamically allocated video_device The struct v4l2_device instance for the G-Scaler is not dyanmically allocated but a member of the struct gsc_dev. In fact, the assigned .release callback is video_device_release_empty(). But gsc_register_m2m_device() attempts to release the v4l2_device by calling video_device_release() in its error path. This is wrong since the v4l2_device wasn't allocated directly and will be freed once its parent struct gsc_dev is freed. While being there, rename the remaining goto label in the error path to something that better explains the error path cleanup. Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index e2a16b52f87d..a1cac52ea230 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -760,24 +760,21 @@ int gsc_register_m2m_device(struct gsc_dev *gsc) gsc->m2m.m2m_dev = v4l2_m2m_init(&gsc_m2m_ops); if (IS_ERR(gsc->m2m.m2m_dev)) { dev_err(&pdev->dev, "failed to initialize v4l2-m2m device\n"); - ret = PTR_ERR(gsc->m2m.m2m_dev); - goto err_m2m_r1; + return PTR_ERR(gsc->m2m.m2m_dev); } ret = video_register_device(&gsc->vdev, VFL_TYPE_GRABBER, -1); if (ret) { dev_err(&pdev->dev, "%s(): failed to register video device\n", __func__); - goto err_m2m_r2; + goto err_m2m_release; } pr_debug("gsc m2m driver registered as /dev/video%d", gsc->vdev.num); return 0; -err_m2m_r2: +err_m2m_release: v4l2_m2m_release(gsc->m2m.m2m_dev); -err_m2m_r1: - video_device_release(gsc->m2m.vfd); return ret; } -- cgit v1.2.3 From 115a16ba3fa492a13b5530c982fec1ecac5666a1 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 7 Oct 2016 17:39:18 -0300 Subject: [media] exynos-gsc: unregister video device node on driver removal The driver doesn't unregister the video device node when the driver is removed, this keeps video device nodes that makes the machine to crash with a NULL pointer dereference when nodes are attempted to be opened: [ 36.530006] Unable to handle kernel paging request at virtual address bf1f8200 [ 36.535985] pgd = edbbc000 [ 36.538486] [bf1f8200] *pgd=6d99a811, *pte=00000000, *ppte=00000000 [ 36.544727] Internal error: Oops: 7 [#1] PREEMPT SMP ARM [ 36.550016] Modules linked in: s5p_jpeg s5p_mfc v4l2_mem2mem videobuf2_dma_contig [ 36.566303] CPU: 6 PID: 533 Comm: v4l2-ctl Not tainted 4.8.0 [ 36.574466] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 36.580526] task: ee3cc600 task.stack: ed626000 [ 36.585046] PC is at try_module_get+0x1c/0xac [ 36.589364] LR is at try_module_get+0x1c/0xac [ 36.593698] pc : [] lr : [] psr: 80070013 [ 36.593698] sp : ed627de0 ip : a0070013 fp : 00000000 [ 36.605156] r10: 00000002 r9 : ed627ed0 r8 : 00000000 [ 36.610331] r7 : c01e5f14 r6 : ed57be00 r5 : bf1f8200 r4 : bf1f8200 [ 36.616834] r3 : 00000002 r2 : 00000002 r1 : 01930192 r0 : 00000001 .. [ 36.785004] [] (try_module_get) from [] (cdev_get+0x1c/0x4c) [ 36.792362] [] (cdev_get) from [] (chrdev_open+0x2c/0x178) [ 36.799555] [] (chrdev_open) from [] (do_dentry_open+0x1e0/0x300) [ 36.807360] [] (do_dentry_open) from [] (path_openat+0x35c/0xf58) [ 36.815154] [] (path_openat) from [] (do_filp_open+0x5c/0xc0) [ 36.822606] [] (do_filp_open) from [] (do_sys_open+0x10c/0x1bc) [ 36.830235] [] (do_sys_open) from [] (ret_fast_syscall+0x0/0x3c) [ 36.837942] Code: 0a00001c e1a04000 e3a00001 ebfec92d (e5943000) Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index a1cac52ea230..c8c0bcec35ed 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -781,6 +781,8 @@ err_m2m_release: void gsc_unregister_m2m_device(struct gsc_dev *gsc) { - if (gsc) + if (gsc) { v4l2_m2m_release(gsc->m2m.m2m_dev); + video_unregister_device(&gsc->vdev); + } } -- cgit v1.2.3 From 76ca0824afef3d18c555ab01fcdd222075e0b14d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 7 Oct 2016 17:39:19 -0300 Subject: [media] exynos-gsc: cleanup m2m src and dst vb2 queues on STREAMOFF Media drivers that use the videobuf2 framework have to give back to vb2 all the buffers that received from vb2 using its .buf_queue callback. But the exynos-gsc driver isn't doing a proper cleanup so vb2 complains that the number of buffers enqueued and received are not balanced: WARNING: CPU: 2 PID: 660 at drivers/media/v4l2-core/videobuf2-core.c:1654 __vb2_queue_cancel+0xec/0x150 [videobuf2_core] Modules linked in: mwifiex_sdio mwifiex uvcvideo exynos_gsc videobuf2_vmalloc s5p_mfc s5p_jpeg CPU: 2 PID: 660 Comm: lt-gst-validate Not tainted 4.8.0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x88/0x9c) [] (dump_stack) from [] (__warn+0xe8/0x100) [] (__warn) from [] (warn_slowpath_null+0x20/0x28) [] (warn_slowpath_null) from [] (__vb2_queue_cancel+0xec/0x150 [videobuf2_core]) [] (__vb2_queue_cancel [videobuf2_core]) from [] (vb2_core_streamoff+0x34/0x9c [videobuf2_core]) [] (vb2_core_streamoff [videobuf2_core]) from [] (v4l2_m2m_streamoff+0x2c/0xe4 [v4l2_mem2mem]) [] (v4l2_m2m_streamoff [v4l2_mem2mem]) from [] (__video_do_ioctl+0x298/0x30c [videodev]) [] (__video_do_ioctl [videodev]) from [] (video_usercopy+0x174/0x4e8 [videodev]) [] (video_usercopy [videodev]) from [] (v4l2_ioctl+0xc4/0xd8 [videodev]) [] (v4l2_ioctl [videodev]) from [] (do_vfs_ioctl+0x9c/0x8f4) [] (do_vfs_ioctl) from [] (SyS_ioctl+0x34/0x5c) [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) Fix this by passing back to vb2 all the received buffers that were not processed. Signed-off-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index c8c0bcec35ed..f49f24b4462a 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -66,12 +66,29 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) return ret > 0 ? 0 : ret; } +static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx) +{ + struct vb2_v4l2_buffer *src_vb, *dst_vb; + + while (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0) { + src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR); + } + + while (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0) { + dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR); + } +} + static void gsc_m2m_stop_streaming(struct vb2_queue *q) { struct gsc_ctx *ctx = q->drv_priv; __gsc_m2m_job_abort(ctx); + __gsc_m2m_cleanup_queue(ctx); + pm_runtime_put(&ctx->gsc_dev->pdev->dev); } -- cgit v1.2.3 From 43e6347f400d8bf8beff56a164c6a7e8c3d0ba5f Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Mon, 7 Nov 2016 21:39:25 -0200 Subject: [media] s5p-mfc: include buffer size in error message Include buffer size in s5p_mfc_alloc_priv_buf() the error message when it fails to allocate the buffer. Signed-off-by: Shuah Khan Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c index f0f5e8ce5416..99f65a92a6be 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c @@ -45,7 +45,8 @@ int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, b->virt = dma_alloc_coherent(dev, b->size, &b->dma, GFP_KERNEL); if (!b->virt) { - mfc_err("Allocating private buffer failed\n"); + mfc_err("Allocating private buffer of size %zu failed\n", + b->size); return -ENOMEM; } -- cgit v1.2.3 From d83db90456d5d1bbf6a73e9cf7848afcdfff205c Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:50 -0200 Subject: [media] exynos-gsc: Simplify clock management Instead of having separate functions that fetches, prepares and unprepares the clock, let's encapsulate this code into ->probe(). This makes error handling easier and decreases the lines of code. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 49 ++++++++-------------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index a6c47deba3b7..183c6e4e915f 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1001,36 +1001,6 @@ static void *gsc_get_drv_data(struct platform_device *pdev) return driver_data; } -static void gsc_clk_put(struct gsc_dev *gsc) -{ - if (!IS_ERR(gsc->clock)) - clk_unprepare(gsc->clock); -} - -static int gsc_clk_get(struct gsc_dev *gsc) -{ - int ret; - - dev_dbg(&gsc->pdev->dev, "gsc_clk_get Called\n"); - - gsc->clock = devm_clk_get(&gsc->pdev->dev, GSC_CLOCK_GATE_NAME); - if (IS_ERR(gsc->clock)) { - dev_err(&gsc->pdev->dev, "failed to get clock~~~: %s\n", - GSC_CLOCK_GATE_NAME); - return PTR_ERR(gsc->clock); - } - - ret = clk_prepare(gsc->clock); - if (ret < 0) { - dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n", - GSC_CLOCK_GATE_NAME); - gsc->clock = ERR_PTR(-EINVAL); - return ret; - } - - return 0; -} - static int gsc_m2m_suspend(struct gsc_dev *gsc) { unsigned long flags; @@ -1098,7 +1068,6 @@ static int gsc_probe(struct platform_device *pdev) init_waitqueue_head(&gsc->irq_queue); spin_lock_init(&gsc->slock); mutex_init(&gsc->lock); - gsc->clock = ERR_PTR(-EINVAL); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); gsc->regs = devm_ioremap_resource(dev, res); @@ -1111,9 +1080,19 @@ static int gsc_probe(struct platform_device *pdev) return -ENXIO; } - ret = gsc_clk_get(gsc); - if (ret) + gsc->clock = devm_clk_get(dev, GSC_CLOCK_GATE_NAME); + if (IS_ERR(gsc->clock)) { + dev_err(dev, "failed to get clock~~~: %s\n", + GSC_CLOCK_GATE_NAME); + return PTR_ERR(gsc->clock); + } + + ret = clk_prepare(gsc->clock); + if (ret) { + dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n", + GSC_CLOCK_GATE_NAME); return ret; + } ret = devm_request_irq(dev, res->start, gsc_irq_handler, 0, pdev->name, gsc); @@ -1148,7 +1127,7 @@ err_m2m: err_v4l2: v4l2_device_unregister(&gsc->v4l2_dev); err_clk: - gsc_clk_put(gsc); + clk_unprepare(gsc->clock); return ret; } @@ -1161,7 +1140,7 @@ static int gsc_remove(struct platform_device *pdev) vb2_dma_contig_clear_max_seg_size(&pdev->dev); pm_runtime_disable(&pdev->dev); - gsc_clk_put(gsc); + clk_unprepare(gsc->clock); dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); return 0; -- cgit v1.2.3 From f9fd6ee6fb504b99c63831ae1f166f6bdda47d0b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:51 -0200 Subject: [media] exynos-gsc: Convert gsc_m2m_resume() from int to void Since gsc_m2m_resume() always returns 0, convert it to a void instead. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 183c6e4e915f..945042c346e7 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1023,7 +1023,7 @@ static int gsc_m2m_suspend(struct gsc_dev *gsc) return timeout == 0 ? -EAGAIN : 0; } -static int gsc_m2m_resume(struct gsc_dev *gsc) +static void gsc_m2m_resume(struct gsc_dev *gsc) { struct gsc_ctx *ctx; unsigned long flags; @@ -1036,8 +1036,6 @@ static int gsc_m2m_resume(struct gsc_dev *gsc) if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state)) gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); - - return 0; } static int gsc_probe(struct platform_device *pdev) @@ -1159,8 +1157,9 @@ static int gsc_runtime_resume(struct device *dev) gsc_hw_set_sw_reset(gsc); gsc_wait_reset(gsc); + gsc_m2m_resume(gsc); - return gsc_m2m_resume(gsc); + return 0; } static int gsc_runtime_suspend(struct device *dev) -- cgit v1.2.3 From 15f90ab57acc318a90578a2e05b7b450e0e3cfe0 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:52 -0200 Subject: [media] exynos-gsc: Make driver functional when CONFIG_PM is unset The driver depended on CONFIG_PM to be functional. Let's remove that dependency, by enable the runtime PM resourses during ->probe() and update the device's runtime PM status to reflect this. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 945042c346e7..7539bb3e318f 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1085,7 +1085,7 @@ static int gsc_probe(struct platform_device *pdev) return PTR_ERR(gsc->clock); } - ret = clk_prepare(gsc->clock); + ret = clk_prepare_enable(gsc->clock); if (ret) { dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n", GSC_CLOCK_GATE_NAME); @@ -1108,24 +1108,23 @@ static int gsc_probe(struct platform_device *pdev) goto err_v4l2; platform_set_drvdata(pdev, gsc); - pm_runtime_enable(dev); - ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) - goto err_m2m; + + gsc_hw_set_sw_reset(gsc); + gsc_wait_reset(gsc); vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); dev_dbg(dev, "gsc-%d registered successfully\n", gsc->id); - pm_runtime_put(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + return 0; -err_m2m: - gsc_unregister_m2m_device(gsc); err_v4l2: v4l2_device_unregister(&gsc->v4l2_dev); err_clk: - clk_unprepare(gsc->clock); + clk_disable_unprepare(gsc->clock); return ret; } -- cgit v1.2.3 From 81aa8d141f84868f3523eeab6ced4991819e7f18 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 14 Nov 2016 08:27:32 -0200 Subject: [media] exynos-gsc: Make PM callbacks available conditionally There are no need to set up the PM callbacks (runtime and system) unless they are being used. It also causes compiler warnings about unused functions. Silence the warnings by making them available for CONFIG_PM (runtime callbacks) and CONFIG_PM_SLEEP (system sleep callbacks). [mszyprow: squashed two patches into one to avoid potential build break, changed patch subject and updated commit message] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 84 ++++++++++++++-------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 7539bb3e318f..19fcbc7424fc 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1001,43 +1001,6 @@ static void *gsc_get_drv_data(struct platform_device *pdev) return driver_data; } -static int gsc_m2m_suspend(struct gsc_dev *gsc) -{ - unsigned long flags; - int timeout; - - spin_lock_irqsave(&gsc->slock, flags); - if (!gsc_m2m_pending(gsc)) { - spin_unlock_irqrestore(&gsc->slock, flags); - return 0; - } - clear_bit(ST_M2M_SUSPENDED, &gsc->state); - set_bit(ST_M2M_SUSPENDING, &gsc->state); - spin_unlock_irqrestore(&gsc->slock, flags); - - timeout = wait_event_timeout(gsc->irq_queue, - test_bit(ST_M2M_SUSPENDED, &gsc->state), - GSC_SHUTDOWN_TIMEOUT); - - clear_bit(ST_M2M_SUSPENDING, &gsc->state); - return timeout == 0 ? -EAGAIN : 0; -} - -static void gsc_m2m_resume(struct gsc_dev *gsc) -{ - struct gsc_ctx *ctx; - unsigned long flags; - - spin_lock_irqsave(&gsc->slock, flags); - /* Clear for full H/W setup in first run after resume */ - ctx = gsc->m2m.ctx; - gsc->m2m.ctx = NULL; - spin_unlock_irqrestore(&gsc->slock, flags); - - if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state)) - gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); -} - static int gsc_probe(struct platform_device *pdev) { struct gsc_dev *gsc; @@ -1143,6 +1106,44 @@ static int gsc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int gsc_m2m_suspend(struct gsc_dev *gsc) +{ + unsigned long flags; + int timeout; + + spin_lock_irqsave(&gsc->slock, flags); + if (!gsc_m2m_pending(gsc)) { + spin_unlock_irqrestore(&gsc->slock, flags); + return 0; + } + clear_bit(ST_M2M_SUSPENDED, &gsc->state); + set_bit(ST_M2M_SUSPENDING, &gsc->state); + spin_unlock_irqrestore(&gsc->slock, flags); + + timeout = wait_event_timeout(gsc->irq_queue, + test_bit(ST_M2M_SUSPENDED, &gsc->state), + GSC_SHUTDOWN_TIMEOUT); + + clear_bit(ST_M2M_SUSPENDING, &gsc->state); + return timeout == 0 ? -EAGAIN : 0; +} + +static void gsc_m2m_resume(struct gsc_dev *gsc) +{ + struct gsc_ctx *ctx; + unsigned long flags; + + spin_lock_irqsave(&gsc->slock, flags); + /* Clear for full H/W setup in first run after resume */ + ctx = gsc->m2m.ctx; + gsc->m2m.ctx = NULL; + spin_unlock_irqrestore(&gsc->slock, flags); + + if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state)) + gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); +} + static int gsc_runtime_resume(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); @@ -1173,7 +1174,9 @@ static int gsc_runtime_suspend(struct device *dev) pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); return ret; } +#endif +#ifdef CONFIG_PM_SLEEP static int gsc_resume(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); @@ -1210,12 +1213,11 @@ static int gsc_suspend(struct device *dev) return 0; } +#endif static const struct dev_pm_ops gsc_pm_ops = { - .suspend = gsc_suspend, - .resume = gsc_resume, - .runtime_suspend = gsc_runtime_suspend, - .runtime_resume = gsc_runtime_resume, + SET_SYSTEM_SLEEP_PM_OPS(gsc_suspend, gsc_resume) + SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) }; static struct platform_driver gsc_driver = { -- cgit v1.2.3 From a006c04e6218bb82c11888d9b99ef642bd64cf93 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:54 -0200 Subject: [media] exynos-gsc: Fixup clock management at ->remove() To make sure the clock is fully gated in ->remove(), we first need to to bring the device into full power by invoking pm_runtime_get_sync(). Then, let's both unprepare and disable the clock. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 19fcbc7424fc..e62765328848 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1095,12 +1095,15 @@ static int gsc_remove(struct platform_device *pdev) { struct gsc_dev *gsc = platform_get_drvdata(pdev); + pm_runtime_get_sync(&pdev->dev); + gsc_unregister_m2m_device(gsc); v4l2_device_unregister(&gsc->v4l2_dev); vb2_dma_contig_clear_max_seg_size(&pdev->dev); - pm_runtime_disable(&pdev->dev); - clk_unprepare(gsc->clock); + clk_disable_unprepare(gsc->clock); + + pm_runtime_put_noidle(&pdev->dev); dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); return 0; -- cgit v1.2.3 From 7ebcb3e842bd933fa6792414a3b369a661d99665 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:55 -0200 Subject: [media] exynos-gsc: Do full clock gating at runtime PM suspend To potentially save more power in runtime PM suspend state, let's also prepare/unprepare the clock from the runtime PM callbacks. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index e62765328848..3ac588f5c558 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1154,7 +1154,7 @@ static int gsc_runtime_resume(struct device *dev) pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); - ret = clk_enable(gsc->clock); + ret = clk_prepare_enable(gsc->clock); if (ret) return ret; @@ -1172,7 +1172,7 @@ static int gsc_runtime_suspend(struct device *dev) ret = gsc_m2m_suspend(gsc); if (!ret) - clk_disable(gsc->clock); + clk_disable_unprepare(gsc->clock); pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); return ret; -- cgit v1.2.3 From 701a8de6ef4ee1a5000144cc7d66ecc343598e14 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 9 Nov 2016 12:23:57 -0200 Subject: [media] exynos-gsc: Simplify system PM It's not needed to keep a local flag about the current system PM state. Let's just remove that code and the corresponding debug print. [mszyprow: rebased onto v4.9-rc4] Signed-off-by: Ulf Hansson Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 21 --------------------- drivers/media/platform/exynos-gsc/gsc-core.h | 3 --- 2 files changed, 24 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 3ac588f5c558..5aeb8b44eacd 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1182,20 +1182,6 @@ static int gsc_runtime_suspend(struct device *dev) #ifdef CONFIG_PM_SLEEP static int gsc_resume(struct device *dev) { - struct gsc_dev *gsc = dev_get_drvdata(dev); - unsigned long flags; - - pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); - - /* Do not resume if the device was idle before system suspend */ - spin_lock_irqsave(&gsc->slock, flags); - if (!test_and_clear_bit(ST_SUSPEND, &gsc->state) || - !gsc_m2m_opened(gsc)) { - spin_unlock_irqrestore(&gsc->slock, flags); - return 0; - } - spin_unlock_irqrestore(&gsc->slock, flags); - if (!pm_runtime_suspended(dev)) return gsc_runtime_resume(dev); @@ -1204,13 +1190,6 @@ static int gsc_resume(struct device *dev) static int gsc_suspend(struct device *dev) { - struct gsc_dev *gsc = dev_get_drvdata(dev); - - pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); - - if (test_and_set_bit(ST_SUSPEND, &gsc->state)) - return 0; - if (!pm_runtime_suspended(dev)) return gsc_runtime_suspend(dev); diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 7ad7b9dc2243..8480aec05441 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h @@ -48,9 +48,6 @@ #define GSC_CTX_ABORT (1 << 7) enum gsc_dev_flags { - /* for global */ - ST_SUSPEND, - /* for m2m node */ ST_M2M_OPEN, ST_M2M_RUN, -- cgit v1.2.3 From 8098f9ca949006578d8127cbaa46a84699066959 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:23:58 -0200 Subject: [media] exynos-gsc: Simplify system PM even more System PM callbacks only ensure that device is runtime suspended/resumed, so remove them and use generic pm_runtime_force_suspend/resume helper. Signed-off-by: Marek Szyprowski Reviewed-by: Ulf Hansson Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 5aeb8b44eacd..45a62216385a 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1179,26 +1179,9 @@ static int gsc_runtime_suspend(struct device *dev) } #endif -#ifdef CONFIG_PM_SLEEP -static int gsc_resume(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - return gsc_runtime_resume(dev); - - return 0; -} - -static int gsc_suspend(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - return gsc_runtime_suspend(dev); - - return 0; -} -#endif - static const struct dev_pm_ops gsc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(gsc_suspend, gsc_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) }; -- cgit v1.2.3 From d641cf26941ecfe75b99472738447b692775944a Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:23:59 -0200 Subject: [media] exynos-gsc: Remove unused lclk_freqency entry Remove dead, unused code. Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 1 - drivers/media/platform/exynos-gsc/gsc-core.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 45a62216385a..aa4db1dfc438 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -977,7 +977,6 @@ static struct gsc_driverdata gsc_v_100_drvdata = { [3] = &gsc_v_100_variant, }, .num_entities = 4, - .lclk_frequency = 266000000UL, }; static const struct of_device_id exynos_gsc_match[] = { diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 8480aec05441..e5aa8f42f11e 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h @@ -303,12 +303,10 @@ struct gsc_variant { * struct gsc_driverdata - per device type driver data for init time. * * @variant: the variant information for this driver. - * @lclk_frequency: G-Scaler clock frequency * @num_entities: the number of g-scalers */ struct gsc_driverdata { struct gsc_variant *variant[GSC_MAX_DEVS]; - unsigned long lclk_frequency; int num_entities; }; -- cgit v1.2.3 From e0f013990e5bb68aec8d70dd5b35a6b81da836f7 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:24:00 -0200 Subject: [media] exynos-gsc: Add missing newline char in debug messages Fix missing newline char in debug messages. Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index aa4db1dfc438..c7693c6296bf 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1151,7 +1151,7 @@ static int gsc_runtime_resume(struct device *dev) struct gsc_dev *gsc = dev_get_drvdata(dev); int ret = 0; - pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); + pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); ret = clk_prepare_enable(gsc->clock); if (ret) @@ -1173,7 +1173,7 @@ static int gsc_runtime_suspend(struct device *dev) if (!ret) clk_disable_unprepare(gsc->clock); - pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state); + pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); return ret; } #endif -- cgit v1.2.3 From aa7929f5954ce7232bdd9a5fe01d7458f95d104b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:24:01 -0200 Subject: [media] exynos-gsc: Use of_device_get_match_data() helper Replace open-coded driver data extraction code with generic helper. Signed-off-by: Marek Szyprowski Tested-by: Javier Martinez Canillas Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index c7693c6296bf..f0d8e2433299 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "gsc-core.h" @@ -988,24 +989,12 @@ static const struct of_device_id exynos_gsc_match[] = { }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); -static void *gsc_get_drv_data(struct platform_device *pdev) -{ - struct gsc_driverdata *driver_data = NULL; - const struct of_device_id *match; - - match = of_match_node(exynos_gsc_match, pdev->dev.of_node); - if (match) - driver_data = (struct gsc_driverdata *)match->data; - - return driver_data; -} - static int gsc_probe(struct platform_device *pdev) { struct gsc_dev *gsc; struct resource *res; - struct gsc_driverdata *drv_data = gsc_get_drv_data(pdev); struct device *dev = &pdev->dev; + const struct gsc_driverdata *drv_data = of_device_get_match_data(dev); int ret; gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL); -- cgit v1.2.3 From 6f99e1b85af48275f9d4cbcfd86275220c055ac9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:29:37 -0200 Subject: [media] exynos-gsc: Enable driver on ARCH_EXYNOS This driver can be also used on Exynos5433, which is ARM64-based platform, which selects only ARCH_EXYNOS symbol. Signed-off-by: Marek Szyprowski Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Acked-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 84f44098dc99..3c5a0b6b23a9 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -266,7 +266,7 @@ config VIDEO_MX2_EMMAPRP config VIDEO_SAMSUNG_EXYNOS_GSC tristate "Samsung Exynos G-Scaler driver" depends on VIDEO_DEV && VIDEO_V4L2 - depends on ARCH_EXYNOS5 || COMPILE_TEST + depends on ARCH_EXYNOS || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV -- cgit v1.2.3 From 92955ea0baf4315342d66eaf824deffed431c3be Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Nov 2016 12:29:38 -0200 Subject: [media] exynos-gsc: Add support for Exynos5433 specific version This patch adds support for Exynos5433 specific version of the GScaler module. The main difference between Exynos 5433 and earlier is addition of new clocks that have to be controlled. Signed-off-by: Marek Szyprowski Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Acked-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/exynos5-gsc.txt | 3 +- drivers/media/platform/exynos-gsc/gsc-core.c | 74 ++++++++++++++++------ drivers/media/platform/exynos-gsc/gsc-core.h | 6 +- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/media/exynos5-gsc.txt b/Documentation/devicetree/bindings/media/exynos5-gsc.txt index 5fe9372abb37..26ca25b6d264 100644 --- a/Documentation/devicetree/bindings/media/exynos5-gsc.txt +++ b/Documentation/devicetree/bindings/media/exynos5-gsc.txt @@ -3,7 +3,8 @@ G-Scaler is used for scaling and color space conversion on EXYNOS5 SoCs. Required properties: -- compatible: should be "samsung,exynos5-gsc" +- compatible: should be "samsung,exynos5-gsc" (for Exynos 5250, 5420 and + 5422 SoCs) or "samsung,exynos5433-gsc" (Exynos 5433) - reg: should contain G-Scaler physical address location and length. - interrupts: should contain G-Scaler interrupt number diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index f0d8e2433299..cbf75b6194b4 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -29,8 +29,6 @@ #include "gsc-core.h" -#define GSC_CLOCK_GATE_NAME "gscl" - static const struct gsc_fmt gsc_formats[] = { { .name = "RGB565", @@ -978,6 +976,19 @@ static struct gsc_driverdata gsc_v_100_drvdata = { [3] = &gsc_v_100_variant, }, .num_entities = 4, + .clk_names = { "gscl" }, + .num_clocks = 1, +}; + +static struct gsc_driverdata gsc_5433_drvdata = { + .variant = { + [0] = &gsc_v_100_variant, + [1] = &gsc_v_100_variant, + [2] = &gsc_v_100_variant, + }, + .num_entities = 3, + .clk_names = { "pclk", "aclk", "aclk_xiu", "aclk_gsclbend" }, + .num_clocks = 4, }; static const struct of_device_id exynos_gsc_match[] = { @@ -985,6 +996,10 @@ static const struct of_device_id exynos_gsc_match[] = { .compatible = "samsung,exynos5-gsc", .data = &gsc_v_100_drvdata, }, + { + .compatible = "samsung,exynos5433-gsc", + .data = &gsc_5433_drvdata, + }, {}, }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); @@ -996,6 +1011,7 @@ static int gsc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct gsc_driverdata *drv_data = of_device_get_match_data(dev); int ret; + int i; gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL); if (!gsc) @@ -1011,6 +1027,7 @@ static int gsc_probe(struct platform_device *pdev) return -EINVAL; } + gsc->num_clocks = drv_data->num_clocks; gsc->variant = drv_data->variant[gsc->id]; gsc->pdev = pdev; @@ -1029,18 +1046,24 @@ static int gsc_probe(struct platform_device *pdev) return -ENXIO; } - gsc->clock = devm_clk_get(dev, GSC_CLOCK_GATE_NAME); - if (IS_ERR(gsc->clock)) { - dev_err(dev, "failed to get clock~~~: %s\n", - GSC_CLOCK_GATE_NAME); - return PTR_ERR(gsc->clock); + for (i = 0; i < gsc->num_clocks; i++) { + gsc->clock[i] = devm_clk_get(dev, drv_data->clk_names[i]); + if (IS_ERR(gsc->clock[i])) { + dev_err(dev, "failed to get clock: %s\n", + drv_data->clk_names[i]); + return PTR_ERR(gsc->clock[i]); + } } - ret = clk_prepare_enable(gsc->clock); - if (ret) { - dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n", - GSC_CLOCK_GATE_NAME); - return ret; + for (i = 0; i < gsc->num_clocks; i++) { + ret = clk_prepare_enable(gsc->clock[i]); + if (ret) { + dev_err(dev, "clock prepare failed for clock: %s\n", + drv_data->clk_names[i]); + while (--i >= 0) + clk_disable_unprepare(gsc->clock[i]); + return ret; + } } ret = devm_request_irq(dev, res->start, gsc_irq_handler, @@ -1075,13 +1098,15 @@ static int gsc_probe(struct platform_device *pdev) err_v4l2: v4l2_device_unregister(&gsc->v4l2_dev); err_clk: - clk_disable_unprepare(gsc->clock); + for (i = gsc->num_clocks - 1; i >= 0; i--) + clk_disable_unprepare(gsc->clock[i]); return ret; } static int gsc_remove(struct platform_device *pdev) { struct gsc_dev *gsc = platform_get_drvdata(pdev); + int i; pm_runtime_get_sync(&pdev->dev); @@ -1089,7 +1114,8 @@ static int gsc_remove(struct platform_device *pdev) v4l2_device_unregister(&gsc->v4l2_dev); vb2_dma_contig_clear_max_seg_size(&pdev->dev); - clk_disable_unprepare(gsc->clock); + for (i = 0; i < gsc->num_clocks; i++) + clk_disable_unprepare(gsc->clock[i]); pm_runtime_put_noidle(&pdev->dev); @@ -1139,12 +1165,18 @@ static int gsc_runtime_resume(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); int ret = 0; + int i; pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); - ret = clk_prepare_enable(gsc->clock); - if (ret) - return ret; + for (i = 0; i < gsc->num_clocks; i++) { + ret = clk_prepare_enable(gsc->clock[i]); + if (ret) { + while (--i >= 0) + clk_disable_unprepare(gsc->clock[i]); + return ret; + } + } gsc_hw_set_sw_reset(gsc); gsc_wait_reset(gsc); @@ -1157,10 +1189,14 @@ static int gsc_runtime_suspend(struct device *dev) { struct gsc_dev *gsc = dev_get_drvdata(dev); int ret = 0; + int i; ret = gsc_m2m_suspend(gsc); - if (!ret) - clk_disable_unprepare(gsc->clock); + if (ret) + return ret; + + for (i = gsc->num_clocks - 1; i >= 0; i--) + clk_disable_unprepare(gsc->clock[i]); pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state); return ret; diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index e5aa8f42f11e..696217e9af66 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h @@ -33,6 +33,7 @@ #define GSC_SHUTDOWN_TIMEOUT ((100*HZ)/1000) #define GSC_MAX_DEVS 4 +#define GSC_MAX_CLOCKS 4 #define GSC_M2M_BUF_NUM 0 #define GSC_MAX_CTRL_NUM 10 #define GSC_SC_ALIGN_4 4 @@ -307,6 +308,8 @@ struct gsc_variant { */ struct gsc_driverdata { struct gsc_variant *variant[GSC_MAX_DEVS]; + const char *clk_names[GSC_MAX_CLOCKS]; + int num_clocks; int num_entities; }; @@ -330,7 +333,8 @@ struct gsc_dev { struct platform_device *pdev; struct gsc_variant *variant; u16 id; - struct clk *clock; + int num_clocks; + struct clk *clock[GSC_MAX_CLOCKS]; void __iomem *regs; wait_queue_head_t irq_queue; struct gsc_m2m_device m2m; -- cgit v1.2.3 From f662f1b7e5b630c6c95e59c4fe3ff70489c5f8ee Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 10 Nov 2016 08:31:20 -0200 Subject: [media] s5p-mfc: Correct scratch buffer size of H.263 decoder Driver complains about too small scratch buffer size. After adjusting it according to vendor code, decoding works. [mszyprow: moved the change to the header file] Signed-off-by: Andrzej Hajda Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/regs-mfc-v6.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h index 83e01f3466e9..d2cd35916dc5 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h @@ -386,7 +386,8 @@ ((w) * 144 + 8192 * (h) + 49216 + 1048576) #define S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(w, h) \ (2096 * ((w) + (h) + 1)) -#define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) ((w) * 400) +#define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) \ + S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(w, h) #define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6(w, h) \ ((w) * 32 + (h) * 128 + (((w) + 1) / 2) * 64 + 2112) #define S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6(w, h) \ -- cgit v1.2.3 From dd62b8f1a39334c6efbcf06c071def9760700d96 Mon Sep 17 00:00:00 2001 From: Ingi Kim Date: Thu, 10 Nov 2016 08:31:21 -0200 Subject: [media] s5p-mfc: Fix MFC context buffer size When video file was decoded by H/W MFCv8. It occurred IOMMU page fault because of accessing abnormal memory of mfc ctx buf. So this patch supports buffer size of mfc context more. Relevant page fault error is below. [ 3524.617147] PAGE FAULT occurred at 0x10108000 by 11200000.sysmmu(Page table base: 0x6d86c000) [ 3524.624192] Lv1 entry: 0x6c27d001 [ 3524.627567] Lv2 entry: 0x0 [ 3524.630482] ------------[ cut here ]------------ [ 3524.635020] kernel BUG at drivers/iommu/exynos-iommu.c:358! [ 3524.640567] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM [ 3524.646373] Modules linked in: [ 3524.649410] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.0.0-00001-g0ff9b87-dirty #18 [ 3524.657117] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 3524.663184] task: c0e4aff0 ti: c0e3c000 task.ti: c0e3c000 [ 3524.668566] PC is at exynos_sysmmu_irq+0x1b8/0x2c4 [ 3524.673330] LR is at vprintk_emit+0x2b8/0x58c [ 3524.677657] pc : [] lr : [] psr: 600d0193 [ 3524.677657] sp : c0e3dd90 ip : 00000000 fp : c0e3ddcc [ 3524.689092] r10: ee29a110 r9 : 00000000 r8 : ee29a128 [ 3524.694292] r7 : ed812810 r6 : 10108000 r5 : ed86c000 r4 : 00000000 [ 3524.700791] r3 : c0ec9bd8 r2 : 00000000 r1 : 00000000 r0 : ed82ff00 [ 3524.707292] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel [ 3524.714656] Control: 10c5387d Table: 6b08c06a DAC: 00000015 [ 3524.720375] Process swapper/0 (pid: 0, stack limit = 0xc0e3c210) [ 3524.726354] Stack: (0xc0e3dd90 to 0xc0e3e000) [ 3524.730689] dd80: c0e3dd9c c0069d68 ee58c338 6d86c000 [ 3524.738836] dda0: ee58c338 ee298c40 ee2915a0 0000003b c0e64ef4 c0e3c000 00000000 00000000 [ 3524.746981] ddc0: c0e3de14 c0e3ddd0 c0071ef4 c037cacc ffffffff a00d0193 c0e3ddf4 ee291540 [ 3524.755126] dde0: c0ec793c c0ec7928 7fffffff ee291540 ee2915a0 ee298c40 c0e64ef4 ee004660 [ 3524.763272] de00: ee010800 c0e3df00 c0e3de34 c0e3de18 c0072138 c0071e9c 00020000 ee291540 [ 3524.771418] de20: ee2915a0 00000016 c0e3de4c c0e3de38 c0075130 c00720f8 0000003b ee028300 [ 3524.779563] de40: c0e3de64 c0e3de50 c0071450 c0075068 00000100 00000012 c0e3de8c c0e3de68 [ 3524.787708] de60: c030d240 c0071420 c030d19c 00000016 00000000 00000016 00000000 00000001 [ 3524.795854] de80: c0e3dea4 c0e3de90 c0071450 c030d1a8 00000092 c0e37a1c c0e3ded4 c0e3dea8 [ 3524.804000] dea0: c0071790 c0071420 c0e3df00 f000200c 00000016 c0e440a8 c0e3df00 f0002000 [ 3524.812145] dec0: c095bc8c 00000001 c0e3defc c0e3ded8 c0008730 c0071710 c0010d88 c0010d8c [ 3524.820290] dee0: 600d0013 ffffffff c0e3df34 c0ec7eb4 c0e3df54 c0e3df00 c0014780 c00086fc [ 3524.828436] df00: 00000001 00000000 00000000 c0020780 c0e3c000 c0e43530 00000000 00000000 [ 3524.836581] df20: c0ec7eb4 c095bc8c 00000001 c0e3df54 c0e3df58 c0e3df48 c0010d88 c0010d8c [ 3524.844727] df40: 600d0013 ffffffff c0e3df94 c0e3df58 c0062690 c0010d50 c0ec75f0 00000001 [ 3524.852872] df60: c0e3df84 c0e4353c c0e39580 c0e43e84 c0e3c000 00000002 c0e3df58 c0e38b88 [ 3524.861018] df80: c0952b9c ffffffff c0e3dfac c0e3df98 c094d1b8 c00622d4 c0e3c000 c0e43e10 [ 3524.869163] dfa0: c0e3dff4 c0e3dfb0 c0d86d30 c094d130 ffffffff ffffffff c0d866f0 00000000 [ 3524.877309] dfc0: 00000000 c0df06d8 00000000 c0ee3f14 c0e434c0 c0df06d4 c0e4c20c 4000406a [ 3524.885454] dfe0: 410fc073 00000000 00000000 c0e3dff8 40008074 c0d86970 00000000 00000000 [ 3524.893610] [] (exynos_sysmmu_irq) from [] (handle_irq_event_percpu+0x64/0x25c) [ 3524.902615] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x4c/0x6c) [ 3524.911454] [] (handle_irq_event) from [] (handle_level_irq+0xd4/0x14c) [ 3524.919773] [] (handle_level_irq) from [] (generic_handle_irq+0x3c/0x4c) [ 3524.928180] [] (generic_handle_irq) from [] (combiner_handle_cascade_irq+0xa4/0x110) [ 3524.937624] [] (combiner_handle_cascade_irq) from [] (generic_handle_irq+0x3c/0x4c) [ 3524.946981] [] (generic_handle_irq) from [] (__handle_domain_irq+0x8c/0xfc) [ 3524.955646] [] (__handle_domain_irq) from [] (gic_handle_irq+0x40/0x78) [ 3524.963966] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x74) [ 3524.971412] Exception stack(0xc0e3df00 to 0xc0e3df48) [ 3524.976441] df00: 00000001 00000000 00000000 c0020780 c0e3c000 c0e43530 00000000 00000000 [ 3524.984586] df20: c0ec7eb4 c095bc8c 00000001 c0e3df54 c0e3df58 c0e3df48 c0010d88 c0010d8c [ 3524.992729] df40: 600d0013 ffffffff [ 3524.996205] [] (__irq_svc) from [] (arch_cpu_idle+0x48/0x4c) [ 3525.003567] [] (arch_cpu_idle) from [] (cpu_startup_entry+0x3c8/0x4a4) [ 3525.011805] [] (cpu_startup_entry) from [] (rest_init+0x94/0x98) [ 3525.019516] [] (rest_init) from [] (start_kernel+0x3cc/0x3d8) [ 3525.026963] Code: e34c30ec e5932004 e3520000 ca000018 (e7f001f2) [ 3525.033028] ---[ end trace 71ed544f653b4d46 ]--- Signed-off-by: Ingi Kim Signed-off-by: Seung-Woo Kim Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/regs-mfc-v8.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h index cc7cbec51b5e..4d1c3750eb5e 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h @@ -90,7 +90,7 @@ #define S5P_FIMV_E_H264_OPTIONS_V8 0xfb54 /* MFCv8 Context buffer sizes */ -#define MFC_CTX_BUF_SIZE_V8 (30 * SZ_1K) /* 30KB */ +#define MFC_CTX_BUF_SIZE_V8 (36 * SZ_1K) /* 36KB */ #define MFC_H264_DEC_CTX_BUF_SIZE_V8 (2 * SZ_1M) /* 2MB */ #define MFC_OTHER_DEC_CTX_BUF_SIZE_V8 (20 * SZ_1K) /* 20KB */ #define MFC_H264_ENC_CTX_BUF_SIZE_V8 (100 * SZ_1K) /* 100KB */ -- cgit v1.2.3 From 5d1ec73184e657fb2b429f8742cd7cb42336bc45 Mon Sep 17 00:00:00 2001 From: Donghwa Lee Date: Thu, 10 Nov 2016 08:31:22 -0200 Subject: [media] s5p-mfc: Skip incomplete frame Currently, when incomplete frame is received in the middle of decoding, driver treats it as an error, so src/dst queue and clock are cleaned. Although it is obviously error case, it is needed to maintain video decoding in case of necessity. This patch supports skip incomplete frame to next. Signed-off-by: Donghwa Lee Signed-off-by: Seung-Woo Kim Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/regs-mfc.h | 3 +++ drivers/media/platform/s5p-mfc/s5p_mfc.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/regs-mfc.h b/drivers/media/platform/s5p-mfc/regs-mfc.h index 6ccc3f8c122a..57b7e0be0596 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc.h @@ -393,6 +393,9 @@ #define S5P_FIMV_REG_CLEAR_COUNT 0 /* Error handling defines */ +#define S5P_FIMV_ERR_NO_VALID_SEQ_HDR 67 +#define S5P_FIMV_ERR_INCOMPLETE_FRAME 124 +#define S5P_FIMV_ERR_TIMEOUT 140 #define S5P_FIMV_ERR_WARNINGS_START 145 #define S5P_FIMV_ERR_DEC_MASK 0xFFFF #define S5P_FIMV_ERR_DEC_SHIFT 0 diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 3436eda58855..9f73ba1cc9c3 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -641,8 +641,11 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) case S5P_MFC_R2H_CMD_ERR_RET: /* An error has occurred */ if (ctx->state == MFCINST_RUNNING && - s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >= - dev->warn_start) + (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >= + dev->warn_start || + err == S5P_FIMV_ERR_NO_VALID_SEQ_HDR || + err == S5P_FIMV_ERR_INCOMPLETE_FRAME || + err == S5P_FIMV_ERR_TIMEOUT)) s5p_mfc_handle_frame(ctx, reason, err); else s5p_mfc_handle_error(dev, ctx, reason, err); -- cgit v1.2.3 From c5086f130a77009dd1dcacf0fbc2ca83f09ebca4 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 10 Nov 2016 08:31:23 -0200 Subject: [media] s5p-mfc: Use clock gating only on MFC v5 hardware Newer MFC hardware have internal clock gating feature, so additional software-triggered clock gating sometimes causes misbehavior of the MFC firmware and results in freeze or crash. This patch changes the driver to use software-triggered clock gating only when working with v5 MFC hardware, where it has been proven to work properly. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 + drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 ++ drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 17 +++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 9f73ba1cc9c3..ba6e2c5bca05 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1442,6 +1442,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { .buf_size = &buf_size_v5, .buf_align = &mfc_buf_align_v5, .fw_name[0] = "s5p-mfc.fw", + .use_clock_gating = true, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 46b99f28cbd7..c068ee3ece6e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -199,6 +199,7 @@ struct s5p_mfc_buf { struct s5p_mfc_pm { struct clk *clock; struct clk *clock_gate; + bool use_clock_gating; atomic_t power; struct device *device; }; @@ -235,6 +236,7 @@ struct s5p_mfc_variant { struct s5p_mfc_buf_size *buf_size; struct s5p_mfc_buf_align *buf_align; char *fw_name[MFC_FW_MAX_VERSIONS]; + bool use_clock_gating; }; /** diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 930dc2dddae6..b5806ab7ac31 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -37,6 +37,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) pm = &dev->pm; p_dev = dev; + pm->use_clock_gating = dev->variant->use_clock_gating; pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME); if (IS_ERR(pm->clock_gate)) { mfc_err("Failed to get clock-gating control\n"); @@ -108,6 +109,8 @@ int s5p_mfc_clock_on(void) atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); #endif + if (!pm->use_clock_gating) + return 0; if (!IS_ERR_OR_NULL(pm->clock_gate)) ret = clk_enable(pm->clock_gate); return ret; @@ -119,22 +122,32 @@ void s5p_mfc_clock_off(void) atomic_dec(&clk_ref); mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); #endif + if (!pm->use_clock_gating) + return; if (!IS_ERR_OR_NULL(pm->clock_gate)) clk_disable(pm->clock_gate); } int s5p_mfc_power_on(void) { + int ret = 0; + #ifdef CONFIG_PM - return pm_runtime_get_sync(pm->device); + ret = pm_runtime_get_sync(pm->device); + if (ret) + return ret; #else atomic_set(&pm->power, 1); - return 0; #endif + if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) + ret = clk_enable(pm->clock_gate); + return ret; } int s5p_mfc_power_off(void) { + if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) + clk_disable(pm->clock_gate); #ifdef CONFIG_PM return pm_runtime_put_sync(pm->device); #else -- cgit v1.2.3 From c0026c7bfb95c250c3e34fde59f96ad72fd730d6 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 14 Nov 2016 12:09:26 -0200 Subject: [media] s5p-mfc: Fix clock management in s5p_mfc_release() function Clock control indirectly requires access to MFC device, so call it only if we are sure that the device exists in s5p_mfc_release function. s5p_mfc_remove() calls s5p_mfc_final_pm(), which releases all PM related resources, including clocks, so any call to clocks related functions is not valid after s5p_mfc_final_pm(). Fixes: d695c12 ("[media] media: s5p-mfc fix invalid memory access from s5p_mfc_release()") Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index ba6e2c5bca05..320124352e82 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -929,10 +929,11 @@ static int s5p_mfc_release(struct file *file) mfc_debug_enter(); if (dev) mutex_lock(&dev->mfc_mutex); - s5p_mfc_clock_on(); vb2_queue_release(&ctx->vq_src); vb2_queue_release(&ctx->vq_dst); if (dev) { + s5p_mfc_clock_on(); + /* Mark context as idle */ clear_work_bit_irqsave(ctx); /* @@ -954,9 +955,9 @@ static int s5p_mfc_release(struct file *file) if (s5p_mfc_power_off() < 0) mfc_err("Power off failed\n"); } + mfc_debug(2, "Shutting down clock\n"); + s5p_mfc_clock_off(); } - mfc_debug(2, "Shutting down clock\n"); - s5p_mfc_clock_off(); if (dev) dev->ctx[ctx->num] = NULL; s5p_mfc_dec_ctrls_delete(ctx); -- cgit v1.2.3 From a45267ae40081ef5c54f9f9e0aac4697188d8297 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 27 Oct 2016 06:23:09 -0200 Subject: [media] dtv-core: get rid of duplicated kernel-doc include Somehow, two DVB headers were included twice. Remove the duplication Reported-by: Markus Heiser Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-core.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index a3c4642eabfc..ff86bf0abeae 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -8,14 +8,6 @@ Digital TV Common functions .. kernel-doc:: drivers/media/dvb-core/dvbdev.h - - -.. kernel-doc:: drivers/media/dvb-core/dvb_math.h - :export: drivers/media/dvb-core/dvb_math.c - -.. kernel-doc:: drivers/media/dvb-core/dvbdev.h - :export: drivers/media/dvb-core/dvbdev.c - Digital TV Ring buffer ---------------------- -- cgit v1.2.3 From 9e3d073009d271b694a1187414663fa89b968523 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 14 Nov 2016 13:50:42 -0200 Subject: [media] docs-rst: cleanup SVG files The SVG files are larger than the draw dimentions, have long lines and aren't cleaned. Use inkscape to automatically fix those issues. Signed-off-by: Mauro Carvalho Chehab --- .../media/media_api_files/typical_media_device.svg | 2974 +++++++++++++++++++- .../subdev-image-processing-crop.svg | 335 ++- .../subdev-image-processing-full.svg | 865 +++++- ...ubdev-image-processing-scaling-multi-source.svg | 606 +++- 4 files changed, 4471 insertions(+), 309 deletions(-) diff --git a/Documentation/media/media_api_files/typical_media_device.svg b/Documentation/media/media_api_files/typical_media_device.svg index f0c82f72c4b6..0c8abd69f39a 100644 --- a/Documentation/media/media_api_files/typical_media_device.svg +++ b/Documentation/media/media_api_files/typical_media_device.svg @@ -1,28 +1,2948 @@ -Audio decoder -Video decoder -Audio encoder -Button Key/IR input logic -EEPROM -Sensor -System Bus -Demux -Conditional Access Module -Video encoder -Radio / Analog TV -Digital TV -PS.: picture is not complete: other blocks may be present -Webcam -Processing blocks -Smartcard -TunerFM/TV -Satellite Equipment Control (SEC) -Demod -I2C Bus (control bus) -Digital TV Frontend - -CPU -PCI, USB, SPI, I2C, ... -Bridge - DMA - +image/svg+xmlAudio decoder +Video decoder +Audio encoder +Button Key/IR input logic +EEPROM +Sensor +System Bus +Demux +Conditional Access Module +Video encoder +Radio / Analog TV +Digital TV +PS.: picture is not complete: other blocks may be present +Webcam +Processing blocks +Smartcard +TunerFM/TV +Satellite Equipment Control (SEC) +Demod +I2C Bus (control bus) +Digital TV Frontend + +CPU +PCI, USB, SPI, I2C, ... +Bridge + DMA + \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-crop.svg b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-crop.svg index 18b0f5de9ed2..1903dd3846c2 100644 --- a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-crop.svg +++ b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-crop.svg @@ -1,63 +1,302 @@ - - - - - - + + + + + image/svg+xml + + + + + + + + + + + - - - + + + - - sink - crop - selection + + sink + crop + selection - - + + - - sink media - bus format + + sink media + bus format - - source media - bus format + + source media + bus format - - - + + + - - - - - - - - + + + + + + + + - - - - + + + + - - pad 1 (source) + + pad 1 (source) - - - - + + + + - - - - + + + + - - pad 0 (sink) + + pad 0 (sink) diff --git a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-full.svg b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-full.svg index 3322cf4c0093..91cf51832c12 100644 --- a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-full.svg +++ b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-full.svg @@ -1,163 +1,742 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pad 0 (sink) + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pad 0 (sink) - - pad 2 (source) + + pad 2 (source) - - - + + + - - - + + + - - + + - - sink media - bus format + + sink media + bus format - - - - - - - - - - sink compose - selection (scaling) + + + + + + + + + + sink compose + selection (scaling) - - - + + + - - source media - bus format + + source media + bus format - - - - - - - - - - sink compose - bounds selection + + + + + + + + + + sink compose + bounds selection - - - - - - - - - - - - pad 1 (sink) + + + + + + + + + + + + pad 1 (sink) - - - + + + - - - + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - pad 3 (source) + + + + + + + + + + + + + + + + + + + + + + + + + + pad 3 (source) - - sink - crop - selection + + sink + crop + selection - - source - crop - selection + + source + crop + selection - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.svg b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.svg index 2340c0f8bc92..cedcbf598923 100644 --- a/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.svg +++ b/Documentation/media/uapi/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.svg @@ -1,116 +1,540 @@ - - - - - - + + + + + image/svg+xml + + + + + + + + + + + - - - + + + - - sink - crop - selection + + sink + crop + selection - - + + - - sink media - bus format + + sink media + bus format - - - + + + - - - - - - sink compose - selection (scaling) + + + + + + sink compose + selection (scaling) - - - + + + - - source - crop - selection + + source + crop + selection - - source media - bus format + + source media + bus format - - - + + + - - - - - - - - + + + + + + + + - - - - + + + + - - pad 1 (source) + + pad 1 (source) - - - - + + + + - - - - + + + + - - pad 0 (sink) + + pad 0 (sink) - - - - + + + + - - - - - - - - + + + + + + + + - - - - + + + + - - pad 2 (source) + + pad 2 (source) - - - - + + + + - - - - + + + + -- cgit v1.2.3 From a8cd47d3608e47de0be8cc36a2546e5930c17d2f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:39:45 -0300 Subject: [media] stb0899_drv: get rid of continuation lines This driver has printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'")', this won't work as expected anymore. So, use %*ph and get rid of it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stb0899_drv.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index 3d171b0e00c2..8e7cafb8f36a 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -485,15 +485,8 @@ int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u3 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) _stb0899_read_reg(state, (reg | 0x00ff)); - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) { - printk(" %02x", buf[i]); - } - printk("\n"); - } + dprintk(state->verbose, FE_DEBUGREG, 1, + "%s [0x%04x]: %*ph", __func__, reg, count, buf); return 0; err: @@ -522,14 +515,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, buf[1] = reg & 0xff; memcpy(&buf[2], data, count); - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) - printk(" %02x", data[i]); - printk("\n"); - } + dprintk(state->verbose, FE_DEBUGREG, 1, + "%s [0x%04x]: %*ph", __func__, reg, count, data); ret = i2c_transfer(state->i2c, &i2c_msg, 1); /* -- cgit v1.2.3 From fed9d8f3cd6b7e8dbb697377065ee3b88b6baa45 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:42:47 -0300 Subject: [media] stv090x: get rid of continuation lines This driver has printk continuation lines for debugging purposes. Since commit 563873318d32 ("Merge branch 'printk-cleanups'")', this won't work as expected anymore. So, use %*ph and get rid of it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv090x.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 25bdf6e0f963..42d62cc9a357 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -739,14 +739,8 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 buf[1] = reg & 0xff; memcpy(&buf[2], data, count); - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) - printk(" %02x", data[i]); - printk("\n"); - } + dprintk(FE_DEBUGREG, 1, "%s [0x%04x]: %*ph", + __func__, reg, count, data); ret = i2c_transfer(state->i2c, &i2c_msg, 1); if (ret != 1) { -- cgit v1.2.3 From 7c646913530e2dc7fc679f31c1e5624277ef3c19 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Oct 2016 15:57:58 -0300 Subject: [media] bt8xx/dst: use a more standard way to print messages This driver uses a weird, non-standard macro to print errors. It allows hiding all messages, including error ones, with doesn't seem a good idea. Instead, replace it to pr_foo(), and, for error messages, use pr_err(). The remaining messages were previouly classified as notice, info or debug, but they all looked like debug messages. So, add a dprintk() macro using the "verbose" modprobe argument to select what will be displayed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/dst.c | 262 +++++++++++++++++++----------------------- 1 file changed, 118 insertions(+), 144 deletions(-) diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index 35bc9b2287b4..faea3f06e350 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c @@ -18,6 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -30,9 +32,9 @@ #include "dst_priv.h" #include "dst_common.h" -static unsigned int verbose = 1; +static unsigned int verbose; module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); +MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)"); static unsigned int dst_addons; module_param(dst_addons, int, 0644); @@ -46,29 +48,10 @@ MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); #define ATTEMPT_TUNE 2 #define HAS_POWER 4 -#define DST_ERROR 0 -#define DST_NOTICE 1 -#define DST_INFO 2 -#define DST_DEBUG 3 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > DST_ERROR) && (x > y)) \ - printk(KERN_ERR "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_INFO) && (x > y)) \ - printk(KERN_INFO "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ##arg); \ - } \ +#define dprintk(level, fmt, arg...) do { \ + if (level >= verbose) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ } while(0) static int dst_command(struct dst_state *state, u8 *data, u8 len); @@ -91,9 +74,11 @@ static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, enb.enb.mask = mask; enb.enb.enable = enbb; - dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh); + dprintk(2, "mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", + mask, enbb, outhigh); if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { - dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb); + dprintk(2, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", + err, mask, enbb); return -EREMOTEIO; } udelay(1000); @@ -105,7 +90,8 @@ static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, bits.outp.mask = enbb; bits.outp.highvals = outhigh; if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { - dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh); + dprintk(2, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", + err, enbb, outhigh); return -EREMOTEIO; } @@ -119,7 +105,7 @@ static int dst_gpio_inb(struct dst_state *state, u8 *result) *result = 0; if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); + pr_err("dst_gpio_inb error (err == %i)\n", err); return -EREMOTEIO; } *result = (u8) rd_packet.rd.value; @@ -129,14 +115,14 @@ static int dst_gpio_inb(struct dst_state *state, u8 *result) int rdc_reset_state(struct dst_state *state) { - dprintk(verbose, DST_INFO, 1, "Resetting state machine"); + dprintk(2, "Resetting state machine\n"); if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); return -1; } msleep(10); if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); msleep(10); return -1; } @@ -147,14 +133,14 @@ EXPORT_SYMBOL(rdc_reset_state); static int rdc_8820_reset(struct dst_state *state) { - dprintk(verbose, DST_DEBUG, 1, "Resetting DST"); + dprintk(3, "Resetting DST\n"); if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); return -1; } udelay(1000); if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); return -1; } @@ -164,7 +150,7 @@ static int rdc_8820_reset(struct dst_state *state) static int dst_pio_enable(struct dst_state *state) { if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); return -1; } udelay(1000); @@ -175,7 +161,7 @@ static int dst_pio_enable(struct dst_state *state) int dst_pio_disable(struct dst_state *state) { if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); + pr_err("dst_gpio_outb ERROR !\n"); return -1; } if (state->type_flags & DST_TYPE_HAS_FW_1) @@ -192,16 +178,16 @@ int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) for (i = 0; i < 200; i++) { if (dst_gpio_inb(state, &reply) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !"); + pr_err("dst_gpio_inb ERROR !\n"); return -1; } if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { - dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i); + dprintk(2, "dst wait ready after %d\n", i); return 1; } msleep(10); } - dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i); + dprintk(1, "dst wait NOT ready after %d\n", i); return 0; } @@ -209,7 +195,7 @@ EXPORT_SYMBOL(dst_wait_dst_ready); int dst_error_recovery(struct dst_state *state) { - dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors."); + dprintk(1, "Trying to return from previous errors.\n"); dst_pio_disable(state); msleep(10); dst_pio_enable(state); @@ -221,7 +207,7 @@ EXPORT_SYMBOL(dst_error_recovery); int dst_error_bailout(struct dst_state *state) { - dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error."); + dprintk(2, "Trying to bailout from previous error.\n"); rdc_8820_reset(state); dst_pio_disable(state); msleep(10); @@ -232,13 +218,13 @@ EXPORT_SYMBOL(dst_error_bailout); int dst_comm_init(struct dst_state *state) { - dprintk(verbose, DST_INFO, 1, "Initializing DST."); + dprintk(2, "Initializing DST.\n"); if ((dst_pio_enable(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed"); + pr_err("PIO Enable Failed\n"); return -1; } if ((rdc_reset_state(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed."); + pr_err("RDC 8820 State RESET Failed.\n"); return -1; } if (state->type_flags & DST_TYPE_HAS_FW_1) @@ -260,23 +246,21 @@ int write_dst(struct dst_state *state, u8 *data, u8 len) }; int err; - u8 cnt, i; + u8 cnt; - dprintk(verbose, DST_NOTICE, 0, "writing [ "); - for (i = 0; i < len; i++) - dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]); - dprintk(verbose, DST_NOTICE, 0, "]\n"); + dprintk(1, "writing [ %*ph ]\n", len, data); for (cnt = 0; cnt < 2; cnt++) { if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { - dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]); + dprintk(2, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", + err, len, data[0]); dst_error_recovery(state); continue; } else break; } if (cnt >= 2) { - dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); + dprintk(2, "RDC 8820 RESET\n"); dst_error_bailout(state); return -1; @@ -300,23 +284,20 @@ int read_dst(struct dst_state *state, u8 *ret, u8 len) for (cnt = 0; cnt < 2; cnt++) { if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { - dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]); + dprintk(2, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", + err, len, ret[0]); dst_error_recovery(state); continue; } else break; } if (cnt >= 2) { - dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); + dprintk(2, "RDC 8820 RESET\n"); dst_error_bailout(state); return -1; } - dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]); - for (err = 1; err < len; err++) - dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]); - if (err > 1) - dprintk(verbose, DST_DEBUG, 0, "\n"); + dprintk(3, "reply is %*ph\n", len, ret); return 0; } @@ -326,11 +307,11 @@ static int dst_set_polarization(struct dst_state *state) { switch (state->voltage) { case SEC_VOLTAGE_13: /* Vertical */ - dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]"); + dprintk(2, "Polarization=[Vertical]\n"); state->tx_tuna[8] &= ~0x40; break; case SEC_VOLTAGE_18: /* Horizontal */ - dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]"); + dprintk(2, "Polarization=[Horizontal]\n"); state->tx_tuna[8] |= 0x40; break; case SEC_VOLTAGE_OFF: @@ -343,7 +324,7 @@ static int dst_set_polarization(struct dst_state *state) static int dst_set_freq(struct dst_state *state, u32 freq) { state->frequency = freq; - dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq); + dprintk(2, "set Frequency %u\n", freq); if (state->dst_type == DST_TYPE_IS_SAT) { freq = freq / 1000; @@ -463,7 +444,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) if (state->dst_type == DST_TYPE_IS_TERR) { return -EOPNOTSUPP; } - dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); + dprintk(2, "set symrate %u\n", srate); srate /= 1000; if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_SYMDIV) { @@ -471,7 +452,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) sval <<= 20; do_div(sval, 88000); symcalc = (u32) sval; - dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); + dprintk(2, "set symcalc %u\n", symcalc); state->tx_tuna[5] = (u8) (symcalc >> 12); state->tx_tuna[6] = (u8) (symcalc >> 4); state->tx_tuna[7] = (u8) (symcalc << 4); @@ -486,7 +467,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) state->tx_tuna[8] |= 0x20; } } else if (state->dst_type == DST_TYPE_IS_CABLE) { - dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); + dprintk(3, "%s\n", state->fw_name); if (!strncmp(state->fw_name, "DCTNEW", 6)) { state->tx_tuna[5] = (u8) (srate >> 8); state->tx_tuna[6] = (u8) srate; @@ -561,24 +542,24 @@ static void dst_type_flags_print(struct dst_state *state) { u32 type_flags = state->type_flags; - dprintk(verbose, DST_ERROR, 0, "DST type flags :"); + pr_err("DST type flags :\n"); if (type_flags & DST_TYPE_HAS_TS188) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); + pr_err(" 0x%x newtuner\n", DST_TYPE_HAS_TS188); if (type_flags & DST_TYPE_HAS_NEWTUNE_2) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); + pr_err(" 0x%x newtuner 2\n", DST_TYPE_HAS_NEWTUNE_2); if (type_flags & DST_TYPE_HAS_TS204) - dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); + pr_err(" 0x%x ts204\n", DST_TYPE_HAS_TS204); if (type_flags & DST_TYPE_HAS_VLF) - dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); + pr_err(" 0x%x VLF\n", DST_TYPE_HAS_VLF); if (type_flags & DST_TYPE_HAS_SYMDIV) - dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); + pr_err(" 0x%x symdiv\n", DST_TYPE_HAS_SYMDIV); if (type_flags & DST_TYPE_HAS_FW_1) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); + pr_err(" 0x%x firmware version = 1\n", DST_TYPE_HAS_FW_1); if (type_flags & DST_TYPE_HAS_FW_2) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); + pr_err(" 0x%x firmware version = 2\n", DST_TYPE_HAS_FW_2); if (type_flags & DST_TYPE_HAS_FW_3) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); - dprintk(verbose, DST_ERROR, 0, "\n"); + pr_err(" 0x%x firmware version = 3\n", DST_TYPE_HAS_FW_3); + pr_err("\n"); } @@ -603,10 +584,10 @@ static int dst_type_print(struct dst_state *state, u8 type) break; default: - dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); + dprintk(2, "invalid dst type %d\n", type); return -EINVAL; } - dprintk(verbose, DST_INFO, 1, "DST type: %s", otype); + dprintk(2, "DST type: %s\n", otype); return 0; } @@ -914,12 +895,12 @@ static int dst_get_mac(struct dst_state *state) u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; get_mac[7] = dst_check_sum(get_mac, 7); if (dst_command(state, get_mac, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + dprintk(2, "Unsupported Command\n"); return -1; } memset(&state->mac_address, '\0', 8); memcpy(&state->mac_address, &state->rxbuffer, 6); - dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address); + pr_err("MAC Address=[%pM]\n", state->mac_address); return 0; } @@ -929,11 +910,11 @@ static int dst_fw_ver(struct dst_state *state) u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; get_ver[7] = dst_check_sum(get_ver, 7); if (dst_command(state, get_ver, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + dprintk(2, "Unsupported Command\n"); return -1; } memcpy(&state->fw_version, &state->rxbuffer, 8); - dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x", + pr_err("Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x\n", state->fw_version[0] >> 4, state->fw_version[0] & 0x0f, state->fw_version[1], state->fw_version[5], state->fw_version[6], @@ -950,17 +931,17 @@ static int dst_card_type(struct dst_state *state) u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; get_type[7] = dst_check_sum(get_type, 7); if (dst_command(state, get_type, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + dprintk(2, "Unsupported Command\n"); return -1; } memset(&state->card_info, '\0', 8); memcpy(&state->card_info, &state->rxbuffer, 7); - dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); + pr_err("Device Model=[%s]\n", &state->card_info[0]); for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { state->tuner_type = p_tuner_list->tuner_type; - dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", + pr_err("DST has [%s] tuner, tuner type=[%d]\n", p_tuner_list->tuner_name, p_tuner_list->tuner_type); } } @@ -973,26 +954,19 @@ static int dst_get_vendor(struct dst_state *state) u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; get_vendor[7] = dst_check_sum(get_vendor, 7); if (dst_command(state, get_vendor, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + dprintk(2, "Unsupported Command\n"); return -1; } memset(&state->vendor, '\0', 8); memcpy(&state->vendor, &state->rxbuffer, 7); - dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); + pr_err("Vendor=[%s]\n", &state->vendor[0]); return 0; } static void debug_dst_buffer(struct dst_state *state) { - int i; - - if (verbose > 2) { - printk("%s: [", __func__); - for (i = 0; i < 8; i++) - printk(" %02x", state->rxbuffer[i]); - printk("]\n"); - } + dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer); } static int dst_check_stv0299(struct dst_state *state) @@ -1001,13 +975,13 @@ static int dst_check_stv0299(struct dst_state *state) check_stv0299[7] = dst_check_sum(check_stv0299, 7); if (dst_command(state, check_stv0299, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); + pr_err("Cmd=[0x04] failed\n"); return -1; } debug_dst_buffer(state); if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { - dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); + pr_err("Found a STV0299 NIM\n"); state->tuner_type = TUNER_TYPE_STV0299; return 0; } @@ -1021,13 +995,13 @@ static int dst_check_mb86a15(struct dst_state *state) check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); if (dst_command(state, check_mb86a15, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); + pr_err("Cmd=[0x10], failed\n"); return -1; } debug_dst_buffer(state); if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); + pr_err("Found a MB86A15 NIM\n"); state->tuner_type = TUNER_TYPE_MB86A15; return 0; } @@ -1042,21 +1016,21 @@ static int dst_get_tuner_info(struct dst_state *state) get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); - dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); + pr_err("DST TYpe = MULTI FE\n"); if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { if (dst_command(state, get_tuner_1, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); + dprintk(2, "Cmd=[0x13], Unsupported\n"); goto force; } } else { if (dst_command(state, get_tuner_2, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); + dprintk(2, "Cmd=[0xb], Unsupported\n"); goto force; } } memcpy(&state->board_info, &state->rxbuffer, 8); if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { - dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); + pr_err("DST type has TS=188\n"); } if (state->board_info[0] == 0xbc) { if (state->dst_type != DST_TYPE_IS_ATSC) @@ -1066,7 +1040,7 @@ static int dst_get_tuner_info(struct dst_state *state) if (state->board_info[1] == 0x01) { state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; - dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); + pr_err("DST has Daughterboard\n"); } } @@ -1074,7 +1048,7 @@ static int dst_get_tuner_info(struct dst_state *state) force: if (!strncmp(state->fw_name, "DCT-CI", 6)) { state->type_flags |= DST_TYPE_HAS_TS204; - dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); + pr_err("Forcing [%s] to TS188\n", state->fw_name); } return -1; @@ -1103,7 +1077,7 @@ static int dst_get_device_id(struct dst_state *state) if (read_dst(state, &reply, GET_ACK)) return -1; /* Read failure */ if (reply != ACK) { - dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply); + dprintk(2, "Write not Acknowledged! [Reply=0x%02x]\n", reply); return -1; /* Unack'd write */ } if (!dst_wait_dst_ready(state, DEVICE_INIT)) @@ -1113,7 +1087,7 @@ static int dst_get_device_id(struct dst_state *state) dst_pio_disable(state); if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { - dprintk(verbose, DST_INFO, 1, "Checksum failure!"); + dprintk(2, "Checksum failure!\n"); return -1; /* Checksum failure */ } state->rxbuffer[7] = '\0'; @@ -1125,7 +1099,7 @@ static int dst_get_device_id(struct dst_state *state) /* Card capabilities */ state->dst_hw_cap = p_dst_type->dst_feature; - dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); + pr_err("Recognise [%s]\n", p_dst_type->device_id); strncpy(&state->fw_name[0], p_dst_type->device_id, 6); /* Multiple tuners */ if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { @@ -1133,7 +1107,7 @@ static int dst_get_device_id(struct dst_state *state) case DST_TYPE_IS_SAT: /* STV0299 check */ if (dst_check_stv0299(state) < 0) { - dprintk(verbose, DST_ERROR, 1, "Unsupported"); + pr_err("Unsupported\n"); state->tuner_type = TUNER_TYPE_MB86A15; } break; @@ -1141,7 +1115,7 @@ static int dst_get_device_id(struct dst_state *state) break; } if (dst_check_mb86a15(state) < 0) - dprintk(verbose, DST_ERROR, 1, "Unsupported"); + pr_err("Unsupported\n"); /* Single tuner */ } else { state->tuner_type = p_dst_type->tuner_type; @@ -1149,7 +1123,7 @@ static int dst_get_device_id(struct dst_state *state) for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && p_tuner_list->tuner_type == state->tuner_type) { - dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", + pr_err("[%s] has a [%s]\n", p_dst_type->device_id, p_tuner_list->tuner_name); } } @@ -1158,8 +1132,8 @@ static int dst_get_device_id(struct dst_state *state) } if (i >= ARRAY_SIZE(dst_tlist)) { - dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]); - dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in"); + pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]); + pr_err("please email linux-dvb@linuxtv.org with this type in"); use_dst_type = DST_TYPE_IS_SAT; use_type_flags = DST_TYPE_HAS_SYMDIV; } @@ -1176,7 +1150,7 @@ static int dst_probe(struct dst_state *state) mutex_init(&state->dst_mutex); if (dst_addons & DST_TYPE_HAS_CA) { if ((rdc_8820_reset(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); + pr_err("RDC 8820 RESET Failed.\n"); return -1; } msleep(4000); @@ -1184,35 +1158,35 @@ static int dst_probe(struct dst_state *state) msleep(100); } if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); + pr_err("DST Initialization Failed.\n"); return -1; } msleep(100); if (dst_get_device_id(state) < 0) { - dprintk(verbose, DST_ERROR, 1, "unknown device."); + pr_err("unknown device.\n"); return -1; } if (dst_get_mac(state) < 0) { - dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); + dprintk(2, "MAC: Unsupported command\n"); } if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { if (dst_get_tuner_info(state) < 0) - dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command"); + dprintk(2, "Tuner: Unsupported command\n"); } if (state->type_flags & DST_TYPE_HAS_TS204) { dst_packsize(state, 204); } if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { if (dst_fw_ver(state) < 0) { - dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); + dprintk(2, "FW: Unsupported command\n"); return 0; } if (dst_card_type(state) < 0) { - dprintk(verbose, DST_INFO, 1, "Card: Unsupported command"); + dprintk(2, "Card: Unsupported command\n"); return 0; } if (dst_get_vendor(state) < 0) { - dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command"); + dprintk(2, "Vendor: Unsupported command\n"); return 0; } } @@ -1226,33 +1200,33 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len) mutex_lock(&state->dst_mutex); if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); + dprintk(1, "DST Communication Initialization Failed.\n"); goto error; } if (write_dst(state, data, len)) { - dprintk(verbose, DST_INFO, 1, "Trying to recover.. "); + dprintk(2, "Trying to recover..\n"); if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); + pr_err("Recovery Failed.\n"); goto error; } goto error; } if ((dst_pio_disable(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); + pr_err("PIO Disable Failed.\n"); goto error; } if (state->type_flags & DST_TYPE_HAS_FW_1) mdelay(3); if (read_dst(state, &reply, GET_ACK)) { - dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); + dprintk(3, "Trying to recover..\n"); if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_INFO, 1, "Recovery Failed."); + dprintk(2, "Recovery Failed.\n"); goto error; } goto error; } if (reply != ACK) { - dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); + dprintk(2, "write not acknowledged 0x%02x\n", reply); goto error; } if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) @@ -1264,15 +1238,15 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len) if (!dst_wait_dst_ready(state, NO_DELAY)) goto error; if (read_dst(state, state->rxbuffer, FIXED_COMM)) { - dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); + dprintk(3, "Trying to recover..\n"); if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_INFO, 1, "Recovery failed."); + dprintk(2, "Recovery failed.\n"); goto error; } goto error; } if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { - dprintk(verbose, DST_INFO, 1, "checksum failure"); + dprintk(2, "checksum failure\n"); goto error; } mutex_unlock(&state->dst_mutex); @@ -1348,19 +1322,19 @@ static int dst_get_tuna(struct dst_state *state) else retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); if (retval < 0) { - dprintk(verbose, DST_DEBUG, 1, "read not successful"); + dprintk(3, "read not successful\n"); return retval; } if ((state->type_flags & DST_TYPE_HAS_VLF) && !(state->dst_type == DST_TYPE_IS_ATSC)) { if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { - dprintk(verbose, DST_INFO, 1, "checksum failure ? "); + dprintk(2, "checksum failure ?\n"); return -EIO; } } else { if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { - dprintk(verbose, DST_INFO, 1, "checksum failure? "); + dprintk(2, "checksum failure?\n"); return -EIO; } } @@ -1387,7 +1361,7 @@ static int dst_write_tuna(struct dvb_frontend *fe) int retval; u8 reply; - dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags); + dprintk(2, "type_flags 0x%x\n", state->type_flags); state->decode_freq = 0; state->decode_lock = state->decode_strength = state->decode_snr = 0; if (state->dst_type == DST_TYPE_IS_SAT) { @@ -1397,7 +1371,7 @@ static int dst_write_tuna(struct dvb_frontend *fe) state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); mutex_lock(&state->dst_mutex); if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); + dprintk(3, "DST Communication initialization failed.\n"); goto error; } // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { @@ -1412,19 +1386,19 @@ static int dst_write_tuna(struct dvb_frontend *fe) } if (retval < 0) { dst_pio_disable(state); - dprintk(verbose, DST_DEBUG, 1, "write not successful"); + dprintk(3, "write not successful\n"); goto werr; } if ((dst_pio_disable(state)) < 0) { - dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); + dprintk(3, "DST PIO disable failed !\n"); goto error; } if ((read_dst(state, &reply, GET_ACK) < 0)) { - dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); + dprintk(3, "read verify not successful.\n"); goto error; } if (reply != ACK) { - dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); + dprintk(3, "write not acknowledged 0x%02x\n", reply); goto error; } state->diseq_flags |= ATTEMPT_TUNE; @@ -1622,7 +1596,7 @@ static int dst_set_frontend(struct dvb_frontend *fe) retval = dst_set_freq(state, p->frequency); if(retval != 0) return retval; - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); + dprintk(3, "Set Frequency=[%d]\n", p->frequency); if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) @@ -1630,7 +1604,7 @@ static int dst_set_frontend(struct dvb_frontend *fe) dst_set_fec(state, p->fec_inner); dst_set_symbolrate(state, p->symbol_rate); dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); + dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate); } else if (state->dst_type == DST_TYPE_IS_TERR) dst_set_bandwidth(state, p->bandwidth_hz); @@ -1656,7 +1630,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe, if (re_tune) { dst_set_freq(state, p->frequency); - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); + dprintk(3, "Set Frequency=[%d]\n", p->frequency); if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) @@ -1664,7 +1638,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe, dst_set_fec(state, p->fec_inner); dst_set_symbolrate(state, p->symbol_rate); dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); + dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate); } else if (state->dst_type == DST_TYPE_IS_TERR) dst_set_bandwidth(state, p->bandwidth_hz); @@ -1750,7 +1724,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); break; default: - dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); + pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n"); kfree(state); return NULL; } -- cgit v1.2.3 From fa132a64e2003c72c149725ffa7bae06b0cc9054 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 06:33:25 -0300 Subject: [media] bt8xx: use pr_foo() macros instead of printk() Replace printk() macros by their pr_foo() counterparts, using pr_cont() for continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/btcx-risc.c | 46 +++++++++++++++++++++---------------- drivers/media/pci/bt8xx/dvb-bt8xx.c | 25 +++++++++++--------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/drivers/media/pci/bt8xx/btcx-risc.c b/drivers/media/pci/bt8xx/btcx-risc.c index 57c7f58c3af2..70bdf93fc020 100644 --- a/drivers/media/pci/bt8xx/btcx-risc.c +++ b/drivers/media/pci/bt8xx/btcx-risc.c @@ -22,6 +22,8 @@ */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -36,6 +38,13 @@ static unsigned int btcx_debug; module_param(btcx_debug, int, 0644); MODULE_PARM_DESC(btcx_debug,"debug messages, default is 0 (no)"); +#define dprintk(fmt, arg...) do { \ + if (btcx_debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) + + /* ---------------------------------------------------------- */ /* allocate/free risc memory */ @@ -46,11 +55,11 @@ void btcx_riscmem_free(struct pci_dev *pci, { if (NULL == risc->cpu) return; - if (btcx_debug) { - memcnt--; - printk("btcx: riscmem free [%d] dma=%lx\n", - memcnt, (unsigned long)risc->dma); - } + + memcnt--; + dprintk("btcx: riscmem free [%d] dma=%lx\n", + memcnt, (unsigned long)risc->dma); + pci_free_consistent(pci, risc->size, risc->cpu, risc->dma); memset(risc,0,sizeof(*risc)); } @@ -71,11 +80,10 @@ int btcx_riscmem_alloc(struct pci_dev *pci, risc->cpu = cpu; risc->dma = dma; risc->size = size; - if (btcx_debug) { - memcnt++; - printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n", - memcnt, (unsigned long)dma, cpu, size); - } + + memcnt++; + dprintk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n", + memcnt, (unsigned long)dma, cpu, size); } memset(risc->cpu,0,risc->size); return 0; @@ -137,9 +145,8 @@ btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int m dx = nx - win->left; win->left = nx; win->width = nw; - if (btcx_debug) - printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n", - win->width, win->height, win->left, win->top, dx); + dprintk("btcx: window align %dx%d+%d+%d [dx=%d]\n", + win->width, win->height, win->left, win->top, dx); /* fixup clips */ for (i = 0; i < n; i++) { @@ -149,10 +156,9 @@ btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int m nw += mask+1; clips[i].c.left = nx; clips[i].c.width = nw; - if (btcx_debug) - printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n", - clips[i].c.width, clips[i].c.height, - clips[i].c.left, clips[i].c.top); + dprintk("btcx: clip align %dx%d+%d+%d\n", + clips[i].c.width, clips[i].c.height, + clips[i].c.left, clips[i].c.top); } return 0; } @@ -228,10 +234,10 @@ btcx_calc_skips(int line, int width, int *maxy, *maxy = maxline; if (btcx_debug) { - printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline); + dprintk("btcx: skips line %d-%d:", line, maxline); for (skip = 0; skip < *nskips; skip++) { - printk(" %d-%d",skips[skip].start,skips[skip].end); + pr_cont(" %d-%d", skips[skip].start, skips[skip].end); } - printk("\n"); + pr_cont("\n"); } } diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c index e69d338ab9be..6100fa71ece8 100644 --- a/drivers/media/pci/bt8xx/dvb-bt8xx.c +++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c @@ -19,7 +19,7 @@ * */ -#define pr_fmt(fmt) "dvb_bt8xx: " fmt +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -44,10 +44,12 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk( args... ) \ - do { \ - if (debug) printk(KERN_DEBUG args); \ - } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) + #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ @@ -55,7 +57,7 @@ static void dvb_bt8xx_task(unsigned long data) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data; - //printk("%d ", card->bt->finished_block); + dprintk("%d\n", card->bt->finished_block); while (card->bt->last_block != card->bt->finished_block) { (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) @@ -443,7 +445,7 @@ static void or51211_reset(struct dvb_frontend * fe) /* reset & PRM1,2&4 are outputs */ int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F); if (ret != 0) - printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret); + pr_warn("or51211: Init Error - Can't Reset DVR (%i)\n", ret); bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */ msleep(20); /* Now set for normal operation */ @@ -560,7 +562,8 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08); if (ret != 0) - printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret); + pr_warn("digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", + ret); /* Pulse the reset line */ bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ @@ -620,7 +623,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) dvb_attach(simple_tuner_attach, card->fe, card->i2c_adapter, 0x61, TUNER_LG_TDVS_H06XF); - dprintk ("dvb_bt8xx: lgdt330x detected\n"); + dprintk("dvb_bt8xx: lgdt330x detected\n"); } break; @@ -635,7 +638,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter); if (card->fe != NULL) { card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; - dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); + dprintk("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); break; } @@ -645,7 +648,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) if (card->fe != NULL) { card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; - dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); + dprintk("dvb_bt8xx: an mt352 was detected on your digitv card\n"); } break; -- cgit v1.2.3 From 09f8be263c9c5fa0ee33e24e1f89b8cde68ec056 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 06:50:56 -0300 Subject: [media] cx23885: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. While here, add missing log level annotations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-core.c | 8 ++++---- drivers/media/pci/cx23885/cx23885-i2c.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 5020a60a4f1f..0d97da3be90b 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -407,12 +407,12 @@ static int cx23885_risc_decode(u32 risc) }; int i; - printk("0x%08x [ %s", risc, + printk(KERN_DEBUG "0x%08x [ %s", risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) if (risc & (1 << (i + 12))) - printk(" %s", bits[i]); - printk(" count=%d ]\n", risc & 0xfff); + printk(KERN_CONT " %s", bits[i]); + printk(KERN_CONT " count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; } @@ -2003,7 +2003,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, pci_set_master(pci_dev); err = pci_set_dma_mask(pci_dev, 0xffffffff); if (err) { - printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); + printk(KERN_ERR "%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); goto fail_ctrl; } diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c index 61591225be9a..19faf9a611ed 100644 --- a/drivers/media/pci/cx23885/cx23885-i2c.c +++ b/drivers/media/pci/cx23885/cx23885-i2c.c @@ -119,9 +119,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; if (i2c_debug) { - printk(" addr << 1, msg->buf[0]); + printk(KERN_DEBUG " addr << 1, msg->buf[0]); if (!(ctrl & I2C_NOSTOP)) - printk(" >\n"); + printk(KERN_CONT " >\n"); } for (cnt = 1; cnt < msg->len; cnt++) { @@ -141,9 +141,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); + printk(KERN_CONT " %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); + printk(KERN_CONT " >\n"); } } return msg->len; -- cgit v1.2.3 From f1dc10b6e18df849429c1625bbcdf04ecc25d5c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 14 Nov 2016 11:14:37 -0200 Subject: gp8psk-fe: add missing MODULE_foo() macros This file was converted to a separate module at commit 7a0786c19d65 ("gp8psk: Fix DVB frontend attach"), because the DVB attach routines require it to work. However, I forgot to copy the MODULE_foo() macros from the original module, causing this warning: WARNING: modpost: missing MODULE_LICENSE() in drivers/media/dvb-frontends/gp8psk-fe.o Reported-by: Stephen Rothwell Fixes: 7a0786c19d65 ("gp8psk: Fix DVB frontend attach") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Linus Torvalds --- drivers/media/dvb-frontends/gp8psk-fe.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb-frontends/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c index be19afeed7a9..93f59bfea092 100644 --- a/drivers/media/dvb-frontends/gp8psk-fe.c +++ b/drivers/media/dvb-frontends/gp8psk-fe.c @@ -1,5 +1,5 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module +/* + * Frontend driver for the GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module * * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com) * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com) @@ -8,11 +8,9 @@ * * This module is based off the vp7045 and vp702x modules * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -395,3 +393,8 @@ static struct dvb_frontend_ops gp8psk_fe_ops = { .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage }; + +MODULE_AUTHOR("Alan Nisota "); +MODULE_DESCRIPTION("Frontend Driver for Genpix DVB-S"); +MODULE_VERSION("1.1"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e39682b5d96ae7a33a0f6b5578911913be8f14b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Nov 2016 09:46:11 -0200 Subject: [media] cx23885: convert it to use pr_foo() macros Instead of calling printk() directly, use pr_foo() macros, as suggested at the Kernel's coding style. Please notice that a conversion to dev_foo() is not trivial, as several parts on this driver uses pr_cont(). Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/altera-ci.c | 15 ++-- drivers/media/pci/cx23885/altera-ci.h | 14 +-- drivers/media/pci/cx23885/cimax2.c | 8 +- drivers/media/pci/cx23885/cx23885-417.c | 57 ++++++------- drivers/media/pci/cx23885/cx23885-alsa.c | 21 ++--- drivers/media/pci/cx23885/cx23885-cards.c | 49 ++++++----- drivers/media/pci/cx23885/cx23885-core.c | 137 ++++++++++++++---------------- drivers/media/pci/cx23885/cx23885-dvb.c | 40 ++++----- drivers/media/pci/cx23885/cx23885-f300.c | 2 +- drivers/media/pci/cx23885/cx23885-i2c.c | 25 +++--- drivers/media/pci/cx23885/cx23885-input.c | 6 +- drivers/media/pci/cx23885/cx23885-ir.c | 4 +- drivers/media/pci/cx23885/cx23885-vbi.c | 7 +- drivers/media/pci/cx23885/cx23885-video.c | 23 ++--- drivers/media/pci/cx23885/cx23885.h | 2 + drivers/media/pci/cx23885/cx23888-ir.c | 6 +- drivers/media/pci/cx23885/netup-eeprom.c | 4 +- drivers/media/pci/cx23885/netup-init.c | 8 +- 18 files changed, 209 insertions(+), 219 deletions(-) diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index aaf4e46ff3e9..5c94e312cba3 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c @@ -48,6 +48,9 @@ * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| * +-------+-------+-------+-------+-------+-------+-------+-------+ */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "altera-ci.h" @@ -84,16 +87,18 @@ MODULE_DESCRIPTION("altera FPGA CI module"); MODULE_AUTHOR("Igor M. Liplianin "); MODULE_LICENSE("GPL"); -#define ci_dbg_print(args...) \ +#define ci_dbg_print(fmt, args...) \ do { \ if (ci_dbg) \ - printk(KERN_DEBUG args); \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##args); \ } while (0) -#define pid_dbg_print(args...) \ +#define pid_dbg_print(fmt, args...) \ do { \ if (pid_dbg) \ - printk(KERN_DEBUG args); \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##args); \ } while (0) struct altera_ci_state; @@ -718,7 +723,7 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr) if (temp_int != NULL) { inter = temp_int->internal; (inter->cis_used)++; - inter->fpga_rw = config->fpga_rw; + inter->fpga_rw = config->fpga_rw; ci_dbg_print("%s: Find Internal Structure!\n", __func__); } else { inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL); diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h index 57a40c84b46e..ababd80fee93 100644 --- a/drivers/media/pci/cx23885/altera-ci.h +++ b/drivers/media/pci/cx23885/altera-ci.h @@ -48,24 +48,24 @@ extern int altera_ci_tuner_reset(void *dev, int ci_nr); static inline int altera_ci_init(struct altera_ci_config *config, int ci_nr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return 0; } static inline void altera_ci_release(void *dev, int ci_nr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); } static inline int altera_ci_irq(void *dev) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return 0; } static inline int altera_ci_tuner_reset(void *dev, int ci_nr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return 0; } @@ -74,19 +74,19 @@ static inline int altera_ci_tuner_reset(void *dev, int ci_nr) static inline int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return 0; } static inline void altera_hw_filt_release(void *dev, int filt_nr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); } static inline int altera_pid_feed_control(void *dev, int filt_nr, struct dvb_demux_feed *dvbdmxfeed, int onoff) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return 0; } diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c index d644c65622e2..5e8e134d81c2 100644 --- a/drivers/media/pci/cx23885/cimax2.c +++ b/drivers/media/pci/cx23885/cimax2.c @@ -65,10 +65,11 @@ static unsigned int ci_irq_enable; module_param(ci_irq_enable, int, 0644); MODULE_PARM_DESC(ci_irq_enable, "Enable IRQ from CAM"); -#define ci_dbg_print(args...) \ +#define ci_dbg_print(fmt, args...) \ do { \ if (ci_dbg) \ - printk(KERN_DEBUG args); \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##args); \ } while (0) #define ci_irq_flags() (ci_irq_enable ? NETUP_IRQ_IRQAM : 0) @@ -135,8 +136,7 @@ static int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, }; if (1 + len > sizeof(buffer)) { - printk(KERN_WARNING - "%s: i2c wr reg=%04x: len=%d is too big!\n", + pr_warn("%s: i2c wr reg=%04x: len=%d is too big!\n", KBUILD_MODNAME, reg, len); return -EINVAL; } diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index 0c122585a1f0..2ff1d1e274be 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -20,6 +20,9 @@ * GNU General Public License for more details. */ +#include "cx23885.h" +#include "cx23885-ioctl.h" + #include #include #include @@ -32,9 +35,6 @@ #include #include -#include "cx23885.h" -#include "cx23885-ioctl.h" - #define CX23885_FIRM_IMAGE_SIZE 376836 #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -55,8 +55,8 @@ MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); #define dprintk(level, fmt, arg...)\ do { if (v4l_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, \ - (dev) ? dev->name : "cx23885[?]", ## arg); \ + printk(KERN_DEBUG pr_fmt("%s: 417:" fmt), \ + __func__, ##arg); \ } while (0) static struct cx23885_tvnorm cx23885_tvnorms[] = { @@ -769,8 +769,7 @@ static int cx23885_mbox_func(void *priv, without side effects */ mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); if (value != 0x12345678) { - printk(KERN_ERR - "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n", + pr_err("Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n", value, cmd_to_str(command)); return -1; } @@ -780,7 +779,7 @@ static int cx23885_mbox_func(void *priv, */ mc417_memory_read(dev, dev->cx23417_mailbox, &flag); if (flag) { - printk(KERN_ERR "ERROR: Mailbox appears to be in use (%x), cmd = %s\n", + pr_err("ERROR: Mailbox appears to be in use (%x), cmd = %s\n", flag, cmd_to_str(command)); return -1; } @@ -810,7 +809,7 @@ static int cx23885_mbox_func(void *priv, if (0 != (flag & 4)) break; if (time_after(jiffies, timeout)) { - printk(KERN_ERR "ERROR: API Mailbox timeout\n"); + pr_err("ERROR: API Mailbox timeout\n"); return -1; } udelay(10); @@ -887,7 +886,7 @@ static int cx23885_find_mailbox(struct cx23885_dev *dev) return i+1; } } - printk(KERN_ERR "Mailbox signature values not found!\n"); + pr_err("Mailbox signature values not found!\n"); return -1; } @@ -922,7 +921,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) IVTV_REG_APU, 0); if (retval != 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", + pr_err("%s: Error with mc417_register_write\n", __func__); return -1; } @@ -931,23 +930,21 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) &dev->pci->dev); if (retval != 0) { - printk(KERN_ERR - "ERROR: Hotplug firmware request failed (%s).\n", - CX23885_FIRM_IMAGE_NAME); - printk(KERN_ERR "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + pr_err("ERROR: Hotplug firmware request failed (%s).\n", + CX23885_FIRM_IMAGE_NAME); + pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { - printk(KERN_ERR "ERROR: Firmware size mismatch (have %zu, expected %d)\n", - firmware->size, CX23885_FIRM_IMAGE_SIZE); + pr_err("ERROR: Firmware size mismatch (have %zu, expected %d)\n", + firmware->size, CX23885_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; } if (0 != memcmp(firmware->data, magic, 8)) { - printk(KERN_ERR - "ERROR: Firmware magic mismatch, wrong file?\n"); + pr_err("ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -1; } @@ -959,7 +956,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) value = *dataptr; checksum += ~value; if (mc417_memory_write(dev, i, value) != 0) { - printk(KERN_ERR "ERROR: Loading firmware failed!\n"); + pr_err("ERROR: Loading firmware failed!\n"); release_firmware(firmware); return -1; } @@ -970,15 +967,14 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) dprintk(1, "Verifying firmware ...\n"); for (i--; i >= 0; i--) { if (mc417_memory_read(dev, i, &value) != 0) { - printk(KERN_ERR "ERROR: Reading firmware failed!\n"); + pr_err("ERROR: Reading firmware failed!\n"); release_firmware(firmware); return -1; } checksum -= ~value; } if (checksum) { - printk(KERN_ERR - "ERROR: Firmware load failed (checksum mismatch).\n"); + pr_err("ERROR: Firmware load failed (checksum mismatch).\n"); release_firmware(firmware); return -1; } @@ -1003,7 +999,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) mc417_register_read(dev, 0x900C, &gpio_value); if (retval < 0) - printk(KERN_ERR "%s: Error with mc417_register_write\n", + pr_err("%s: Error with mc417_register_write\n", __func__); return 0; } @@ -1055,26 +1051,25 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder) dprintk(2, "%s() PING OK\n", __func__); retval = cx23885_load_firmware(dev); if (retval < 0) { - printk(KERN_ERR "%s() f/w load failed\n", __func__); + pr_err("%s() f/w load failed\n", __func__); return retval; } retval = cx23885_find_mailbox(dev); if (retval < 0) { - printk(KERN_ERR "%s() mailbox < 0, error\n", + pr_err("%s() mailbox < 0, error\n", __func__); return -1; } dev->cx23417_mailbox = retval; retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { - printk(KERN_ERR - "ERROR: cx23417 firmware ping failed!\n"); + pr_err("ERROR: cx23417 firmware ping failed!\n"); return -1; } retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - printk(KERN_ERR "ERROR: cx23417 firmware get encoder :version failed!\n"); + pr_err("ERROR: cx23417 firmware get encoder :version failed!\n"); return -1; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); @@ -1559,11 +1554,11 @@ int cx23885_417_register(struct cx23885_dev *dev) err = video_register_device(dev->v4l_device, VFL_TYPE_GRABBER, -1); if (err < 0) { - printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); + pr_info("%s: can't register mpeg device\n", dev->name); return err; } - printk(KERN_INFO "%s: registered device %s [mpeg]\n", + pr_info("%s: registered device %s [mpeg]\n", dev->name, video_device_node_name(dev->v4l_device)); /* ST: Configure the encoder paramaters, but don't begin diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index 9d2a4e2dc54f..c148f9a4a9ac 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -17,6 +17,9 @@ * GNU General Public License for more details. */ +#include "cx23885.h" +#include "cx23885-reg.h" + #include #include #include @@ -35,20 +38,14 @@ #include - -#include "cx23885.h" -#include "cx23885-reg.h" - #define AUDIO_SRAM_CHANNEL SRAM_CH07 #define dprintk(level, fmt, arg...) do { \ if (audio_debug + 1 > level) \ - printk(KERN_INFO "%s: " fmt, chip->dev->name , ## arg); \ + printk(KERN_DEBUG pr_fmt("%s: alsa: " fmt), \ + chip->dev->name, ##arg); \ } while(0) -#define dprintk_core(level, fmt, arg...) if (audio_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, chip->dev->name , ## arg) - /**************************************************************************** Module global static vars ****************************************************************************/ @@ -247,7 +244,7 @@ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask) /* risc op code error */ if (status & AUD_INT_OPC_ERR) { - printk(KERN_WARNING "%s/1: Audio risc op code error\n", + pr_warn("%s/1: Audio risc op code error\n", dev->name); cx_clear(AUD_INT_DMA_CTL, 0x11); cx23885_sram_channel_dump(dev, @@ -327,7 +324,7 @@ static int snd_cx23885_pcm_open(struct snd_pcm_substream *substream) int err; if (!chip) { - printk(KERN_ERR "BUG: cx23885 can't find device struct. Can't proceed with open\n"); + pr_err("BUG: cx23885 can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -554,7 +551,7 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) return NULL; if (dev->sram_channels[AUDIO_SRAM_CHANNEL].cmds_start == 0) { - printk(KERN_WARNING "%s(): Missing SRAM channel configuration for analog TV Audio\n", + pr_warn("%s(): Missing SRAM channel configuration for analog TV Audio\n", __func__); return NULL; } @@ -589,7 +586,7 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) error: snd_card_free(card); - printk(KERN_ERR "%s(): Failed to register analog audio adapter\n", + pr_err("%s(): Failed to register analog audio adapter\n", __func__); return NULL; diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index e2c4edbfbdb7..0350f13c5a9f 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#include "cx23885.h" + #include #include #include @@ -23,7 +25,6 @@ #include #include -#include "cx23885.h" #include "tuner-xc2028.h" #include "netup-eeprom.h" #include "netup-init.h" @@ -1096,26 +1097,24 @@ void cx23885_card_list(struct cx23885_dev *dev) if (0 == dev->pci->subsystem_vendor && 0 == dev->pci->subsystem_device) { - printk(KERN_INFO - "%s: Board has no valid PCIe Subsystem ID and can't\n" - "%s: be autodetected. Pass card= insmod option\n" - "%s: to workaround that. Redirect complaints to the\n" - "%s: vendor of the TV card. Best regards,\n" - "%s: -- tux\n", - dev->name, dev->name, dev->name, dev->name, dev->name); + pr_info("%s: Board has no valid PCIe Subsystem ID and can't\n" + "%s: be autodetected. Pass card= insmod option\n" + "%s: to workaround that. Redirect complaints to the\n" + "%s: vendor of the TV card. Best regards,\n" + "%s: -- tux\n", + dev->name, dev->name, dev->name, dev->name, dev->name); } else { - printk(KERN_INFO - "%s: Your board isn't known (yet) to the driver.\n" - "%s: Try to pick one of the existing card configs via\n" - "%s: card= insmod option. Updating to the latest\n" - "%s: version might help as well.\n", - dev->name, dev->name, dev->name, dev->name); + pr_info("%s: Your board isn't known (yet) to the driver.\n" + "%s: Try to pick one of the existing card configs via\n" + "%s: card= insmod option. Updating to the latest\n" + "%s: version might help as well.\n", + dev->name, dev->name, dev->name, dev->name); } - printk(KERN_INFO "%s: Here is a list of valid choices for the card= insmod option:\n", + pr_info("%s: Here is a list of valid choices for the card= insmod option:\n", dev->name); for (i = 0; i < cx23885_bcount; i++) - printk(KERN_INFO "%s: card=%d -> %s\n", - dev->name, i, cx23885_boards[i].name); + pr_info("%s: card=%d -> %s\n", + dev->name, i, cx23885_boards[i].name); } static void viewcast_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) @@ -1304,13 +1303,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) */ break; default: - printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", + pr_warn("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); break; } - printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", - dev->name, tv.model); + pr_info("%s: hauppauge eeprom: model=%d\n", + dev->name, tv.model); } /* Some TBS cards require initing a chip using a bitbanged SPI attached @@ -1352,8 +1351,8 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) return 0; if (command != 0) { - printk(KERN_ERR "%s(): Unknown command 0x%x.\n", - __func__, command); + pr_err("%s(): Unknown command 0x%x.\n", + __func__, command); return -EINVAL; } @@ -2336,12 +2335,12 @@ void cx23885_card_setup(struct cx23885_dev *dev) filename = "dvb-netup-altera-01.fw"; break; } - printk(KERN_INFO "NetUP card rev=0x%x fw_filename=%s\n", - cinfo.rev, filename); + pr_info("NetUP card rev=0x%x fw_filename=%s\n", + cinfo.rev, filename); ret = request_firmware(&fw, filename, &dev->pci->dev); if (ret != 0) - printk(KERN_ERR "did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems.", + pr_err("did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems.", filename); else altera_init(&netup_config, fw); diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 0d97da3be90b..02b5ec549369 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#include "cx23885.h" + #include #include #include @@ -27,7 +29,6 @@ #include #include -#include "cx23885.h" #include "cimax2.h" #include "altera-ci.h" #include "cx23888-ir.h" @@ -50,7 +51,8 @@ MODULE_PARM_DESC(card, "card type"); #define dprintk(level, fmt, arg...)\ do { if (debug >= level)\ - printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ } while (0) static unsigned int cx23885_devcount; @@ -411,15 +413,14 @@ static int cx23885_risc_decode(u32 risc) instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) if (risc & (1 << (i + 12))) - printk(KERN_CONT " %s", bits[i]); - printk(KERN_CONT " count=%d ]\n", risc & 0xfff); + pr_cont(" %s", bits[i]); + pr_cont(" count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; } static void cx23885_wakeup(struct cx23885_tsport *port, struct cx23885_dmaqueue *q, u32 count) { - struct cx23885_dev *dev = port->dev; struct cx23885_buffer *buf; if (list_empty(&q->active)) @@ -530,44 +531,44 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev, u32 risc; unsigned int i, j, n; - printk(KERN_WARNING "%s: %s - dma channel status dump\n", - dev->name, ch->name); + pr_warn("%s: %s - dma channel status dump\n", + dev->name, ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) - printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n", - dev->name, name[i], - cx_read(ch->cmds_start + 4*i)); + pr_warn("%s: cmds: %-15s: 0x%08x\n", + dev->name, name[i], + cx_read(ch->cmds_start + 4*i)); for (i = 0; i < 4; i++) { risc = cx_read(ch->cmds_start + 4 * (i + 14)); - printk(KERN_WARNING "%s: risc%d: ", dev->name, i); + pr_warn("%s: risc%d: ", dev->name, i); cx23885_risc_decode(risc); } for (i = 0; i < (64 >> 2); i += n) { risc = cx_read(ch->ctrl_start + 4 * i); /* No consideration for bits 63-32 */ - printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name, - ch->ctrl_start + 4 * i, i); + pr_warn("%s: (0x%08x) iq %x: ", dev->name, + ch->ctrl_start + 4 * i, i); n = cx23885_risc_decode(risc); for (j = 1; j < n; j++) { risc = cx_read(ch->ctrl_start + 4 * (i + j)); - printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n", - dev->name, i+j, risc, j); + pr_warn("%s: iq %x: 0x%08x [ arg #%d ]\n", + dev->name, i+j, risc, j); } } - printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n", - dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n", - dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); - printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr1_reg)); - printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr2_reg)); - printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt1_reg)); - printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt2_reg)); + pr_warn("%s: fifo: 0x%08x -> 0x%x\n", + dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); + pr_warn("%s: ctrl: 0x%08x -> 0x%x\n", + dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); + pr_warn("%s: ptr1_reg: 0x%08x\n", + dev->name, cx_read(ch->ptr1_reg)); + pr_warn("%s: ptr2_reg: 0x%08x\n", + dev->name, cx_read(ch->ptr2_reg)); + pr_warn("%s: cnt1_reg: 0x%08x\n", + dev->name, cx_read(ch->cnt1_reg)); + pr_warn("%s: cnt2_reg: 0x%08x\n", + dev->name, cx_read(ch->cnt2_reg)); } static void cx23885_risc_disasm(struct cx23885_tsport *port, @@ -576,14 +577,14 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port, struct cx23885_dev *dev = port->dev; unsigned int i, j, n; - printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n", + pr_info("%s: risc disasm: %p [dma=0x%08lx]\n", dev->name, risc->cpu, (unsigned long)risc->dma); for (i = 0; i < (risc->size >> 2); i += n) { - printk(KERN_INFO "%s: %04d: ", dev->name, i); + pr_info("%s: %04d: ", dev->name, i); n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) - printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n", - dev->name, i + j, risc->cpu[i + j], j); + pr_info("%s: %04d: 0x%08x [ arg #%d ]\n", + dev->name, i + j, risc->cpu[i + j], j); if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) break; } @@ -674,8 +675,8 @@ static int get_resources(struct cx23885_dev *dev) dev->name)) return 0; - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", - dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); + pr_err("%s: can't get MMIO memory @ 0x%llx\n", + dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); return -EBUSY; } @@ -793,15 +794,15 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) dev->hwrevision = 0xb1; break; default: - printk(KERN_ERR "%s() New hardware revision found 0x%x\n", - __func__, dev->hwrevision); + pr_err("%s() New hardware revision found 0x%x\n", + __func__, dev->hwrevision); } if (dev->hwrevision) - printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", + pr_info("%s() Hardware revision = 0x%02x\n", __func__, dev->hwrevision); else - printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", - __func__, dev->hwrevision); + pr_err("%s() Hardware revision unknown 0x%x\n", + __func__, dev->hwrevision); } /* Find the first v4l2_subdev member of the group id in hw */ @@ -915,7 +916,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_init_tsport(dev, &dev->ts2, 2); if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for subsystem: %04x:%04x\n", + pr_err("CORE %s No more PCIe resources for subsystem: %04x:%04x\n", dev->name, dev->pci->subsystem_vendor, dev->pci->subsystem_device); @@ -929,11 +930,11 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->bmmio = (u8 __iomem *)dev->lmmio; - printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, cx23885_boards[dev->board].name, - dev->board, card[dev->nr] == dev->board ? - "insmod option" : "autodetected"); + pr_info("CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + dev->name, dev->pci->subsystem_vendor, + dev->pci->subsystem_device, cx23885_boards[dev->board].name, + dev->board, card[dev->nr] == dev->board ? + "insmod option" : "autodetected"); cx23885_pci_quirks(dev); @@ -979,7 +980,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { if (cx23885_video_register(dev) < 0) { - printk(KERN_ERR "%s() Failed to register analog video adapters on VID_A\n", + pr_err("%s() Failed to register analog video adapters on VID_A\n", __func__); } } @@ -989,14 +990,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->ts1.num_frontends = cx23885_boards[dev->board].num_fds_portb; if (cx23885_dvb_register(&dev->ts1) < 0) { - printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", + pr_err("%s() Failed to register dvb adapters on VID_B\n", __func__); } } else if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_B\n", + pr_err("%s() Failed to register 417 on VID_B\n", __func__); } } @@ -1006,15 +1006,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->ts2.num_frontends = cx23885_boards[dev->board].num_fds_portc; if (cx23885_dvb_register(&dev->ts2) < 0) { - printk(KERN_ERR - "%s() Failed to register dvb on VID_C\n", + pr_err("%s() Failed to register dvb on VID_C\n", __func__); } } else if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) { if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_C\n", + pr_err("%s() Failed to register 417 on VID_C\n", __func__); } } @@ -1343,7 +1341,7 @@ int cx23885_start_dma(struct cx23885_tsport *port, if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { - printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", + pr_err("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", __func__, cx23885_boards[dev->board].portb, cx23885_boards[dev->board].portc); @@ -1530,7 +1528,6 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) static void do_cancel_buffers(struct cx23885_tsport *port, char *reason) { - struct cx23885_dev *dev = port->dev; struct cx23885_dmaqueue *q = &port->mpegq; struct cx23885_buffer *buf; unsigned long flags; @@ -1550,8 +1547,6 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason) void cx23885_cancel_buffers(struct cx23885_tsport *port) { - struct cx23885_dev *dev = port->dev; - dprintk(1, "%s()\n", __func__); cx23885_stop_dma(port); do_cancel_buffers(port, "cancel"); @@ -1578,7 +1573,7 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status) (status & VID_B_MSK_VBI_SYNC) || (status & VID_B_MSK_OF) || (status & VID_B_MSK_VBI_OF)) { - printk(KERN_ERR "%s: V4L mpeg risc op code error, status = 0x%x\n", + pr_err("%s: V4L mpeg risc op code error, status = 0x%x\n", dev->name, status); if (status & VID_B_MSK_BAD_PKT) dprintk(1, " VID_B_MSK_BAD_PKT\n"); @@ -1640,7 +1635,7 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); - printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); + pr_err("%s: mpeg risc op code error\n", dev->name); cx_clear(port->reg_dma_ctl, port->dma_ctl_val); cx23885_sram_channel_dump(dev, @@ -1880,15 +1875,14 @@ void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask) if (mask & 0x0007fff8) { if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Setting GPIO on encoder ports\n", + pr_err("%s: Setting GPIO on encoder ports\n", dev->name); cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3); } /* TODO: 23-19 */ if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); + pr_info("%s: Unsupported\n", dev->name); } void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) @@ -1898,15 +1892,14 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) if (mask & 0x0007fff8) { if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Clearing GPIO moving on encoder ports\n", + pr_err("%s: Clearing GPIO moving on encoder ports\n", dev->name); cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3); } /* TODO: 23-19 */ if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); + pr_info("%s: Unsupported\n", dev->name); } u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask) @@ -1916,15 +1909,14 @@ u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask) if (mask & 0x0007fff8) { if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Reading GPIO moving on encoder ports\n", + pr_err("%s: Reading GPIO moving on encoder ports\n", dev->name); return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3; } /* TODO: 23-19 */ if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); + pr_info("%s: Unsupported\n", dev->name); return 0; } @@ -1938,8 +1930,7 @@ void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) if (mask & 0x0007fff8) { if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Enabling GPIO on encoder ports\n", + pr_err("%s: Enabling GPIO on encoder ports\n", dev->name); } @@ -1994,7 +1985,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat, @@ -2003,14 +1994,14 @@ static int cx23885_initdev(struct pci_dev *pci_dev, pci_set_master(pci_dev); err = pci_set_dma_mask(pci_dev, 0xffffffff); if (err) { - printk(KERN_ERR "%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); + pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); goto fail_ctrl; } err = request_irq(pci_dev->irq, cx23885_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", + pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); goto fail_irq; } @@ -2096,7 +2087,7 @@ static struct pci_driver cx23885_pci_driver = { static int __init cx23885_init(void) { - printk(KERN_INFO "cx23885 driver version %s loaded\n", + pr_info("cx23885 driver version %s loaded\n", CX23885_VERSION); return pci_register_driver(&cx23885_pci_driver); } diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 42413fa423b4..589a168d1df4 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#include "cx23885.h" + #include #include #include @@ -23,7 +25,6 @@ #include #include -#include "cx23885.h" #include #include "dvb_ca_en50221.h" @@ -80,7 +81,8 @@ static unsigned int debug; #define dprintk(level, fmt, arg...)\ do { if (debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ + printk(KERN_DEBUG pr_fmt("%s dvb: " fmt), \ + __func__, ##arg); \ } while (0) /* ------------------------------------------------------------------ */ @@ -1101,7 +1103,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port) netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); memcpy(port->frontends.adapter.proposed_mac, cinfo.port[port->nr - 1].mac, 6); - printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", + pr_info("NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", port->nr, port->frontends.adapter.proposed_mac); netup_ci_init(port); @@ -1127,7 +1129,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port) /* Read entire EEPROM */ dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); + pr_info("TeVii S470 MAC= %pM\n", eeprom + 0xa0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); return 0; } @@ -1144,7 +1146,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port) dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "%s port %d MAC address: %pM\n", + pr_info("%s port %d MAC address: %pM\n", cx23885_boards[dev->board].name, port->nr, eeprom + 0xc0 + (port->nr-1) * 8); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 + @@ -1185,7 +1187,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port) dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "%s MAC address: %pM\n", + pr_info("%s MAC address: %pM\n", cx23885_boards[dev->board].name, eeprom + 0xc0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6); return 0; @@ -1464,7 +1466,7 @@ static int dvb_register(struct cx23885_tsport *port) return -ENODEV; if (dib7000p_ops.i2c_enumeration(&i2c_bus->i2c_adap, 1, 0x12, &dib7070p_dib7000p_config) < 0) { - printk(KERN_WARNING "Unable to enumerate dib7000p\n"); + pr_warn("Unable to enumerate dib7000p\n"); return -ENODEV; } fe0->dvb.frontend = dib7000p_ops.init(&i2c_bus->i2c_adap, 0x80, &dib7070p_dib7000p_config); @@ -1524,7 +1526,7 @@ static int dvb_register(struct cx23885_tsport *port) fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc4000 attach failed\n", + pr_err("%s/2: xc4000 attach failed\n", dev->name); goto frontend_detach; } @@ -1597,8 +1599,7 @@ static int dvb_register(struct cx23885_tsport *port) &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x09)) - printk(KERN_ERR - "No LNBH24 found!\n"); + pr_err("No LNBH24 found!\n"); } } @@ -1618,8 +1619,7 @@ static int dvb_register(struct cx23885_tsport *port) &i2c_bus->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x0a)) - printk(KERN_ERR - "No LNBH24 found!\n"); + pr_err("No LNBH24 found!\n"); } } @@ -2482,13 +2482,13 @@ static int dvb_register(struct cx23885_tsport *port) break; default: - printk(KERN_INFO "%s: The frontend of your DVB/ATSC card isn't supported yet\n", - dev->name); + pr_info("%s: The frontend of your DVB/ATSC card isn't supported yet\n", + dev->name); break; } if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { - printk(KERN_ERR "%s: frontend initialization failed\n", + pr_err("%s: frontend initialization failed\n", dev->name); goto frontend_detach; } @@ -2569,7 +2569,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) * are for safety, and should provide a good foundation for the * future addition of any multi-frontend cx23885 based boards. */ - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, + pr_info("%s() allocating %d frontend(s)\n", __func__, port->num_frontends); for (i = 1; i <= port->num_frontends; i++) { @@ -2577,7 +2577,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) if (vb2_dvb_alloc_frontend( &port->frontends, i) == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); + pr_err("%s() failed to alloc\n", __func__); return -ENOMEM; } @@ -2596,7 +2596,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) /* dvb stuff */ /* We have to init the queue for each frontend on a port. */ - printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); + pr_info("%s: cx23885 based dvb card\n", dev->name); q = &fe0->dvb.dvbq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; @@ -2616,8 +2616,8 @@ int cx23885_dvb_register(struct cx23885_tsport *port) } err = dvb_register(port); if (err != 0) - printk(KERN_ERR "%s() dvb_register failed err = %d\n", - __func__, err); + pr_err("%s() dvb_register failed err = %d\n", + __func__, err); return err; } diff --git a/drivers/media/pci/cx23885/cx23885-f300.c b/drivers/media/pci/cx23885/cx23885-f300.c index a6c45eb0a105..460cb8f314b2 100644 --- a/drivers/media/pci/cx23885/cx23885-f300.c +++ b/drivers/media/pci/cx23885/cx23885-f300.c @@ -122,7 +122,7 @@ static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf) } if (i > 7) { - printk(KERN_ERR "%s: timeout, the slave no response\n", + pr_err("%s: timeout, the slave no response\n", __func__); ret = 1; /* timeout, the slave no response */ } else { /* the slave not busy, prepare for getting data */ diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c index 19faf9a611ed..8528032090f2 100644 --- a/drivers/media/pci/cx23885/cx23885-i2c.c +++ b/drivers/media/pci/cx23885/cx23885-i2c.c @@ -15,14 +15,14 @@ * GNU General Public License for more details. */ +#include "cx23885.h" + #include #include #include #include #include -#include "cx23885.h" - #include static unsigned int i2c_debug; @@ -35,7 +35,8 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); #define dprintk(level, fmt, arg...)\ do { if (i2c_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ + printk(KERN_DEBUG pr_fmt("%s: i2c:" fmt), \ + __func__, ##arg); \ } while (0) #define I2C_WAIT_DELAY 32 @@ -121,7 +122,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (i2c_debug) { printk(KERN_DEBUG " addr << 1, msg->buf[0]); if (!(ctrl & I2C_NOSTOP)) - printk(KERN_CONT " >\n"); + pr_cont(" >\n"); } for (cnt = 1; cnt < msg->len; cnt++) { @@ -141,9 +142,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; if (i2c_debug) { - printk(KERN_CONT " %02x", msg->buf[cnt]); + pr_cont(" %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) - printk(KERN_CONT " >\n"); + pr_cont(" >\n"); } } return msg->len; @@ -151,7 +152,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); + pr_err(" ERR: %d\n", retval); return retval; } @@ -212,15 +213,13 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); + pr_err(" ERR: %d\n", retval); return retval; } static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; int i, retval = 0; dprintk(1, "%s(num = %d)\n", __func__, num); @@ -302,7 +301,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) rc = i2c_master_recv(c, &buf, 0); if (rc < 0) continue; - printk(KERN_INFO "%s: i2c scan: found device @ 0x%04x [%s]\n", + pr_info("%s: i2c scan: found device @ 0x%04x [%s]\n", name, i, i2c_devs[i] ? i2c_devs[i] : "???"); } } @@ -330,12 +329,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) if (0 == bus->i2c_rc) { dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); if (i2c_scan) { - printk(KERN_INFO "%s: scan bus %d:\n", + pr_info("%s: scan bus %d:\n", dev->name, bus->nr); do_i2c_scan(dev->name, &bus->i2c_client); } } else - printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", + pr_warn("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); /* Instantiate the IR receiver device, if present */ diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 410c3141c163..1f092febdbd1 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -30,13 +30,13 @@ * GNU General Public License for more details. */ +#include "cx23885.h" +#include "cx23885-input.h" + #include #include #include -#include "cx23885.h" -#include "cx23885-input.h" - #define MODULE_NAME "cx23885" static void cx23885_input_process_measurements(struct cx23885_dev *dev, diff --git a/drivers/media/pci/cx23885/cx23885-ir.c b/drivers/media/pci/cx23885/cx23885-ir.c index 89dc4cc3e1ce..2cd5ac41ab75 100644 --- a/drivers/media/pci/cx23885/cx23885-ir.c +++ b/drivers/media/pci/cx23885/cx23885-ir.c @@ -16,12 +16,12 @@ * GNU General Public License for more details. */ -#include - #include "cx23885.h" #include "cx23885-ir.h" #include "cx23885-input.h" +#include + #define CX23885_IR_RX_FIFO_SERVICE_REQ 0 #define CX23885_IR_RX_END_OF_RX_DETECTED 1 #define CX23885_IR_RX_HW_FIFO_OVERRUN 2 diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c index 75e7fa7b1121..369e545cac04 100644 --- a/drivers/media/pci/cx23885/cx23885-vbi.c +++ b/drivers/media/pci/cx23885/cx23885-vbi.c @@ -15,13 +15,13 @@ * GNU General Public License for more details. */ +#include "cx23885.h" + #include #include #include #include -#include "cx23885.h" - static unsigned int vbibufs = 4; module_param(vbibufs, int, 0644); MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32"); @@ -32,7 +32,8 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); #define dprintk(level, fmt, arg...)\ do { if (vbi_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ + printk(KERN_DEBUG pr_fmt("%s: vbi:" fmt), \ + __func__, ##arg); \ } while (0) /* ------------------------------------------------------------------ */ diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 92ff452e5886..ecc580af0148 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -15,6 +15,9 @@ * GNU General Public License for more details. */ +#include "cx23885.h" +#include "cx23885-video.h" + #include #include #include @@ -27,8 +30,6 @@ #include #include -#include "cx23885.h" -#include "cx23885-video.h" #include #include #include @@ -66,7 +67,8 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); #define dprintk(level, fmt, arg...)\ do { if (video_debug >= level)\ - printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ + printk(KERN_DEBUG pr_fmt("%s: video:" fmt), \ + __func__, ##arg); \ } while (0) /* ------------------------------------------------------------------- */ @@ -194,7 +196,7 @@ u8 cx23885_flatiron_read(struct cx23885_dev *dev, u8 reg) ret = i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg[0], 2); if (ret != 2) - printk(KERN_ERR "%s() error\n", __func__); + pr_err("%s() error\n", __func__); return b1[0]; } @@ -811,7 +813,6 @@ static int vidioc_log_status(struct file *file, void *priv) static int cx23885_query_audinput(struct file *file, void *priv, struct v4l2_audio *i) { - struct cx23885_dev *dev = video_drvdata(file); static const char *iname[] = { [0] = "Baseband L/R 1", [1] = "Baseband L/R 2", @@ -1000,7 +1001,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, fe->ops.tuner_ops.set_analog_params(fe, ¶ms); } else - printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); + pr_err("%s() No analog tuner, aborting\n", __func__); /* When changing channels it is required to reset TVAUDIO */ msleep(100); @@ -1058,7 +1059,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) if (status & VID_BC_MSK_OPC_ERR) { dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); - printk(KERN_WARNING "%s: video risc op code error\n", + pr_warn("%s: video risc op code error\n", dev->name); cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]); @@ -1296,11 +1297,11 @@ int cx23885_video_register(struct cx23885_dev *dev) err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, video_nr[dev->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register video device\n", + pr_info("%s: can't register video device\n", dev->name); goto fail_unreg; } - printk(KERN_INFO "%s: registered device %s [v4l2]\n", + pr_info("%s: registered device %s [v4l2]\n", dev->name, video_device_node_name(dev->video_dev)); /* register VBI device */ @@ -1310,11 +1311,11 @@ int cx23885_video_register(struct cx23885_dev *dev) err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register vbi device\n", + pr_info("%s: can't register vbi device\n", dev->name); goto fail_unreg; } - printk(KERN_INFO "%s: registered device %s\n", + pr_info("%s: registered device %s\n", dev->name, video_device_node_name(dev->vbi_dev)); /* Register ALSA audio device */ diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index a6735afe2269..cb714ab60d69 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index 3115cfddab95..040323b0f945 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -16,15 +16,15 @@ * GNU General Public License for more details. */ +#include "cx23885.h" +#include "cx23888-ir.h" + #include #include #include #include -#include "cx23885.h" -#include "cx23888-ir.h" - static unsigned int ir_888_debug; module_param(ir_888_debug, int, 0644); MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]"); diff --git a/drivers/media/pci/cx23885/netup-eeprom.c b/drivers/media/pci/cx23885/netup-eeprom.c index b6542ee4385b..6384c12aa38e 100644 --- a/drivers/media/pci/cx23885/netup-eeprom.c +++ b/drivers/media/pci/cx23885/netup-eeprom.c @@ -52,7 +52,7 @@ int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr) ret = i2c_transfer(i2c_adap, msg, 2); if (ret != 2) { - printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret); + pr_err("eeprom i2c read error, status=%d\n", ret); return -1; } @@ -80,7 +80,7 @@ int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data) ret = i2c_transfer(i2c_adap, msg, 1); if (ret != 1) { - printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret); + pr_err("eeprom i2c write error, status=%d\n", ret); return -1; } diff --git a/drivers/media/pci/cx23885/netup-init.c b/drivers/media/pci/cx23885/netup-init.c index 76d9487aafc8..6a27ef5d9ec2 100644 --- a/drivers/media/pci/cx23885/netup-init.c +++ b/drivers/media/pci/cx23885/netup-init.c @@ -40,7 +40,7 @@ static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val) ret = i2c_transfer(i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); + pr_err("%s: i2c write error!\n", __func__); } static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val) @@ -64,7 +64,7 @@ static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val) ret = i2c_transfer(i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); + pr_err("%s: i2c write error!\n", __func__); } static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) @@ -84,7 +84,7 @@ static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) ret = i2c_transfer(i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); + pr_err("%s: i2c write error!\n", __func__); msg.flags = I2C_M_RD; msg.len = 1; @@ -92,7 +92,7 @@ static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) ret = i2c_transfer(i2c, &msg, 1); if (ret != 1) - printk(KERN_ERR "%s: i2c read error!\n", __func__); + pr_err("%s: i2c read error!\n", __func__); return buf[0]; } -- cgit v1.2.3 From 3b0cb24f96dc06d0c5c049e8327aad50c8b6ddb4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 06:58:14 -0300 Subject: [media] cx88: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups'"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. While here, add missing log level annotations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-core.c | 38 +++++++++++++++++++------------------- drivers/media/pci/cx88/cx88-dsp.c | 7 +------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 46fe8c1eb9d4..1ffd341f990d 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -399,12 +399,12 @@ static int cx88_risc_decode(u32 risc) }; int i; - printk("0x%08x [ %s", risc, + printk(KERN_DEBUG "0x%08x [ %s", risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); for (i = ARRAY_SIZE(bits)-1; i >= 0; i--) if (risc & (1 << (i + 12))) - printk(" %s",bits[i]); - printk(" count=%d ]\n", risc & 0xfff); + printk(KERN_CONT " %s", bits[i]); + printk(KERN_CONT " count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; } @@ -428,42 +428,42 @@ void cx88_sram_channel_dump(struct cx88_core *core, u32 risc; unsigned int i,j,n; - printk("%s: %s - dma channel status dump\n", + printk(KERN_DEBUG "%s: %s - dma channel status dump\n", core->name,ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) - printk("%s: cmds: %-12s: 0x%08x\n", + printk(KERN_DEBUG "%s: cmds: %-12s: 0x%08x\n", core->name,name[i], cx_read(ch->cmds_start + 4*i)); for (n = 1, i = 0; i < 4; i++) { risc = cx_read(ch->cmds_start + 4 * (i+11)); - printk("%s: risc%d: ", core->name, i); + printk(KERN_CONT "%s: risc%d: ", core->name, i); if (--n) - printk("0x%08x [ arg #%d ]\n", risc, n); + printk(KERN_CONT "0x%08x [ arg #%d ]\n", risc, n); else n = cx88_risc_decode(risc); } for (i = 0; i < 16; i += n) { risc = cx_read(ch->ctrl_start + 4 * i); - printk("%s: iq %x: ", core->name, i); + printk(KERN_DEBUG "%s: iq %x: ", core->name, i); n = cx88_risc_decode(risc); for (j = 1; j < n; j++) { risc = cx_read(ch->ctrl_start + 4 * (i+j)); - printk("%s: iq %x: 0x%08x [ arg #%d ]\n", + printk(KERN_CONT "%s: iq %x: 0x%08x [ arg #%d ]\n", core->name, i+j, risc, j); } } - printk("%s: fifo: 0x%08x -> 0x%x\n", + printk(KERN_DEBUG "%s: fifo: 0x%08x -> 0x%x\n", core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk("%s: ctrl: 0x%08x -> 0x%x\n", + printk(KERN_DEBUG "%s: ctrl: 0x%08x -> 0x%x\n", core->name, ch->ctrl_start, ch->ctrl_start+6*16); - printk("%s: ptr1_reg: 0x%08x\n", + printk(KERN_DEBUG "%s: ptr1_reg: 0x%08x\n", core->name,cx_read(ch->ptr1_reg)); - printk("%s: ptr2_reg: 0x%08x\n", + printk(KERN_DEBUG "%s: ptr2_reg: 0x%08x\n", core->name,cx_read(ch->ptr2_reg)); - printk("%s: cnt1_reg: 0x%08x\n", + printk(KERN_DEBUG "%s: cnt1_reg: 0x%08x\n", core->name,cx_read(ch->cnt1_reg)); - printk("%s: cnt2_reg: 0x%08x\n", + printk(KERN_DEBUG "%s: cnt2_reg: 0x%08x\n", core->name,cx_read(ch->cnt2_reg)); } @@ -484,14 +484,14 @@ void cx88_print_irqbits(const char *name, const char *tag, const char *strings[] if (!(bits & (1 << i))) continue; if (strings[i]) - printk(" %s", strings[i]); + printk(KERN_CONT " %s", strings[i]); else - printk(" %d", i); + printk(KERN_CONT " %d", i); if (!(mask & (1 << i))) continue; - printk("*"); + printk(KERN_CONT "*"); } - printk("\n"); + printk(KERN_CONT "\n"); } /* ------------------------------------------------------------------ */ diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 33f3c58f8197..57380c750702 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -257,12 +257,7 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) offset += 4; } - if (dsp_debug >= 2) { - dprintk(2, "RDS samples dump: "); - for (i = 0; i < sample_count; i++) - printk("%hd ", samples[i]); - printk(".\n"); - } + dprintk(2, "RDS samples dump: %*ph\n", sample_count, samples); return samples; } -- cgit v1.2.3 From 65bc2fe86e667077b38a63ce6cb40677be09bc4f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Nov 2016 10:07:38 -0200 Subject: [media] cx88: convert it to use pr_foo() macros Instead of calling printk() directly, use pr_foo() macros, as suggested at the Kernel's coding style. Please notice that a conversion to dev_foo() is not trivial, as several parts on this driver uses pr_cont(). Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 26 ++---- drivers/media/pci/cx88/cx88-blackbird.c | 31 +++---- drivers/media/pci/cx88/cx88-cards.c | 103 +++++++++------------ drivers/media/pci/cx88/cx88-core.c | 126 +++++++++++++------------ drivers/media/pci/cx88/cx88-dsp.c | 17 ++-- drivers/media/pci/cx88/cx88-dvb.c | 61 ++++++------ drivers/media/pci/cx88/cx88-i2c.c | 19 ++-- drivers/media/pci/cx88/cx88-input.c | 3 +- drivers/media/pci/cx88/cx88-mpeg.c | 153 ++++++++++++++----------------- drivers/media/pci/cx88/cx88-tvaudio.c | 15 +-- drivers/media/pci/cx88/cx88-vbi.c | 12 ++- drivers/media/pci/cx88/cx88-video.c | 71 +++++++------- drivers/media/pci/cx88/cx88-vp3054-i2c.c | 8 +- drivers/media/pci/cx88/cx88.h | 9 +- 14 files changed, 311 insertions(+), 343 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 495f9a0569e0..d2f1880a157e 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -24,6 +24,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" +#include "cx88-reg.h" + #include #include #include @@ -42,18 +45,11 @@ #include #include -#include "cx88.h" -#include "cx88-reg.h" - #define dprintk(level, fmt, arg...) do { \ if (debug + 1 > level) \ - printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg);\ -} while(0) - -#define dprintk_core(level, fmt, arg...) do { \ - if (debug + 1 > level) \ - printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg);\ -} while(0) + printk(KERN_DEBUG pr_fmt("%s: alsa: " fmt), \ + chip->core->name, ##arg); \ +} while (0) /**************************************************************************** Data type declarations - Can be moded to a header file later @@ -230,12 +226,12 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip) return; cx_write(MO_AUD_INTSTAT, status); if (debug > 1 || (status & mask & ~0xff)) - cx88_print_irqbits(core->name, "irq aud", + cx88_print_irqbits("irq aud", cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs), status, mask); /* risc op code error */ if (status & AUD_INT_OPC_ERR) { - printk(KERN_WARNING "%s/1: Audio risc op code error\n",core->name); + pr_warn("Audio risc op code error\n"); cx_clear(MO_AUD_DMACNTRL, 0x11); cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]); } @@ -279,9 +275,7 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id) } if (MAX_IRQ_LOOP == loop) { - printk(KERN_ERR - "%s/1: IRQ loop detected, disabling interrupts\n", - core->name); + pr_err("IRQ loop detected, disabling interrupts\n"); cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT); } @@ -423,7 +417,7 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) int err; if (!chip) { - printk(KERN_ERR "BUG: cx88 can't find device struct. Can't proceed with open\n"); + pr_err("BUG: cx88 can't find device struct. Can't proceed with open\n"); return -ENODEV; } diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index b532e49e8f33..4163e777825d 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -26,6 +26,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" + #include #include #include @@ -38,8 +40,6 @@ #include #include -#include "cx88.h" - MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); MODULE_AUTHOR("Jelle Foks , Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -49,10 +49,11 @@ static unsigned int debug; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); -#define dprintk(level, fmt, arg...) do { \ - if (debug + 1 > level) \ - printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg); \ -} while(0) +#define dprintk(level, fmt, arg...) do { \ + if (debug + 1 > level) \ + printk(KERN_DEBUG pr_fmt("%s: blackbird:" fmt), \ + __func__, ##arg); \ +} while (0) /* ------------------------------------------------------------------ */ @@ -446,14 +447,14 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) if (retval != 0) { pr_err("Hotplug firmware request failed (%s).\n", - CX2341X_FIRM_ENC_FILENAME); + CX2341X_FIRM_ENC_FILENAME); pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -EIO; } if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { pr_err("Firmware size mismatch (have %zd, expected %d)\n", - firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); + firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); release_firmware(firmware); return -EINVAL; } @@ -1118,12 +1119,11 @@ static int blackbird_register_video(struct cx8802_dev *dev) dev->mpeg_dev.queue = &dev->vb2_mpegq; err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1); if (err < 0) { - printk(KERN_INFO "%s/2: can't register mpeg device\n", - dev->core->name); + pr_info("can't register mpeg device\n"); return err; } - printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", - dev->core->name, video_device_node_name(&dev->mpeg_dev)); + pr_info("registered device %s [mpeg]\n", + video_device_node_name(&dev->mpeg_dev)); return 0; } @@ -1158,8 +1158,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL); /* blackbird stuff */ - printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", - core->name); + pr_info("cx23416 based mpeg encoder (blackbird reference design)\n"); host_setup(dev->core); blackbird_initialize_codec(dev); @@ -1219,8 +1218,8 @@ static struct cx8802_driver cx8802_blackbird_driver = { static int __init blackbird_init(void) { - printk(KERN_INFO "cx2388x blackbird driver version %s loaded\n", - CX88_VERSION); + pr_info("cx2388x blackbird driver version %s loaded\n", + CX88_VERSION); return cx8802_register_driver(&cx8802_blackbird_driver); } diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 31295b36dafc..1a65db957dcb 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -20,16 +20,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" +#include "tea5767.h" +#include "xc4000.h" + #include #include #include #include #include -#include "cx88.h" -#include "tea5767.h" -#include "xc4000.h" - static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; @@ -50,19 +50,11 @@ static int disable_ir; module_param(disable_ir, int, 0444); MODULE_PARM_DESC(disable_ir, "Disable IR support"); -#define info_printk(core, fmt, arg...) \ - printk(KERN_INFO "%s: " fmt, core->name , ## arg) - -#define warn_printk(core, fmt, arg...) \ - printk(KERN_WARNING "%s: " fmt, core->name , ## arg) - -#define err_printk(core, fmt, arg...) \ - printk(KERN_ERR "%s: " fmt, core->name , ## arg) - #define dprintk(level,fmt, arg...) do { \ if (cx88_core_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, core->name , ## arg); \ - } while(0) + printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \ + __func__, ##arg); \ +} while (0) /* ------------------------------------------------------------------ */ @@ -2829,7 +2821,7 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) if (eeprom_data[4] != 0x7d || eeprom_data[5] != 0x10 || eeprom_data[7] != 0x66) { - warn_printk(core, "Leadtek eeprom invalid.\n"); + pr_warn("Leadtek eeprom invalid.\n"); return; } @@ -2847,8 +2839,8 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) break; } - info_printk(core, "Leadtek Winfast 2000XP Expert config: tuner=%d, eeprom[0]=0x%02x\n", - core->board.tuner_type, eeprom_data[0]); + pr_info("Leadtek Winfast 2000XP Expert config: tuner=%d, eeprom[0]=0x%02x\n", + core->board.tuner_type, eeprom_data[0]); } static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) @@ -2904,12 +2896,11 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) cx_set(MO_GP0_IO, 0x008989FF); break; default: - warn_printk(core, "warning: unknown hauppauge model #%d\n", - tv.model); + pr_warn("warning: unknown hauppauge model #%d\n", tv.model); break; } - info_printk(core, "hauppauge eeprom: model=%d\n", tv.model); + pr_info("hauppauge eeprom: model=%d\n", tv.model); } /* ----------------------------------------------------------------------- */ @@ -2955,7 +2946,7 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) const char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) ? gdi_tuner[eeprom_data[0x0d]].name : NULL; - info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown"); + pr_info("GDI: tuner=%s\n", name ? name : "unknown"); if (NULL == name) return; core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; @@ -3106,8 +3097,8 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) msg.len = (i != 12 ? 5 : 2); err = i2c_transfer(&core->i2c_adap, &msg, 1); if (err != 1) { - warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", - i, err); + pr_warn("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", + i, err); return; } } @@ -3229,14 +3220,14 @@ int cx88_tuner_callback(void *priv, int component, int command, int arg) struct cx88_core *core; if (!i2c_algo) { - printk(KERN_ERR "cx88: Error - i2c private data undefined.\n"); + pr_err("Error - i2c private data undefined.\n"); return -EINVAL; } core = i2c_algo->data; if (!core) { - printk(KERN_ERR "cx88: Error - device struct undefined.\n"); + pr_err("Error - device struct undefined.\n"); return -EINVAL; } @@ -3254,8 +3245,8 @@ int cx88_tuner_callback(void *priv, int component, int command, int arg) dprintk(1, "Calling XC5000 callback\n"); return cx88_xc5000_tuner_callback(core, command, arg); } - err_printk(core, "Error: Calling callback for tuner %d\n", - core->board.tuner_type); + pr_err("Error: Calling callback for tuner %d\n", + core->board.tuner_type); return -EINVAL; } EXPORT_SYMBOL(cx88_tuner_callback); @@ -3268,25 +3259,19 @@ static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) if (0 == pci->subsystem_vendor && 0 == pci->subsystem_device) { - printk(KERN_ERR - "%s: Your board has no valid PCI Subsystem ID and thus can't\n" - "%s: be autodetected. Please pass card= insmod option to\n" - "%s: workaround that. Redirect complaints to the vendor of\n" - "%s: the TV card. Best regards,\n" - "%s: -- tux\n", - core->name,core->name,core->name,core->name,core->name); + pr_err("Your board has no valid PCI Subsystem ID and thus can't\n"); + pr_err("be autodetected. Please pass card= insmod option to\n"); + pr_err("workaround that. Redirect complaints to the vendor of\n"); + pr_err("the TV card\n"); } else { - printk(KERN_ERR - "%s: Your board isn't known (yet) to the driver. You can\n" - "%s: try to pick one of the existing card configs via\n" - "%s: card= insmod option. Updating to the latest\n" - "%s: version might help as well.\n", - core->name,core->name,core->name,core->name); + pr_err("Your board isn't known (yet) to the driver. You can\n"); + pr_err("try to pick one of the existing card configs via\n"); + pr_err("card= insmod option. Updating to the latest\n"); + pr_err("version might help as well.\n"); } - err_printk(core, "Here is a list of valid choices for the card= insmod option:\n"); + pr_err("Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) - printk(KERN_ERR "%s: card=%d -> %s\n", - core->name, i, cx88_boards[i].name); + pr_err(" card=%d -> %s\n", i, cx88_boards[i].name); } static void cx88_card_setup_pre_i2c(struct cx88_core *core) @@ -3508,8 +3493,8 @@ static void cx88_card_setup(struct cx88_core *core) for (i = 0; i < ARRAY_SIZE(buffer); i++) if (2 != i2c_master_send(&core->i2c_client, buffer[i],2)) - warn_printk(core, "Unable to enable tuner(%i).\n", - i); + pr_warn("Unable to enable tuner(%i).\n", + i); } break; case CX88_BOARD_MSI_TVANYWHERE_MASTER: @@ -3608,29 +3593,24 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) /* check pci quirks */ if (pci_pci_problems & PCIPCI_TRITON) { - printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n", - name); + pr_info("quirk: PCIPCI_TRITON -- set TBFX\n"); ctrl |= CX88X_EN_TBFX; } if (pci_pci_problems & PCIPCI_NATOMA) { - printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n", - name); + pr_info("quirk: PCIPCI_NATOMA -- set TBFX\n"); ctrl |= CX88X_EN_TBFX; } if (pci_pci_problems & PCIPCI_VIAETBF) { - printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n", - name); + pr_info("quirk: PCIPCI_VIAETBF -- set TBFX\n"); ctrl |= CX88X_EN_TBFX; } if (pci_pci_problems & PCIPCI_VSFX) { - printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n", - name); + pr_info("quirk: PCIPCI_VSFX -- set VSFX\n"); ctrl |= CX88X_EN_VSFX; } #ifdef PCIPCI_ALIMAGIK if (pci_pci_problems & PCIPCI_ALIMAGIK) { - printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", - name); + pr_info("quirk: PCIPCI_ALIMAGIK -- latency fixup\n"); lat = 0x0A; } #endif @@ -3646,8 +3626,8 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) pci_write_config_byte(pci, CX88X_DEVCTRL, value); } if (UNSET != lat) { - printk(KERN_INFO "%s: setting pci latency timer to %d\n", - name, latency); + pr_info("setting pci latency timer to %d\n", + latency); pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency); } return 0; @@ -3659,9 +3639,8 @@ int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci) pci_resource_len(pci,0), core->name)) return 0; - printk(KERN_ERR - "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n", - core->name, PCI_FUNC(pci->devfn), + pr_err("func %d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n", + PCI_FUNC(pci->devfn), (unsigned long long)pci_resource_start(pci, 0), pci->subsystem_vendor, pci->subsystem_device); return -EBUSY; @@ -3755,7 +3734,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) if (!core->board.num_frontends && (core->board.mpeg & CX88_MPEG_DVB)) core->board.num_frontends = 1; - info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n", + pr_info("subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n", pci->subsystem_vendor, pci->subsystem_device, core->board.name, core->boardnr, card[core->nr] == core->boardnr ? "insmod option" : "autodetected", diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 1ffd341f990d..27203e094655 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -25,6 +25,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" + #include #include #include @@ -38,7 +40,6 @@ #include #include -#include "cx88.h" #include #include @@ -60,10 +61,15 @@ static unsigned int nocomb; module_param(nocomb,int,0644); MODULE_PARM_DESC(nocomb,"disable comb filter"); -#define dprintk(level,fmt, arg...) do { \ - if (cx88_core_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, core->name , ## arg); \ - } while(0) +#define dprintk0(fmt, arg...) \ + printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \ + __func__, ##arg) \ + +#define dprintk(level, fmt, arg...) do { \ + if (cx88_core_debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \ + __func__, ##arg); \ +} while (0) static unsigned int cx88_devcount; static LIST_HEAD(cx88_devlist); @@ -363,7 +369,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, cx_write(ch->cnt1_reg, (bpl >> 3) -1); cx_write(ch->cnt2_reg, (lines*16) >> 3); - dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines); + dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines); return 0; } @@ -399,12 +405,12 @@ static int cx88_risc_decode(u32 risc) }; int i; - printk(KERN_DEBUG "0x%08x [ %s", risc, + dprintk0("0x%08x [ %s", risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); for (i = ARRAY_SIZE(bits)-1; i >= 0; i--) if (risc & (1 << (i + 12))) - printk(KERN_CONT " %s", bits[i]); - printk(KERN_CONT " count=%d ]\n", risc & 0xfff); + pr_cont(" %s", bits[i]); + pr_cont(" count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; } @@ -428,43 +434,39 @@ void cx88_sram_channel_dump(struct cx88_core *core, u32 risc; unsigned int i,j,n; - printk(KERN_DEBUG "%s: %s - dma channel status dump\n", - core->name,ch->name); + dprintk0("%s - dma channel status dump\n", + ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) - printk(KERN_DEBUG "%s: cmds: %-12s: 0x%08x\n", - core->name,name[i], - cx_read(ch->cmds_start + 4*i)); + dprintk0(" cmds: %-12s: 0x%08x\n", + name[i], + cx_read(ch->cmds_start + 4*i)); for (n = 1, i = 0; i < 4; i++) { risc = cx_read(ch->cmds_start + 4 * (i+11)); - printk(KERN_CONT "%s: risc%d: ", core->name, i); + pr_cont(" risc%d: ", i); if (--n) - printk(KERN_CONT "0x%08x [ arg #%d ]\n", risc, n); + pr_cont("0x%08x [ arg #%d ]\n", risc, n); else n = cx88_risc_decode(risc); } for (i = 0; i < 16; i += n) { risc = cx_read(ch->ctrl_start + 4 * i); - printk(KERN_DEBUG "%s: iq %x: ", core->name, i); + dprintk0(" iq %x: ", i); n = cx88_risc_decode(risc); for (j = 1; j < n; j++) { risc = cx_read(ch->ctrl_start + 4 * (i+j)); - printk(KERN_CONT "%s: iq %x: 0x%08x [ arg #%d ]\n", - core->name, i+j, risc, j); + pr_cont(" iq %x: 0x%08x [ arg #%d ]\n", + i + j, risc, j); } } - printk(KERN_DEBUG "%s: fifo: 0x%08x -> 0x%x\n", - core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk(KERN_DEBUG "%s: ctrl: 0x%08x -> 0x%x\n", - core->name, ch->ctrl_start, ch->ctrl_start+6*16); - printk(KERN_DEBUG "%s: ptr1_reg: 0x%08x\n", - core->name,cx_read(ch->ptr1_reg)); - printk(KERN_DEBUG "%s: ptr2_reg: 0x%08x\n", - core->name,cx_read(ch->ptr2_reg)); - printk(KERN_DEBUG "%s: cnt1_reg: 0x%08x\n", - core->name,cx_read(ch->cnt1_reg)); - printk(KERN_DEBUG "%s: cnt2_reg: 0x%08x\n", - core->name,cx_read(ch->cnt2_reg)); + dprintk0("fifo: 0x%08x -> 0x%x\n", + ch->fifo_start, ch->fifo_start+ch->fifo_size); + dprintk0("ctrl: 0x%08x -> 0x%x\n", + ch->ctrl_start, ch->ctrl_start + 6 * 16); + dprintk0(" ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg)); + dprintk0(" ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg)); + dprintk0(" cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg)); + dprintk0(" cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg)); } static const char *cx88_pci_irqs[32] = { @@ -474,24 +476,24 @@ static const char *cx88_pci_irqs[32] = { "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1" }; -void cx88_print_irqbits(const char *name, const char *tag, const char *strings[], +void cx88_print_irqbits(const char *tag, const char *strings[], int len, u32 bits, u32 mask) { unsigned int i; - printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits); + dprintk0("%s [0x%x]", tag, bits); for (i = 0; i < len; i++) { if (!(bits & (1 << i))) continue; if (strings[i]) - printk(KERN_CONT " %s", strings[i]); + pr_cont(" %s", strings[i]); else - printk(KERN_CONT " %d", i); + pr_cont(" %d", i); if (!(mask & (1 << i))) continue; - printk(KERN_CONT "*"); + pr_cont("*"); } - printk(KERN_CONT "\n"); + pr_cont("\n"); } /* ------------------------------------------------------------------ */ @@ -505,7 +507,7 @@ int cx88_core_irq(struct cx88_core *core, u32 status) handled++; } if (!handled) - cx88_print_irqbits(core->name, "irq pci", + cx88_print_irqbits("irq pci", cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs), status, core->pci_irqmask); return handled; @@ -551,7 +553,7 @@ void cx88_shutdown(struct cx88_core *core) int cx88_reset(struct cx88_core *core) { - dprintk(1,"%s\n",__func__); + dprintk(1, ""); cx88_shutdown(core); /* clear irq status */ @@ -663,7 +665,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig unsigned int sheight = norm_maxh(core->tvnorm); u32 value; - dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height, + dprintk(1, "set_scale: %dx%d [%s%s,%s]\n", width, height, V4L2_FIELD_HAS_TOP(field) ? "T" : "", V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "", v4l2_norm_to_name(core->tvnorm)); @@ -675,30 +677,30 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig value &= 0x3fe; cx_write(MO_HDELAY_EVEN, value); cx_write(MO_HDELAY_ODD, value); - dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth); + dprintk(1, "set_scale: hdelay 0x%04x (width %d)\n", value, swidth); value = (swidth * 4096 / width) - 4096; cx_write(MO_HSCALE_EVEN, value); cx_write(MO_HSCALE_ODD, value); - dprintk(1,"set_scale: hscale 0x%04x\n", value); + dprintk(1, "set_scale: hscale 0x%04x\n", value); cx_write(MO_HACTIVE_EVEN, width); cx_write(MO_HACTIVE_ODD, width); - dprintk(1,"set_scale: hactive 0x%04x\n", width); + dprintk(1, "set_scale: hactive 0x%04x\n", width); // recalc V scale Register (delay is constant) cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm)); cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm)); - dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm)); + dprintk(1, "set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm)); value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff; cx_write(MO_VSCALE_EVEN, value); cx_write(MO_VSCALE_ODD, value); - dprintk(1,"set_scale: vscale 0x%04x\n", value); + dprintk(1, "set_scale: vscale 0x%04x\n", value); cx_write(MO_VACTIVE_EVEN, sheight); cx_write(MO_VACTIVE_ODD, sheight); - dprintk(1,"set_scale: vactive 0x%04x\n", sheight); + dprintk(1, "set_scale: vactive 0x%04x\n", sheight); // setup filters value = 0; @@ -720,7 +722,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig cx_andor(MO_FILTER_EVEN, 0x7ffc7f, value); /* preserve PEAKEN, PSEL */ cx_andor(MO_FILTER_ODD, 0x7ffc7f, value); - dprintk(1,"set_scale: filter 0x%04x\n", value); + dprintk(1, "set_scale: filter 0x%04x\n", value); return 0; } @@ -743,11 +745,11 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) do_div(pll,xtal); reg = (pll & 0x3ffffff) | (pre[prescale] << 26); if (((reg >> 20) & 0x3f) < 14) { - printk("%s/0: pll out of range\n",core->name); + pr_err("pll out of range\n"); return -1; } - dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n", + dprintk(1, "set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n", reg, cx_read(MO_PLL_REG), ofreq); cx_write(MO_PLL_REG, reg); for (i = 0; i < 100; i++) { @@ -757,10 +759,10 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) prescale,ofreq); return 0; } - dprintk(1,"pll not locked yet, waiting ...\n"); + dprintk(1, "pll not locked yet, waiting ...\n"); msleep(10); } - dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq); + dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq); return -1; } @@ -836,8 +838,8 @@ static int set_tvaudio(struct cx88_core *core) core->tvaudio = WW_EIAJ; } else { - printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n", - core->name, v4l2_norm_to_name(core->tvnorm)); + pr_info("tvaudio support needs work for this tv norm [%s], sorry\n", + v4l2_norm_to_name(core->tvnorm)); core->tvaudio = WW_NONE; return 0; } @@ -912,12 +914,12 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) cxoformat = 0x181f0008; } - dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n", + dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n", v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock, step_db, step_dr); set_pll(core,2,vdec_clock); - dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", + dprintk(1, "set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f); /* Chroma AGC must be disabled if SECAM is used, we enable it by default on PAL and NTSC */ @@ -925,35 +927,36 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400); // FIXME: as-is from DScaler - dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n", + dprintk(1, "set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n", cxoformat, cx_read(MO_OUTPUT_FORMAT)); cx_write(MO_OUTPUT_FORMAT, cxoformat); // MO_SCONV_REG = adc clock / video dec clock * 2^17 tmp64 = adc_clock * (u64)(1 << 17); do_div(tmp64, vdec_clock); - dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n", + dprintk(1, "set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n", (u32)tmp64, cx_read(MO_SCONV_REG)); cx_write(MO_SCONV_REG, (u32)tmp64); // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22 tmp64 = step_db * (u64)(1 << 22); do_div(tmp64, vdec_clock); - dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n", + dprintk(1, "set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n", (u32)tmp64, cx_read(MO_SUB_STEP)); cx_write(MO_SUB_STEP, (u32)tmp64); // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22 tmp64 = step_dr * (u64)(1 << 22); do_div(tmp64, vdec_clock); - dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n", + dprintk(1, "set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n", (u32)tmp64, cx_read(MO_SUB_STEP_DR)); cx_write(MO_SUB_STEP_DR, (u32)tmp64); // bdelay + agcdelay bdelay = vdec_clock * 65 / 20000000 + 21; agcdelay = vdec_clock * 68 / 20000000 + 15; - dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n", + dprintk(1, + "set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n", (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay); cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay); @@ -961,7 +964,8 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) tmp64 = norm_htotal(norm) * (u64)vdec_clock; do_div(tmp64, fsc8); htotal = (u32)tmp64; - dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n", + dprintk(1, + "set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n", htotal, cx_read(MO_HTOTAL), (u32)tmp64); cx_andor(MO_HTOTAL, 0x07ff, htotal); diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 57380c750702..4f1ec8d13389 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -19,15 +19,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" +#include "cx88-reg.h" + #include #include #include #include #include -#include "cx88.h" -#include "cx88-reg.h" - #define INT_PI ((s32)(3.141592653589 * 32768.0)) #define compat_remainder(a, b) \ @@ -71,8 +71,11 @@ static unsigned int dsp_debug; module_param(dsp_debug, int, 0644); MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages"); -#define dprintk(level, fmt, arg...) if (dsp_debug >= level) \ - printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) +#define dprintk(level, fmt, arg...) do { \ + if (dsp_debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: dsp:" fmt), \ + __func__, ##arg); \ +} while (0) static s32 int_cos(u32 x) { @@ -176,8 +179,8 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) dual_freq = FREQ_EIAJ_DUAL; break; default: - printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n", - core->name, core->tvaudio, __func__); + pr_warn("unsupported audio mode %d for %s\n", + core->tvaudio, __func__); return UNSET; } diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 157bc14874eb..378135ddb6fb 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -21,6 +21,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" +#include "dvb-pll.h" + #include #include #include @@ -29,8 +32,6 @@ #include #include -#include "cx88.h" -#include "dvb-pll.h" #include #include "mt352.h" @@ -77,8 +78,11 @@ MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk(level,fmt, arg...) if (debug >= level) \ - printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: dvb:" fmt), \ + __func__, ##arg); \ +} while (0) /* ------------------------------------------------------------------ */ @@ -178,7 +182,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) fe_id = vb2_dvb_find_frontend(&dev->frontends, fe); if (!fe_id) { - printk(KERN_ERR "%s() No frontend found\n", __func__); + pr_err("%s() No frontend found\n", __func__); return -EINVAL; } @@ -625,8 +629,7 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) return -EINVAL; if (!fe0->dvb.frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. Can't attach xc3028\n", - dev->core->name); + pr_err("dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } @@ -639,16 +642,14 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc3028 attach failed\n", - dev->core->name); + pr_err("xc3028 attach failed\n"); dvb_frontend_detach(fe0->dvb.frontend); dvb_unregister_frontend(fe0->dvb.frontend); fe0->dvb.frontend = NULL; return -EINVAL; } - printk(KERN_INFO "%s/2: xc3028 attached\n", - dev->core->name); + pr_info("xc3028 attached\n"); return 0; } @@ -664,23 +665,21 @@ static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) return -EINVAL; if (!fe0->dvb.frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. Can't attach xc4000\n", - dev->core->name); + pr_err("dvb frontend not attached. Can't attach xc4000\n"); return -EINVAL; } fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap, cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc4000 attach failed\n", - dev->core->name); + pr_err("xc4000 attach failed\n"); dvb_frontend_detach(fe0->dvb.frontend); dvb_unregister_frontend(fe0->dvb.frontend); fe0->dvb.frontend = NULL; return -EINVAL; } - printk(KERN_INFO "%s/2: xc4000 attached\n", dev->core->name); + pr_info("xc4000 attached\n"); return 0; } @@ -798,12 +797,12 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev) if (!core->board.num_frontends) return -ENODEV; - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, - core->board.num_frontends); + pr_info("%s: allocating %d frontend(s)\n", __func__, + core->board.num_frontends); for (i = 1; i <= core->board.num_frontends; i++) { fe = vb2_dvb_alloc_frontend(&dev->frontends, i); if (!fe) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); + pr_err("%s() failed to alloc\n", __func__); vb2_dvb_dealloc_frontends(&dev->frontends); return -ENOMEM; } @@ -1007,7 +1006,7 @@ static int dvb_register(struct cx8802_dev *dev) int res = -EINVAL; if (0 != core->i2c_rc) { - printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); + pr_err("no i2c-bus available, cannot attach dvb drivers\n"); goto frontend_detach; } @@ -1182,8 +1181,7 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; } #else - printk(KERN_ERR "%s/2: built without vp3054 support\n", - core->name); + pr_err("built without vp3054 support\n"); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: @@ -1615,15 +1613,12 @@ static int dvb_register(struct cx8802_dev *dev) break; default: - printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", - core->name); + pr_err("The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { - printk(KERN_ERR - "%s/2: frontend initialization failed\n", - core->name); + pr_err("frontend initialization failed\n"); goto frontend_detach; } /* define general-purpose callback pointer */ @@ -1762,7 +1757,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) goto fail_core; /* dvb stuff */ - printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); + pr_info("cx2388x based DVB/ATSC card\n"); dev->ts_gen_cntrl = 0x0c; err = cx8802_alloc_frontends(dev); @@ -1774,8 +1769,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) fe = vb2_dvb_get_frontend(&core->dvbdev->frontends, i); if (fe == NULL) { - printk(KERN_ERR "%s() failed to get frontend(%d)\n", - __func__, i); + pr_err("%s() failed to get frontend(%d)\n", + __func__, i); err = -ENODEV; goto fail_probe; } @@ -1803,8 +1798,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) err = dvb_register(dev); if (err) /* frontends/adapter de-allocated in dvb_register */ - printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", - core->name, err); + pr_err("dvb_register failed (err = %d)\n", err); return err; fail_probe: vb2_dvb_dealloc_frontends(&core->dvbdev->frontends); @@ -1839,8 +1833,7 @@ static struct cx8802_driver cx8802_dvb_driver = { static int __init dvb_init(void) { - printk(KERN_INFO "cx88/2: cx2388x dvb driver version %s loaded\n", - CX88_VERSION); + pr_info("cx2388x dvb driver version %s loaded\n", CX88_VERSION); return cx8802_register_driver(&cx8802_dvb_driver); } diff --git a/drivers/media/pci/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c index 804f7417d19f..831f8db5150e 100644 --- a/drivers/media/pci/cx88/cx88-i2c.c +++ b/drivers/media/pci/cx88/cx88-i2c.c @@ -27,12 +27,13 @@ */ +#include "cx88.h" + #include #include #include -#include "cx88.h" #include static unsigned int i2c_debug; @@ -47,8 +48,11 @@ static unsigned int i2c_udelay = 5; module_param(i2c_udelay, int, 0644); MODULE_PARM_DESC(i2c_udelay, "i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); -#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, core->name , ## arg) +#define dprintk(level, fmt, arg...) do { \ + if (i2c_debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: i2c:" fmt), \ + __func__, ##arg); \ +} while (0) /* ----------------------------------------------------------------------- */ @@ -126,8 +130,8 @@ static void do_i2c_scan(const char *name, struct i2c_client *c) rc = i2c_master_recv(c,&buf,0); if (rc < 0) continue; - printk("%s: i2c scan: found device @ 0x%x [%s]\n", - name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + pr_info("i2c scan: found device @ 0x%x [%s]\n", + i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } } @@ -166,8 +170,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_HVR1300: case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: - printk("%s: i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n", - core->name); + pr_info("i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n"); i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1); break; default: @@ -176,7 +179,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) if (i2c_scan) do_i2c_scan(core->name,&core->i2c_client); } else - printk("%s: i2c register FAILED\n", core->name); + pr_err("i2c register FAILED\n"); return core->i2c_rc; } diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index cd7687183381..3a05629ba6e4 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -22,13 +22,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "cx88.h" + #include #include #include #include #include -#include "cx88.h" #include #define MODULE_NAME "cx88xx" diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 86b46b62d985..ed3fcc8149bd 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -22,6 +22,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" + #include #include #include @@ -30,8 +32,6 @@ #include #include -#include "cx88.h" - /* ------------------------------------------------------------------ */ MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); @@ -45,15 +45,11 @@ static unsigned int debug; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); -#define dprintk(level, fmt, arg...) do { \ - if (debug + 1 > level) \ - printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg); \ -} while(0) - -#define mpeg_dbg(level, fmt, arg...) do { \ - if (debug + 1 > level) \ - printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg); \ -} while(0) +#define dprintk(level, fmt, arg...) do { \ + if (debug + 1 > level) \ + printk(KERN_DEBUG pr_fmt("%s: mpeg:" fmt), \ + __func__, ##arg); \ +} while (0) #if defined(CONFIG_MODULES) && defined(MODULE) static void request_module_async(struct work_struct *work) @@ -92,7 +88,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, { struct cx88_core *core = dev->core; - dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", + dprintk(1, "w: %d, h: %d, f: %d\n", core->width, core->height, core->field); /* setup fifo + format */ @@ -105,12 +101,12 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* FIXME: this needs a review. * also: move to cx88-blackbird + cx88-dvb source files? */ - dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id); + dprintk(1, "core->active_type_id = 0x%08x\n", core->active_type_id); if ( (core->active_type_id == CX88_MPEG_DVB) && (core->board.mpeg & CX88_MPEG_DVB) ) { - dprintk( 1, "cx8802_start_dma doing .dvb\n"); + dprintk(1, "cx8802_start_dma doing .dvb\n"); /* negedge driven & software reset */ cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl); udelay(100); @@ -154,7 +150,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, udelay(100); } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) && (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) { - dprintk( 1, "cx8802_start_dma doing .blackbird\n"); + dprintk(1, "cx8802_start_dma doing .blackbird\n"); cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ @@ -166,8 +162,8 @@ int cx8802_start_dma(struct cx8802_dev *dev, cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ udelay(100); } else { - printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __func__, - core->board.mpeg ); + pr_err("%s() Failed. Unsupported value in .mpeg (0x%08x)\n", + __func__, core->board.mpeg); return -EINVAL; } @@ -176,7 +172,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, q->count = 0; /* enable irqs */ - dprintk( 1, "setting the interrupt mask\n" ); + dprintk(1, "setting the interrupt mask\n"); cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT); cx_set(MO_TS_INTMSK, 0x1f0011); @@ -189,7 +185,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, static int cx8802_stop_dma(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - dprintk( 1, "cx8802_stop_dma\n" ); + dprintk(1, "\n"); /* stop dma */ cx_clear(MO_TS_DMACNTRL, 0x11); @@ -208,7 +204,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, { struct cx88_buffer *buf; - dprintk( 1, "cx8802_restart_queue\n" ); + dprintk(1, "\n"); if (list_empty(&q->active)) return 0; @@ -249,25 +245,25 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) struct cx88_buffer *prev; struct cx88_dmaqueue *cx88q = &dev->mpegq; - dprintk( 1, "cx8802_buf_queue\n" ); + dprintk(1, "\n"); /* add jump to start */ buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); if (list_empty(&cx88q->active)) { - dprintk( 1, "queue is empty - first active\n" ); + dprintk(1, "queue is empty - first active\n"); list_add_tail(&buf->list, &cx88q->active); dprintk(1,"[%p/%d] %s - first active\n", buf, buf->vb.vb2_buf.index, __func__); } else { buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); - dprintk( 1, "queue is not empty - append to active\n" ); + dprintk(1, "queue is not empty - append to active\n"); prev = list_entry(cx88q->active.prev, struct cx88_buffer, list); list_add_tail(&buf->list, &cx88q->active); prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk( 1, "[%p/%d] %s - append to active\n", + dprintk(1, "[%p/%d] %s - append to active\n", buf, buf->vb.vb2_buf.index, __func__); } } @@ -291,7 +287,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev) void cx8802_cancel_buffers(struct cx8802_dev *dev) { - dprintk( 1, "cx8802_cancel_buffers" ); + dprintk(1, "\n"); cx8802_stop_dma(dev); do_cancel_buffers(dev); } @@ -310,7 +306,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) struct cx88_core *core = dev->core; u32 status, mask, count; - dprintk( 1, "cx8802_mpeg_irq\n" ); + dprintk(1, "\n"); status = cx_read(MO_TS_INTSTAT); mask = cx_read(MO_TS_INTMSK); if (0 == (status & mask)) @@ -319,20 +315,20 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) cx_write(MO_TS_INTSTAT, status); if (debug || (status & mask & ~0xff)) - cx88_print_irqbits(core->name, "irq mpeg ", + cx88_print_irqbits("irq mpeg ", cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs), status, mask); /* risc op code error */ if (status & (1 << 16)) { - printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name); + pr_warn("mpeg risc op code error\n"); cx_clear(MO_TS_DMACNTRL, 0x11); cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); } /* risc1 y */ if (status & 0x01) { - dprintk( 1, "wake up\n" ); + dprintk(1, "wake up\n"); spin_lock(&dev->slock); count = cx_read(MO_TS_GPCNT); cx88_wakeup(dev->core, &dev->mpegq, count); @@ -341,7 +337,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) /* other general errors */ if (status & 0x1f0100) { - dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); + dprintk(0, "general errors: 0x%08x\n", status & 0x1f0100); spin_lock(&dev->slock); cx8802_stop_dma(dev); spin_unlock(&dev->slock); @@ -362,9 +358,9 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id) (core->pci_irqmask | PCI_INT_TSINT); if (0 == status) goto out; - dprintk( 1, "cx8802_irq\n" ); - dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP ); - dprintk( 1, " status: %d\n", status ); + dprintk(1, "cx8802_irq\n"); + dprintk(1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP); + dprintk(1, " status: %d\n", status); handled = 1; cx_write(MO_PCI_INTSTAT, status); @@ -374,9 +370,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id) cx8802_mpeg_irq(dev); } if (MAX_IRQ_LOOP == loop) { - dprintk( 0, "clearing mask\n" ); - printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", - core->name); + dprintk(0, "clearing mask\n"); + pr_warn("irq loop -- clearing mask\n"); cx_write(MO_PCI_INTMSK,0); } @@ -395,16 +390,16 @@ static int cx8802_init_common(struct cx8802_dev *dev) pci_set_master(dev->pci); err = pci_set_dma_mask(dev->pci,DMA_BIT_MASK(32)); if (err) { - printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name); + pr_err("Oops: no 32bit PCI DMA ???\n"); return -EIO; } dev->pci_rev = dev->pci->revision; pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", - dev->core->name, - pci_name(dev->pci), dev->pci_rev, dev->pci->irq, - dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0)); + pr_info("found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + pci_name(dev->pci), dev->pci_rev, dev->pci->irq, + dev->pci_lat, + (unsigned long long)pci_resource_start(dev->pci, 0)); /* initialize driver struct */ spin_lock_init(&dev->slock); @@ -416,8 +411,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) err = request_irq(dev->pci->irq, cx8802_irq, IRQF_SHARED, dev->core->name, dev); if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", - dev->core->name, dev->pci->irq); + pr_err("can't get IRQ %d\n", dev->pci->irq); return err; } cx_set(MO_PCI_INTMSK, core->pci_irqmask); @@ -429,7 +423,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) static void cx8802_fini_common(struct cx8802_dev *dev) { - dprintk( 2, "cx8802_fini_common\n" ); + dprintk(2, "\n"); cx8802_stop_dma(dev); pci_disable_device(dev->pci); @@ -442,14 +436,13 @@ static void cx8802_fini_common(struct cx8802_dev *dev) static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); - struct cx88_core *core = dev->core; unsigned long flags; /* stop mpeg dma */ spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->mpegq.active)) { - dprintk( 2, "suspend\n" ); - printk("%s: suspend mpeg\n", core->name); + dprintk(2, "suspend\n"); + pr_info("suspend mpeg\n"); cx8802_stop_dma(dev); } spin_unlock_irqrestore(&dev->slock, flags); @@ -468,23 +461,20 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) static int cx8802_resume_common(struct pci_dev *pci_dev) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); - struct cx88_core *core = dev->core; unsigned long flags; int err; if (dev->state.disabled) { err=pci_enable_device(pci_dev); if (err) { - printk(KERN_ERR "%s: can't enable device\n", - dev->core->name); + pr_err("can't enable device\n"); return err; } dev->state.disabled = 0; } err=pci_set_power_state(pci_dev, PCI_D0); if (err) { - printk(KERN_ERR "%s: can't enable device\n", - dev->core->name); + pr_err("can't enable device\n"); pci_disable_device(pci_dev); dev->state.disabled = 1; @@ -498,7 +488,7 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) /* restart video+vbi capture */ spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->mpegq.active)) { - printk("%s: resume mpeg\n", core->name); + pr_info("resume mpeg\n"); cx8802_restart_queue(dev,&dev->mpegq); } spin_unlock_irqrestore(&dev->slock, flags); @@ -550,7 +540,7 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) drv->advise_acquire(drv); } - mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); + dprintk(1, "Post acquire GPIO=%x\n", cx_read(MO_GP0_IO)); } return 0; @@ -571,7 +561,7 @@ static int cx8802_request_release(struct cx8802_driver *drv) drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; - mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); + dprintk(1, "Post release GPIO=%x\n", cx_read(MO_GP0_IO)); } return 0; @@ -605,24 +595,22 @@ int cx8802_register_driver(struct cx8802_driver *drv) struct cx8802_driver *driver; int err, i = 0; - printk(KERN_INFO - "cx88/2: registering cx8802 driver, type: %s access: %s\n", - drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", - drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); + pr_info("registering cx8802 driver, type: %s access: %s\n", + drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", + drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); if ((err = cx8802_check_driver(drv)) != 0) { - printk(KERN_ERR "cx88/2: cx8802_driver is invalid\n"); + pr_err("cx8802_driver is invalid\n"); return err; } mutex_lock(&cx8802_mutex); list_for_each_entry(dev, &cx8802_devlist, devlist) { - printk(KERN_INFO - "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", - dev->core->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, dev->core->board.name, - dev->core->boardnr); + pr_info("subsystem: %04x:%04x, board: %s [card=%d]\n", + dev->pci->subsystem_vendor, + dev->pci->subsystem_device, dev->core->board.name, + dev->core->boardnr); /* Bring up a new struct for each driver instance */ driver = kzalloc(sizeof(*drv),GFP_KERNEL); @@ -645,9 +633,7 @@ int cx8802_register_driver(struct cx8802_driver *drv) i++; list_add_tail(&driver->drvlist, &dev->drvlist); } else { - printk(KERN_ERR - "%s/2: cx8802 probe failed, err = %d\n", - dev->core->name, err); + pr_err("cx8802 probe failed, err = %d\n", err); } mutex_unlock(&drv->core->lock); } @@ -664,19 +650,17 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) struct cx8802_driver *d, *dtmp; int err = 0; - printk(KERN_INFO - "cx88/2: unregistering cx8802 driver, type: %s access: %s\n", - drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", - drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); + pr_info("unregistering cx8802 driver, type: %s access: %s\n", + drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", + drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); mutex_lock(&cx8802_mutex); list_for_each_entry(dev, &cx8802_devlist, devlist) { - printk(KERN_INFO - "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", - dev->core->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, dev->core->board.name, - dev->core->boardnr); + pr_info("subsystem: %04x:%04x, board: %s [card=%d]\n", + dev->pci->subsystem_vendor, + dev->pci->subsystem_device, dev->core->board.name, + dev->core->boardnr); mutex_lock(&dev->core->lock); @@ -690,8 +674,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) list_del(&d->drvlist); kfree(d); } else - printk(KERN_ERR "%s/2: cx8802 driver remove failed (%d)\n", - dev->core->name, err); + pr_err("cx8802 driver remove failed (%d)\n", + err); } mutex_unlock(&dev->core->lock); @@ -715,7 +699,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, if (NULL == core) return -EINVAL; - printk("%s/2: cx2388x 8802 Driver Manager\n", core->name); + pr_info("cx2388x 8802 Driver Manager\n"); err = -ENODEV; if (!core->board.mpeg) @@ -758,7 +742,7 @@ static void cx8802_remove(struct pci_dev *pci_dev) dev = pci_get_drvdata(pci_dev); - dprintk( 1, "%s\n", __func__); + dprintk(1, "%s\n", __func__); flush_request_modules(dev); @@ -768,16 +752,15 @@ static void cx8802_remove(struct pci_dev *pci_dev) struct cx8802_driver *drv, *tmp; int err; - printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver while cx8802 sub-drivers still loaded?!\n", - dev->core->name); + pr_warn("Trying to remove cx8802 driver while cx8802 sub-drivers still loaded?!\n"); list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { err = drv->remove(drv); if (err == 0) { list_del(&drv->drvlist); } else - printk(KERN_ERR "%s/2: cx8802 driver remove failed (%d)\n", - dev->core->name, err); + pr_err("cx8802 driver remove failed (%d)\n", + err); kfree(drv); } } diff --git a/drivers/media/pci/cx88/cx88-tvaudio.c b/drivers/media/pci/cx88/cx88-tvaudio.c index dd8e6f324204..b1d8680235e6 100644 --- a/drivers/media/pci/cx88/cx88-tvaudio.c +++ b/drivers/media/pci/cx88/cx88-tvaudio.c @@ -35,6 +35,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" + #include #include #include @@ -50,8 +52,6 @@ #include #include -#include "cx88.h" - static unsigned int audio_debug; module_param(audio_debug, int, 0644); MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]"); @@ -64,9 +64,11 @@ static unsigned int radio_deemphasis; module_param(radio_deemphasis,int,0644); MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, 0=None, 1=50us (elsewhere), 2=75us (USA)"); -#define dprintk(fmt, arg...) if (audio_debug) \ - printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) - +#define dprintk(fmt, arg...) do { \ + if (audio_debug) \ + printk(KERN_DEBUG pr_fmt("%s: tvaudio:" fmt), \ + __func__, ##arg); \ +} while (0) /* ----------------------------------------------------------- */ static const char * const aud_ctl_names[64] = { @@ -797,8 +799,7 @@ void cx88_set_tvaudio(struct cx88_core *core) break; case WW_NONE: case WW_I2SPT: - printk("%s/0: unknown tv audio mode [%d]\n", - core->name, core->tvaudio); + pr_info("unknown tv audio mode [%d]\n", core->tvaudio); break; } return; diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index d3237cf8ffa3..227f0f66e015 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -1,17 +1,21 @@ /* */ + +#include "cx88.h" + #include #include #include -#include "cx88.h" - static unsigned int vbi_debug; module_param(vbi_debug,int,0644); MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); -#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg) +#define dprintk(level, fmt, arg...) do { \ + if (vbi_debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: vbi:" fmt), \ + __func__, ##arg); \ +} while (0) /* ------------------------------------------------------------------ */ diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 418e2db40b39..3d349dfb23ff 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -25,6 +25,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx88.h" + #include #include #include @@ -37,7 +39,6 @@ #include #include -#include "cx88.h" #include #include #include @@ -70,8 +71,12 @@ static unsigned int irq_debug; module_param(irq_debug,int,0644); MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); -#define dprintk(level,fmt, arg...) if (video_debug >= level) \ - printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) +#define dprintk(level, fmt, arg...) do { \ + if (video_debug >= level) \ + printk(KERN_DEBUG pr_fmt("%s: video:" fmt), \ + __func__, ##arg); \ +} while (0) + /* ------------------------------------------------------------------- */ /* static data */ @@ -414,7 +419,6 @@ static int stop_video_dma(struct cx8800_dev *dev) static int restart_video_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q) { - struct cx88_core *core = dev->core; struct cx88_buffer *buf; if (!list_empty(&q->active)) { @@ -513,7 +517,6 @@ static void buffer_queue(struct vb2_buffer *vb) struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb); struct cx88_buffer *prev; - struct cx88_core *core = dev->core; struct cx88_dmaqueue *q = &dev->vidq; /* add jump to start */ @@ -1090,13 +1093,13 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) return; cx_write(MO_VID_INTSTAT, status); if (irq_debug || (status & mask & ~0xff)) - cx88_print_irqbits(core->name, "irq vid", + cx88_print_irqbits("irq vid", cx88_vid_irqs, ARRAY_SIZE(cx88_vid_irqs), status, mask); /* risc op code error */ if (status & (1 << 16)) { - printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); + pr_warn("video risc op code error\n"); cx_clear(MO_VID_DMACNTRL, 0x11); cx_clear(VID_CAPTURE_CONTROL, 0x06); cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); @@ -1140,8 +1143,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) cx8800_vid_irq(dev); } if (10 == loop) { - printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", - core->name); + pr_warn("irq loop -- clearing mask\n"); cx_write(MO_PCI_INTMSK,0); } @@ -1307,15 +1309,15 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", - core->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); + pr_info("found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + pci_name(pci_dev), dev->pci_rev, pci_dev->irq, + dev->pci_lat, + (unsigned long long)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); err = pci_set_dma_mask(pci_dev,DMA_BIT_MASK(32)); if (err) { - printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name); + pr_err("Oops: no 32bit PCI DMA ???\n"); goto fail_core; } @@ -1332,8 +1334,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, err = request_irq(pci_dev->irq, cx8800_irq, IRQF_SHARED, core->name, dev); if (err < 0) { - printk(KERN_ERR "%s/0: can't get IRQ %d\n", - core->name,pci_dev->irq); + pr_err("can't get IRQ %d\n", pci_dev->irq); goto fail_core; } cx_set(MO_PCI_INTMSK, core->pci_irqmask); @@ -1470,12 +1471,11 @@ static int cx8800_initdev(struct pci_dev *pci_dev, err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, video_nr[core->nr]); if (err < 0) { - printk(KERN_ERR "%s/0: can't register video device\n", - core->name); + pr_err("can't register video device\n"); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", - core->name, video_device_node_name(&dev->video_dev)); + pr_info("registered device %s [v4l2]\n", + video_device_node_name(&dev->video_dev)); cx88_vdev_init(core, dev->pci, &dev->vbi_dev, &cx8800_vbi_template, "vbi"); @@ -1484,12 +1484,11 @@ static int cx8800_initdev(struct pci_dev *pci_dev, err = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[core->nr]); if (err < 0) { - printk(KERN_ERR "%s/0: can't register vbi device\n", - core->name); + pr_err("can't register vbi device\n"); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device %s\n", - core->name, video_device_node_name(&dev->vbi_dev)); + pr_info("registered device %s\n", + video_device_node_name(&dev->vbi_dev)); if (core->board.radio.type == CX88_RADIO) { cx88_vdev_init(core, dev->pci, &dev->radio_dev, @@ -1499,12 +1498,11 @@ static int cx8800_initdev(struct pci_dev *pci_dev, err = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, radio_nr[core->nr]); if (err < 0) { - printk(KERN_ERR "%s/0: can't register radio device\n", - core->name); + pr_err("can't register radio device\n"); goto fail_unreg; } - printk(KERN_INFO "%s/0: registered device %s\n", - core->name, video_device_node_name(&dev->radio_dev)); + pr_info("registered device %s\n", + video_device_node_name(&dev->radio_dev)); } /* start tvaudio thread */ @@ -1512,8 +1510,8 @@ static int cx8800_initdev(struct pci_dev *pci_dev, core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); if (IS_ERR(core->kthread)) { err = PTR_ERR(core->kthread); - printk(KERN_ERR "%s/0: failed to create cx88 audio thread, err=%d\n", - core->name, err); + pr_err("failed to create cx88 audio thread, err=%d\n", + err); } } mutex_unlock(&core->lock); @@ -1571,11 +1569,11 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) /* stop video+vbi capture */ spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->vidq.active)) { - printk("%s/0: suspend video\n", core->name); + pr_info("suspend video\n"); stop_video_dma(dev); } if (!list_empty(&dev->vbiq.active)) { - printk("%s/0: suspend vbi\n", core->name); + pr_info("suspend vbi\n"); cx8800_stop_vbi_dma(dev); } spin_unlock_irqrestore(&dev->slock, flags); @@ -1603,8 +1601,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) if (dev->state.disabled) { err=pci_enable_device(pci_dev); if (err) { - printk(KERN_ERR "%s/0: can't enable device\n", - core->name); + pr_err("can't enable device\n"); return err; } @@ -1612,7 +1609,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) } err= pci_set_power_state(pci_dev, PCI_D0); if (err) { - printk(KERN_ERR "%s/0: can't set power state\n", core->name); + pr_err("can't set power state\n"); pci_disable_device(pci_dev); dev->state.disabled = 1; @@ -1630,11 +1627,11 @@ static int cx8800_resume(struct pci_dev *pci_dev) /* restart video+vbi capture */ spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->vidq.active)) { - printk("%s/0: resume video\n", core->name); + pr_info("resume video\n"); restart_video_queue(dev,&dev->vidq); } if (!list_empty(&dev->vbiq.active)) { - printk("%s/0: resume vbi\n", core->name); + pr_info("resume vbi\n"); cx8800_restart_vbi_queue(dev,&dev->vbiq); } spin_unlock_irqrestore(&dev->slock, flags); diff --git a/drivers/media/pci/cx88/cx88-vp3054-i2c.c b/drivers/media/pci/cx88/cx88-vp3054-i2c.c index deede6e25d94..4f47ea2ae344 100644 --- a/drivers/media/pci/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.c @@ -22,15 +22,15 @@ */ +#include "cx88.h" +#include "cx88-vp3054-i2c.h" + #include #include #include #include -#include "cx88.h" -#include "cx88-vp3054-i2c.h" - MODULE_DESCRIPTION("driver for cx2388x VP3054 design"); MODULE_AUTHOR("Chris Pascoe "); MODULE_LICENSE("GPL"); @@ -133,7 +133,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) rc = i2c_bit_add_bus(&vp3054_i2c->adap); if (0 != rc) { - printk("%s: vp3054_i2c register FAILED\n", core->name); + pr_err("vp3054_i2c register FAILED\n"); kfree(dev->vp3054); dev->vp3054 = NULL; diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index ecd4b7bece99..01c1287baf93 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -19,6 +19,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef CX88_H +#define CX88_H + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -614,7 +619,7 @@ struct cx8802_dev { extern unsigned int cx88_core_debug; -extern void cx88_print_irqbits(const char *name, const char *tag, const char *strings[], +extern void cx88_print_irqbits(const char *tag, const char *strings[], int len, u32 bits, u32 mask); extern int cx88_core_irq(struct cx88_core *core, u32 status); @@ -738,3 +743,5 @@ int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f); int cx88_video_mux(struct cx88_core *core, unsigned int input); void cx88_querycap(struct file *file, struct cx88_core *core, struct v4l2_capability *cap); + +#endif -- cgit v1.2.3 From 7b61ba8ff838dbee422d428fbd882ab83db4b2d9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 06:59:49 -0200 Subject: [media] cx88: make checkpatch happier This driver is old, and have lots of checkpatch violations. As we're touching a lot on this driver due to the printk conversions, let's run checkpatch --fix on it, in order to solve some of those issues. Also, do a few manual adjustments: - remove the FSF address and use the usual coding style for the initial comments; - use WARN_ON() instead of BUG_ON(); - remove an unused typedef; - break a few long lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 79 +++++++------ drivers/media/pci/cx88/cx88-blackbird.c | 94 +++++++-------- drivers/media/pci/cx88/cx88-cards.c | 85 +++++++------- drivers/media/pci/cx88/cx88-core.c | 121 +++++++++---------- drivers/media/pci/cx88/cx88-dsp.c | 11 +- drivers/media/pci/cx88/cx88-dvb.c | 112 +++++++++--------- drivers/media/pci/cx88/cx88-i2c.c | 95 ++++++++------- drivers/media/pci/cx88/cx88-input.c | 18 ++- drivers/media/pci/cx88/cx88-mpeg.c | 63 +++++----- drivers/media/pci/cx88/cx88-reg.h | 13 +-- drivers/media/pci/cx88/cx88-tvaudio.c | 87 +++++++------- drivers/media/pci/cx88/cx88-vbi.c | 20 ++-- drivers/media/pci/cx88/cx88-video.c | 195 +++++++++++++++---------------- drivers/media/pci/cx88/cx88-vp3054-i2c.c | 44 +++---- drivers/media/pci/cx88/cx88.h | 37 +++--- 15 files changed, 515 insertions(+), 559 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index d2f1880a157e..56770e84b3d5 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -1,5 +1,4 @@ /* - * * Support for audio capture * PCI function #1 of the cx2388x. * @@ -18,10 +17,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -118,8 +113,8 @@ MODULE_VERSION(CX88_VERSION); MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}"); static unsigned int debug; -module_param(debug,int,0644); -MODULE_PARM_DESC(debug,"enable debug messages"); +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages"); /**************************************************************************** Module specific funtions @@ -132,7 +127,7 @@ MODULE_PARM_DESC(debug,"enable debug messages"); static int _cx88_start_audio_dma(snd_cx88_card_t *chip) { struct cx88_audio_buffer *buf = chip->buf; - struct cx88_core *core=chip->core; + struct cx88_core *core = chip->core; const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ @@ -177,7 +172,8 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) */ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) { - struct cx88_core *core=chip->core; + struct cx88_core *core = chip->core; + dprintk(1, "Stopping audio DMA\n"); /* stop dma */ @@ -261,7 +257,7 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id) for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | PCI_INT_AUDINT); - if (0 == status) + if (status == 0) goto out; dprintk(3, "cx8801_irq loop %d/%d, status %x\n", loop, MAX_IRQ_LOOP, status); @@ -274,7 +270,7 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id) cx8801_aud_irq(chip); } - if (MAX_IRQ_LOOP == loop) { + if (loop == MAX_IRQ_LOOP) { pr_err("IRQ loop detected, disabling interrupts\n"); cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT); } @@ -290,7 +286,7 @@ static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) int i; buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); - if (NULL == buf->vaddr) { + if (buf->vaddr == NULL) { dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); return -ENOMEM; } @@ -303,13 +299,13 @@ static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) buf->nr_pages = nr_pages; buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); - if (NULL == buf->sglist) + if (buf->sglist == NULL) goto vzalloc_err; sg_init_table(buf->sglist, buf->nr_pages); for (i = 0; i < buf->nr_pages; i++) { pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); - if (NULL == pg) + if (pg == NULL) goto vmalloc_to_page_err; sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); } @@ -331,7 +327,7 @@ static int cx88_alsa_dma_map(struct cx88_audio_dev *dev) buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); - if (0 == buf->sglen) { + if (buf->sglen == 0) { pr_warn("%s: cx88_alsa_map_sg failed\n", __func__); return -ENOMEM; } @@ -366,7 +362,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) BUG_ON(!chip->dma_size); - dprintk(2,"Freeing buffer\n"); + dprintk(2, "Freeing buffer\n"); cx88_alsa_dma_unmap(chip); cx88_alsa_dma_free(chip->buf); if (risc->cpu) @@ -431,6 +427,7 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) { unsigned int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4; + bpl &= ~7; /* must be multiple of 8 */ runtime->hw.period_bytes_min = bpl; runtime->hw.period_bytes_max = bpl; @@ -438,7 +435,7 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) return 0; _error: - dprintk(1,"Error opening PCM!\n"); + dprintk(1, "Error opening PCM!\n"); return err; } @@ -453,8 +450,8 @@ static int snd_cx88_close(struct snd_pcm_substream *substream) /* * hw_params callback */ -static int snd_cx88_hw_params(struct snd_pcm_substream * substream, - struct snd_pcm_hw_params * hw_params) +static int snd_cx88_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); @@ -474,7 +471,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, BUG_ON(chip->num_periods & (chip->num_periods-1)); buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (NULL == buf) + if (buf == NULL) return -ENOMEM; chip->buf = buf; @@ -511,7 +508,7 @@ error: /* * hw free callback */ -static int snd_cx88_hw_free(struct snd_pcm_substream * substream) +static int snd_cx88_hw_free(struct snd_pcm_substream *substream) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); @@ -545,13 +542,13 @@ static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: - err=_cx88_start_audio_dma(chip); + err = _cx88_start_audio_dma(chip); break; case SNDRV_PCM_TRIGGER_STOP: - err=_cx88_stop_audio_dma(chip); + err = _cx88_stop_audio_dma(chip); break; default: - err=-EINVAL; + err = -EINVAL; break; } @@ -584,6 +581,7 @@ static struct page *snd_cx88_page(struct snd_pcm_substream *substream, unsigned long offset) { void *pageptr = substream->runtime->dma_area + offset; + return vmalloc_to_page(pageptr); } @@ -638,7 +636,7 @@ static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core=chip->core; + struct cx88_core *core = chip->core; int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f), bal = cx_read(AUD_BAL_CTL); @@ -675,7 +673,7 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core=chip->core; + struct cx88_core *core = chip->core; int left, right, v, b; int changed = 0; u32 old; @@ -814,8 +812,8 @@ static struct snd_kcontrol_new snd_cx88_alc_switch = { */ static const struct pci_device_id cx88_audio_pci_tbl[] = { - {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, - {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, + {0x14f1, 0x8801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x14f1, 0x8811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0, } }; MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl); @@ -830,7 +828,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip) if (chip->irq >= 0) free_irq(chip->irq, chip); - cx88_core_put(chip->core,chip->pci); + cx88_core_put(chip->core, chip->pci); pci_disable_device(chip->pci); return 0; @@ -839,7 +837,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip) /* * Component Destructor */ -static void snd_cx88_dev_free(struct snd_card * card) +static void snd_cx88_dev_free(struct snd_card *card) { snd_cx88_card_t *chip = card->private_data; @@ -872,14 +870,14 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, chip = card->private_data; core = cx88_core_get(pci); - if (NULL == core) { + if (core == NULL) { err = -EINVAL; return err; } - err = pci_set_dma_mask(pci,DMA_BIT_MASK(32)); + err = pci_set_dma_mask(pci, DMA_BIT_MASK(32)); if (err) { - dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); + dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name); cx88_core_put(core, pci); return err; } @@ -908,7 +906,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, dprintk(1, "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", core->name, devno, pci_name(pci), pci->revision, pci->irq, - pci_lat, (unsigned long long)pci_resource_start(pci,0)); + pci_lat, (unsigned long long)pci_resource_start(pci, 0)); chip->irq = pci->irq; synchronize_irq(chip->irq); @@ -964,19 +962,20 @@ static int cx88_audio_initdev(struct pci_dev *pci, if (core->sd_wm8775) snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip)); - strcpy (card->driver, "CX88x"); + strcpy(card->driver, "CX88x"); sprintf(card->shortname, "Conexant CX%x", pci->device); sprintf(card->longname, "%s at %#llx", - card->shortname,(unsigned long long)pci_resource_start(pci, 0)); - strcpy (card->mixername, "CX88"); + card->shortname, + (unsigned long long)pci_resource_start(pci, 0)); + strcpy(card->mixername, "CX88"); - dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", - card->driver,devno); + dprintk(0, "%s/%i: ALSA support for cx2388x boards\n", + card->driver, devno); err = snd_card_register(card); if (err < 0) goto error; - pci_set_drvdata(pci,card); + pci_set_drvdata(pci, card); devno++; return 0; diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 4163e777825d..bffd064daff5 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -1,5 +1,4 @@ /* - * * Support for a cx23416 mpeg encoder via cx2388x host port. * "blackbird" reference design. * @@ -20,10 +19,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -46,8 +41,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CX88_VERSION); static unsigned int debug; -module_param(debug,int,0644); -MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages [blackbird]"); #define dprintk(level, fmt, arg...) do { \ if (debug + 1 > level) \ @@ -216,14 +211,14 @@ static void host_setup(struct cx88_core *core) static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state) { unsigned long timeout = jiffies + msecs_to_jiffies(1); - u32 gpio0,need; + u32 gpio0, need; need = state ? 2 : 0; for (;;) { gpio0 = cx_read(MO_GP0_IO) & 2; if (need == gpio0) return 0; - if (time_after(jiffies,timeout)) + if (time_after(jiffies, timeout)) return -1; udelay(1); } @@ -242,7 +237,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value) cx_read(P1_MDATA0); cx_read(P1_MADDR0); - return wait_ready_gpio0_bit1(core,1); + return wait_ready_gpio0_bit1(core, 1); } static int memory_read(struct cx88_core *core, u32 address, u32 *value) @@ -256,7 +251,7 @@ static int memory_read(struct cx88_core *core, u32 address, u32 *value) cx_writeb(P1_MADDR0, (unsigned int)address); cx_read(P1_MADDR0); - retval = wait_ready_gpio0_bit1(core,1); + retval = wait_ready_gpio0_bit1(core, 1); cx_writeb(P1_MDATA3, 0); val = (unsigned char)cx_read(P1_MDATA3) << 24; @@ -283,7 +278,7 @@ static int register_write(struct cx88_core *core, u32 address, u32 value) cx_read(P1_RDATA0); cx_read(P1_RADDR0); - return wait_ready_gpio0_bit1(core,1); + return wait_ready_gpio0_bit1(core, 1); } @@ -297,7 +292,7 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value) cx_writeb(P1_RRDWR, 0); cx_read(P1_RADDR0); - retval = wait_ready_gpio0_bit1(core,1); + retval = wait_ready_gpio0_bit1(core, 1); val = (unsigned char)cx_read(P1_RDATA0); val |= (unsigned char)cx_read(P1_RDATA1) << 8; val |= (unsigned char)cx_read(P1_RDATA2) << 16; @@ -316,7 +311,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat u32 value, flag, retval; int i; - dprintk(1,"%s: 0x%X\n", __func__, command); + dprintk(1, "%s: 0x%X\n", __func__, command); /* this may not be 100% safe if we can't read any memory location without side effects */ @@ -354,7 +349,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat memory_read(dev->core, dev->mailbox, &flag); if (0 != (flag & 4)) break; - if (time_after(jiffies,timeout)) { + if (time_after(jiffies, timeout)) { dprintk(0, "ERROR: API Mailbox timeout %x\n", command); return -EIO; } @@ -368,7 +363,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat } memory_read(dev->core, dev->mailbox + 2, &retval); - dprintk(1, "API result = %d\n",retval); + dprintk(1, "API result = %d\n", retval); flag = 0; memory_write(dev->core, dev->mailbox, flag); @@ -400,8 +395,8 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, static int blackbird_find_mailbox(struct cx8802_dev *dev) { - u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456}; - int signaturecnt=0; + u32 signature[4] = {0x12345678, 0x34567812, 0x56781234, 0x78123456}; + int signaturecnt = 0; u32 value; int i; @@ -411,7 +406,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev) signaturecnt++; else signaturecnt = 0; - if (4 == signaturecnt) { + if (signaturecnt == 4) { dprintk(1, "Mailbox signature found\n"); return i+1; } @@ -459,14 +454,14 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) return -EINVAL; } - if (0 != memcmp(firmware->data, magic, 8)) { + if (memcmp(firmware->data, magic, 8) != 0) { pr_err("Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -EINVAL; } /* transfer to the chip */ - dprintk(1,"Loading firmware ...\n"); + dprintk(1, "Loading firmware ...\n"); dataptr = (__le32 *)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { value = le32_to_cpu(*dataptr); @@ -534,7 +529,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) int version; int retval; - dprintk(1,"Initialize codec\n"); + dprintk(1, "Initialize codec\n"); retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ if (retval < 0) { /* ping was not successful, reset and upload firmware */ @@ -782,7 +777,7 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index != 0) @@ -815,7 +810,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - unsigned maxw, maxh; + unsigned int maxw, maxh; enum v4l2_field field; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; @@ -871,14 +866,14 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int vidioc_s_frequency (struct file *file, void *priv, +static int vidioc_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; bool streaming; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; if (unlikely(f->tuner != 0)) return -EINVAL; @@ -886,7 +881,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, if (streaming) blackbird_stop_codec(dev); - cx88_set_freq (core,f); + cx88_set_freq(core, f); blackbird_initialize_codec(dev); cx88_set_scale(core, core->width, core->height, core->field); @@ -895,7 +890,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, return 0; } -static int vidioc_log_status (struct file *file, void *priv) +static int vidioc_log_status(struct file *file, void *priv) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -907,21 +902,22 @@ static int vidioc_log_status (struct file *file, void *priv) return 0; } -static int vidioc_enum_input (struct file *file, void *priv, +static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - return cx88_enum_input (core,i); + + return cx88_enum_input(core, i); } -static int vidioc_g_frequency (struct file *file, void *priv, +static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; if (unlikely(f->tuner != 0)) return -EINVAL; @@ -932,7 +928,7 @@ static int vidioc_g_frequency (struct file *file, void *priv, return 0; } -static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -941,7 +937,7 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) return 0; } -static int vidioc_s_input (struct file *file, void *priv, unsigned int i) +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -952,20 +948,20 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) return -EINVAL; cx88_newstation(core); - cx88_video_mux(core,i); + cx88_video_mux(core, i); return 0; } -static int vidioc_g_tuner (struct file *file, void *priv, +static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; u32 reg; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; - if (0 != t->index) + if (t->index != 0) return -EINVAL; strcpy(t->name, "Television"); @@ -973,21 +969,21 @@ static int vidioc_g_tuner (struct file *file, void *priv, t->rangehigh = 0xffffffffUL; call_all(core, tuner, g_tuner, t); - cx88_get_stereo(core ,t); + cx88_get_stereo(core, t); reg = cx_read(MO_DEVICE_STATUS); t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; return 0; } -static int vidioc_s_tuner (struct file *file, void *priv, +static int vidioc_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - if (UNSET == core->board.tuner_type) + if (core->board.tuner_type == UNSET) return -EINVAL; - if (0 != t->index) + if (t->index != 0) return -EINVAL; cx88_set_stereo(core, t->audmode, 1); @@ -1011,8 +1007,8 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) return cx88_set_tvnorm(core, id); } -static const struct v4l2_file_operations mpeg_fops = -{ +static const struct v4l2_file_operations mpeg_fops = { + .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, @@ -1051,7 +1047,7 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { static struct video_device cx8802_mpeg_template = { .name = "cx8802", .fops = &mpeg_fops, - .ioctl_ops = &mpeg_ioctl_ops, + .ioctl_ops = &mpeg_ioctl_ops, .tvnorms = CX88_NORMS, }; @@ -1136,8 +1132,8 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) struct vb2_queue *q; int err; - dprintk( 1, "%s\n", __func__); - dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", + dprintk(1, "%s\n", __func__); + dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, core->pci_bus, @@ -1165,8 +1161,8 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) /* initial device configuration: needed ? */ // init_controls(core); - cx88_set_tvnorm(core,core->tvnorm); - cx88_video_mux(core,0); + cx88_set_tvnorm(core, core->tvnorm); + cx88_video_mux(core, 0); cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576); cx2341x_handler_setup(&dev->cxhdl); diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 1a65db957dcb..269179142cd8 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -1,5 +1,4 @@ /* - * * device driver for Conexant 2388x based TV cards * card-specific stuff. * @@ -14,10 +13,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -38,19 +33,19 @@ module_param_array(tuner, int, NULL, 0444); module_param_array(radio, int, NULL, 0444); module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(tuner,"tuner type"); -MODULE_PARM_DESC(radio,"radio tuner type"); -MODULE_PARM_DESC(card,"card type"); +MODULE_PARM_DESC(tuner, "tuner type"); +MODULE_PARM_DESC(radio, "radio tuner type"); +MODULE_PARM_DESC(card, "card type"); static unsigned int latency = UNSET; -module_param(latency,int,0444); -MODULE_PARM_DESC(latency,"pci latency timer"); +module_param(latency, int, 0444); +MODULE_PARM_DESC(latency, "pci latency timer"); static int disable_ir; module_param(disable_ir, int, 0444); MODULE_PARM_DESC(disable_ir, "Disable IR support"); -#define dprintk(level,fmt, arg...) do { \ +#define dprintk(level, fmt, arg...) do { \ if (cx88_core_debug >= level) \ printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \ __func__, ##arg); \ @@ -2911,33 +2906,33 @@ static const struct { int fm; const char *name; } gdi_tuner[] = { - [ 0x01 ] = { .id = UNSET, + [0x01] = { .id = UNSET, .name = "NTSC_M" }, - [ 0x02 ] = { .id = UNSET, + [0x02] = { .id = UNSET, .name = "PAL_B" }, - [ 0x03 ] = { .id = UNSET, + [0x03] = { .id = UNSET, .name = "PAL_I" }, - [ 0x04 ] = { .id = UNSET, + [0x04] = { .id = UNSET, .name = "PAL_D" }, - [ 0x05 ] = { .id = UNSET, + [0x05] = { .id = UNSET, .name = "SECAM" }, - [ 0x10 ] = { .id = UNSET, + [0x10] = { .id = UNSET, .fm = 1, .name = "TEMIC_4049" }, - [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5, + [0x11] = { .id = TUNER_TEMIC_4136FY5, .name = "TEMIC_4136" }, - [ 0x12 ] = { .id = UNSET, + [0x12] = { .id = UNSET, .name = "TEMIC_4146" }, - [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME, + [0x20] = { .id = TUNER_PHILIPS_FQ1216ME, .fm = 1, .name = "PHILIPS_FQ1216_MK3" }, - [ 0x21 ] = { .id = UNSET, .fm = 1, + [0x21] = { .id = UNSET, .fm = 1, .name = "PHILIPS_FQ1236_MK3" }, - [ 0x22 ] = { .id = UNSET, + [0x22] = { .id = UNSET, .name = "PHILIPS_FI1236_MK3" }, - [ 0x23 ] = { .id = UNSET, + [0x23] = { .id = UNSET, .name = "PHILIPS_FI1216_MK3" }, }; @@ -2947,7 +2942,7 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) ? gdi_tuner[eeprom_data[0x0d]].name : NULL; pr_info("GDI: tuner=%s\n", name ? name : "unknown"); - if (NULL == name) + if (name == NULL) return; core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ? @@ -3167,7 +3162,7 @@ static int cx88_xc4000_tuner_callback(struct cx88_core *core, } /* ----------------------------------------------------------------------- */ -/* Tuner callback function. Currently only needed for the Pinnacle * +/* Tuner callback function. Currently only needed for the Pinnacle * * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both * * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */ @@ -3401,7 +3396,7 @@ static void cx88_card_setup(struct cx88_core *core) memset(&tun_setup, 0, sizeof(tun_setup)); - if (0 == core->i2c_rc) { + if (core->i2c_rc == 0) { core->i2c_client.addr = 0xa0 >> 1; tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom)); } @@ -3409,17 +3404,17 @@ static void cx88_card_setup(struct cx88_core *core) switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE: case CX88_BOARD_HAUPPAUGE_ROSLYN: - if (0 == core->i2c_rc) + if (core->i2c_rc == 0) hauppauge_eeprom(core, eeprom+8); break; case CX88_BOARD_GDI: - if (0 == core->i2c_rc) + if (core->i2c_rc == 0) gdi_eeprom(core, eeprom); break; case CX88_BOARD_LEADTEK_PVR2000: case CX88_BOARD_WINFAST_DV2000: case CX88_BOARD_WINFAST2000XP_EXPERT: - if (0 == core->i2c_rc) + if (core->i2c_rc == 0) leadtek_eeprom(core, eeprom); break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: @@ -3432,7 +3427,7 @@ static void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_HVR4000: case CX88_BOARD_HAUPPAUGE_HVR4000LITE: case CX88_BOARD_HAUPPAUGE_IRONLY: - if (0 == core->i2c_rc) + if (core->i2c_rc == 0) hauppauge_eeprom(core, eeprom); break; case CX88_BOARD_KWORLD_DVBS_100: @@ -3478,21 +3473,21 @@ static void cx88_card_setup(struct cx88_core *core) cx_write(MO_GP0_IO, 0x00080808); break; case CX88_BOARD_ATI_HDTVWONDER: - if (0 == core->i2c_rc) { + if (core->i2c_rc == 0) { /* enable tuner */ int i; - static const u8 buffer [][2] = { - {0x10,0x12}, - {0x13,0x04}, - {0x16,0x00}, - {0x14,0x04}, - {0x17,0x00} + static const u8 buffer[][2] = { + {0x10, 0x12}, + {0x13, 0x04}, + {0x16, 0x00}, + {0x14, 0x04}, + {0x17, 0x00} }; core->i2c_client.addr = 0x0a; for (i = 0; i < ARRAY_SIZE(buffer); i++) if (2 != i2c_master_send(&core->i2c_client, - buffer[i],2)) + buffer[i], 2)) pr_warn("Unable to enable tuner(%i).\n", i); } @@ -3616,7 +3611,7 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) #endif /* check insmod options */ - if (UNSET != latency) + if (latency != UNSET) lat = latency; /* apply stuff */ @@ -3625,7 +3620,7 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) value |= ctrl; pci_write_config_byte(pci, CX88X_DEVCTRL, value); } - if (UNSET != lat) { + if (lat != UNSET) { pr_info("setting pci latency timer to %d\n", latency); pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency); @@ -3635,8 +3630,8 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci) { - if (request_mem_region(pci_resource_start(pci,0), - pci_resource_len(pci,0), + if (request_mem_region(pci_resource_start(pci, 0), + pci_resource_len(pci, 0), core->name)) return 0; pr_err("func %d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n", @@ -3692,7 +3687,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) return NULL; } - if (0 != cx88_get_resources(core, pci)) { + if (cx88_get_resources(core, pci) != 0) { v4l2_ctrl_handler_free(&core->video_hdl); v4l2_ctrl_handler_free(&core->audio_hdl); v4l2_device_unregister(&core->v4l2_dev); @@ -3724,7 +3719,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) if (pci->subsystem_vendor == cx88_subids[i].subvendor && pci->subsystem_device == cx88_subids[i].subdevice) core->boardnr = cx88_subids[i].card; - if (UNSET == core->boardnr) { + if (core->boardnr == UNSET) { core->boardnr = CX88_BOARD_UNKNOWN; cx88_card_list(core, pci); } @@ -3754,7 +3749,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) cx88_i2c_init(core, pci); /* load tuner module, if needed */ - if (UNSET != core->board.tuner_type) { + if (core->board.tuner_type != UNSET) { /* Ignore 0x6b and 0x6f on cx88 boards. * FusionHDTV5 RT Gold has an ir receiver at 0x6b * and an RTC at 0x6f which can get corrupted if probed. */ diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 27203e094655..33719f0b06a5 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -1,5 +1,4 @@ /* - * * device driver for Conexant 2388x based TV cards * driver core * @@ -19,10 +18,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -54,12 +49,12 @@ module_param_named(core_debug, cx88_core_debug, int, 0644); MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); static unsigned int nicam; -module_param(nicam,int,0644); -MODULE_PARM_DESC(nicam,"tv audio is nicam"); +module_param(nicam, int, 0644); +MODULE_PARM_DESC(nicam, "tv audio is nicam"); static unsigned int nocomb; -module_param(nocomb,int,0644); -MODULE_PARM_DESC(nocomb,"disable comb filter"); +module_param(nocomb, int, 0644); +MODULE_PARM_DESC(nocomb, "disable comb filter"); #define dprintk0(fmt, arg...) \ printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \ @@ -79,13 +74,13 @@ static DEFINE_MUTEX(devlist); /* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be generated _after_ lpi lines are transferred. */ -static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, +static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, unsigned int lines, unsigned int lpi, bool jump) { struct scatterlist *sg; - unsigned int line,todo,sol; + unsigned int line, todo, sol; if (jump) { (*rp++) = cpu_to_le32(RISC_JUMP); @@ -103,33 +98,33 @@ static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, offset -= sg_dma_len(sg); sg = sg_next(sg); } - if (lpi && line>0 && !(line % lpi)) + if (lpi && line > 0 && !(line % lpi)) sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; else sol = RISC_SOL; if (bpl <= sg_dma_len(sg)-offset) { /* fits into current chunk */ - *(rp++)=cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl); - *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); - offset+=bpl; + *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl); + *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); + offset += bpl; } else { /* scanline needs to be split */ todo = bpl; - *(rp++)=cpu_to_le32(RISC_WRITE|sol| + *(rp++) = cpu_to_le32(RISC_WRITE|sol| (sg_dma_len(sg)-offset)); - *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); + *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); todo -= (sg_dma_len(sg)-offset); offset = 0; sg = sg_next(sg); while (todo > sg_dma_len(sg)) { - *(rp++)=cpu_to_le32(RISC_WRITE| + *(rp++) = cpu_to_le32(RISC_WRITE| sg_dma_len(sg)); - *(rp++)=cpu_to_le32(sg_dma_address(sg)); + *(rp++) = cpu_to_le32(sg_dma_address(sg)); todo -= sg_dma_len(sg); sg = sg_next(sg); } - *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); - *(rp++)=cpu_to_le32(sg_dma_address(sg)); + *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); + *(rp++) = cpu_to_le32(sg_dma_address(sg)); offset += todo; } offset += padding; @@ -143,13 +138,13 @@ int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, unsigned int top_offset, unsigned int bottom_offset, unsigned int bpl, unsigned int padding, unsigned int lines) { - u32 instructions,fields; + u32 instructions, fields; __le32 *rp; fields = 0; - if (UNSET != top_offset) + if (top_offset != UNSET) fields++; - if (UNSET != bottom_offset) + if (bottom_offset != UNSET) fields++; /* estimate risc mem: worst case is one write per page border + @@ -161,21 +156,21 @@ int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, risc->size = instructions * 8; risc->dma = 0; risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); - if (NULL == risc->cpu) + if (risc->cpu == NULL) return -ENOMEM; /* write risc instructions */ rp = risc->cpu; - if (UNSET != top_offset) + if (top_offset != UNSET) rp = cx88_risc_field(rp, sglist, top_offset, 0, bpl, padding, lines, 0, true); - if (UNSET != bottom_offset) + if (bottom_offset != UNSET) rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200, bpl, padding, lines, 0, top_offset == UNSET); /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); + WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); return 0; } @@ -195,7 +190,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, risc->size = instructions * 8; risc->dma = 0; risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); - if (NULL == risc->cpu) + if (risc->cpu == NULL) return -ENOMEM; /* write risc instructions */ @@ -204,7 +199,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, /* save pointer to jmp instruction address */ risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size); + WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); return 0; } @@ -340,7 +335,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, const struct sram_channel *ch, unsigned int bpl, u32 risc) { - unsigned int i,lines; + unsigned int i, lines; u32 cdt; bpl = (bpl + 7) & ~7; /* alignment */ @@ -348,7 +343,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, lines = ch->fifo_size / bpl; if (lines > 6) lines = 6; - BUG_ON(lines < 2); + WARN_ON(lines < 2); /* write CDT */ for (i = 0; i < lines; i++) @@ -366,7 +361,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, /* fill registers */ cx_write(ch->ptr1_reg, ch->fifo_start); cx_write(ch->ptr2_reg, cdt); - cx_write(ch->cnt1_reg, (bpl >> 3) -1); + cx_write(ch->cnt1_reg, (bpl >> 3) - 1); cx_write(ch->cnt2_reg, (lines*16) >> 3); dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines); @@ -379,23 +374,23 @@ int cx88_sram_channel_setup(struct cx88_core *core, static int cx88_risc_decode(u32 risc) { static const char * const instr[16] = { - [ RISC_SYNC >> 28 ] = "sync", - [ RISC_WRITE >> 28 ] = "write", - [ RISC_WRITEC >> 28 ] = "writec", - [ RISC_READ >> 28 ] = "read", - [ RISC_READC >> 28 ] = "readc", - [ RISC_JUMP >> 28 ] = "jump", - [ RISC_SKIP >> 28 ] = "skip", - [ RISC_WRITERM >> 28 ] = "writerm", - [ RISC_WRITECM >> 28 ] = "writecm", - [ RISC_WRITECR >> 28 ] = "writecr", + [RISC_SYNC >> 28] = "sync", + [RISC_WRITE >> 28] = "write", + [RISC_WRITEC >> 28] = "writec", + [RISC_READ >> 28] = "read", + [RISC_READC >> 28] = "readc", + [RISC_JUMP >> 28] = "jump", + [RISC_SKIP >> 28] = "skip", + [RISC_WRITERM >> 28] = "writerm", + [RISC_WRITECM >> 28] = "writecm", + [RISC_WRITECR >> 28] = "writecr", }; static int const incr[16] = { - [ RISC_WRITE >> 28 ] = 2, - [ RISC_JUMP >> 28 ] = 2, - [ RISC_WRITERM >> 28 ] = 3, - [ RISC_WRITECM >> 28 ] = 3, - [ RISC_WRITECR >> 28 ] = 4, + [RISC_WRITE >> 28] = 2, + [RISC_JUMP >> 28] = 2, + [RISC_WRITERM >> 28] = 3, + [RISC_WRITECM >> 28] = 3, + [RISC_WRITECR >> 28] = 4, }; static const char * const bits[] = { "12", "13", "14", "resync", @@ -432,7 +427,7 @@ void cx88_sram_channel_dump(struct cx88_core *core, "line / byte", }; u32 risc; - unsigned int i,j,n; + unsigned int i, j, n; dprintk0("%s - dma channel status dump\n", ch->name); @@ -645,7 +640,7 @@ static inline unsigned int norm_fsc8(v4l2_std_id norm) static inline unsigned int norm_htotal(v4l2_std_id norm) { - unsigned int fsc4=norm_fsc8(norm)/2; + unsigned int fsc4 = norm_fsc8(norm)/2; /* returns 4*FSC / vtotal / frames per seconds */ return (norm & V4L2_STD_625_50) ? @@ -711,7 +706,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig } if (INPUT(core->input).type == CX88_VMUX_SVIDEO) value |= (1 << 13) | (1 << 5); - if (V4L2_FIELD_INTERLACED == field) + if (field == V4L2_FIELD_INTERLACED) value |= (1 << 3); // VINT (interlaced vertical scaling) if (width < 385) value |= (1 << 0); // 3-tap interpolation @@ -742,7 +737,7 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) prescale = 5; pll = ofreq * 8 * prescale * (u64)(1 << 20); - do_div(pll,xtal); + do_div(pll, xtal); reg = (pll & 0x3ffffff) | (pre[prescale] << 26); if (((reg >> 20) & 0x3f) < 14) { pr_err("pll out of range\n"); @@ -755,8 +750,8 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) for (i = 0; i < 100; i++) { reg = cx_read(MO_DEVICE_STATUS); if (reg & (1<<2)) { - dprintk(1,"pll locked [pre=%d,ofreq=%d]\n", - prescale,ofreq); + dprintk(1, "pll locked [pre=%d,ofreq=%d]\n", + prescale, ofreq); return 0; } dprintk(1, "pll not locked yet, waiting ...\n"); @@ -863,9 +858,9 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) u32 fsc8; u32 adc_clock; u32 vdec_clock; - u32 step_db,step_dr; + u32 step_db, step_dr; u64 tmp64; - u32 bdelay,agcdelay,htotal; + u32 bdelay, agcdelay, htotal; u32 cxiformat, cxoformat; if (norm == core->tvnorm) @@ -917,7 +912,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n", v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock, step_db, step_dr); - set_pll(core,2,vdec_clock); + set_pll(core, 2, vdec_clock); dprintk(1, "set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f); @@ -1013,7 +1008,7 @@ void cx88_vdev_init(struct cx88_core *core, core->name, type, core->board.name); } -struct cx88_core* cx88_core_get(struct pci_dev *pci) +struct cx88_core *cx88_core_get(struct pci_dev *pci) { struct cx88_core *core; @@ -1024,7 +1019,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) if (PCI_SLOT(pci->devfn) != core->pci_slot) continue; - if (0 != cx88_get_resources(core, pci)) { + if (cx88_get_resources(core, pci) != 0) { mutex_unlock(&devlist); return NULL; } @@ -1034,7 +1029,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) } core = cx88_core_create(pci, cx88_devcount); - if (NULL != core) { + if (core != NULL) { cx88_devcount++; list_add_tail(&core->devlist, &cx88_devlist); } @@ -1045,15 +1040,15 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) { - release_mem_region(pci_resource_start(pci,0), - pci_resource_len(pci,0)); + release_mem_region(pci_resource_start(pci, 0), + pci_resource_len(pci, 0)); if (!atomic_dec_and_test(&core->refcount)) return; mutex_lock(&devlist); cx88_ir_fini(core); - if (0 == core->i2c_rc) { + if (core->i2c_rc == 0) { if (core->i2c_rtc) i2c_unregister_device(core->i2c_rtc); i2c_del_adapter(&core->i2c_adap); diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 4f1ec8d13389..235124e2a763 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -1,5 +1,4 @@ /* - * * Stereo and SAP detection for cx88 * * Copyright (c) 2009 Marton Balint @@ -13,10 +12,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -82,6 +77,7 @@ static s32 int_cos(u32 x) u32 t2, t4, t6, t8; s32 ret; u16 period = x / INT_PI; + if (period % 2) return -int_cos(x - INT_PI); x = x % INT_PI; @@ -111,6 +107,7 @@ static u32 int_goertzel(s16 x[], u32 N, u32 freq) for (i = 0; i < N; i++) { s32 s = x[i] + ((s64)coeff * s_prev / 32768) - s_prev2; + s_prev2 = s_prev; s_prev = s; } @@ -129,6 +126,7 @@ static u32 int_goertzel(s16 x[], u32 N, u32 freq) static u32 freq_magnitude(s16 x[], u32 N, u32 freq) { u32 sum = int_goertzel(x, N, freq); + return (u32)int_sqrt(sum); } @@ -225,6 +223,7 @@ static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N) s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP); s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF); s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL); + dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d\n", dual_ref, dual, sap_ref, sap); /* FIXME: Currently not supported */ @@ -307,7 +306,7 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) kfree(samples); - if (UNSET != ret) + if (ret != UNSET) dprintk(1, "stereo/sap detection result:%s%s%s\n", (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 378135ddb6fb..5188f8f2d6dd 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -1,5 +1,4 @@ /* - * * device driver for Conexant 2388x based TV cards * MPEG Transport Stream (DVB) routines * @@ -15,10 +14,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -70,7 +65,7 @@ MODULE_VERSION(CX88_VERSION); static unsigned int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); +MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); static unsigned int dvb_buf_tscnt = 32; module_param(dvb_buf_tscnt, int, 0644); @@ -173,9 +168,9 @@ static const struct vb2_ops dvb_qops = { /* ------------------------------------------------------------------ */ -static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) +static int cx88_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; struct cx8802_driver *drv = NULL; int ret = 0; int fe_id; @@ -189,7 +184,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) mutex_lock(&dev->core->lock); drv = cx8802_get_driver(dev, CX88_MPEG_DVB); if (drv) { - if (acquire){ + if (acquire) { dev->frontends.active_fe_id = fe_id; ret = drv->request_acquire(drv); } else { @@ -226,13 +221,13 @@ static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) /* ------------------------------------------------------------------ */ -static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) +static int dvico_fusionhdtv_demod_init(struct dvb_frontend *fe) { - static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; - static const u8 reset [] = { RESET, 0x80 }; - static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; - static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; + static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x39 }; + static const u8 reset[] = { RESET, 0x80 }; + static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; + static const u8 agc_cfg[] = { AGC_TARGET, 0x24, 0x20 }; + static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; mt352_write(fe, clock_config, sizeof(clock_config)); @@ -248,11 +243,11 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) static int dvico_dual_demod_init(struct dvb_frontend *fe) { - static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; - static const u8 reset [] = { RESET, 0x80 }; - static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; - static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; + static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x38 }; + static const u8 reset[] = { RESET, 0x80 }; + static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; + static const u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 }; + static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; mt352_write(fe, clock_config, sizeof(clock_config)); @@ -267,12 +262,12 @@ static int dvico_dual_demod_init(struct dvb_frontend *fe) return 0; } -static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) +static int dntv_live_dvbt_demod_init(struct dvb_frontend *fe) { - static const u8 clock_config [] = { 0x89, 0x38, 0x39 }; - static const u8 reset [] = { 0x50, 0x80 }; - static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, + static const u8 clock_config[] = { 0x89, 0x38, 0x39 }; + static const u8 reset[] = { 0x50, 0x80 }; + static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 }; + static const u8 agc_cfg[] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x40, 0x40 }; static const u8 dntv_extra[] = { 0xB5, 0x7A }; static const u8 capt_range_cfg[] = { 0x75, 0x32 }; @@ -316,12 +311,12 @@ static struct mb86a16_config twinhan_vp1027 = { }; #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) -static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) +static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend *fe) { - static const u8 clock_config [] = { 0x89, 0x38, 0x38 }; - static const u8 reset [] = { 0x50, 0x80 }; - static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, + static const u8 clock_config[] = { 0x89, 0x38, 0x38 }; + static const u8 reset[] = { 0x50, 0x80 }; + static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 }; + static const u8 agc_cfg[] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x40, 0x40 }; static const u8 dntv_extra[] = { 0xB5, 0x7A }; static const u8 capt_range_cfg[] = { 0x75, 0x32 }; @@ -378,9 +373,10 @@ static const struct cx22702_config hauppauge_hvr_config = { .output_mode = CX22702_SERIAL_OUTPUT, }; -static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) +static int or51132_set_ts_param(struct dvb_frontend *fe, int is_punctured) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } @@ -390,9 +386,9 @@ static const struct or51132_config pchdtv_hd3000 = { .set_ts_params = or51132_set_ts_param, }; -static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) +static int lgdt330x_pll_rf_set(struct dvb_frontend *fe, int index) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; dprintk(1, "%s: index = %d\n", __func__, index); @@ -403,9 +399,10 @@ static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) return 0; } -static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) +static int lgdt330x_set_ts_param(struct dvb_frontend *fe, int is_punctured) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; + if (is_punctured) dev->ts_gen_cntrl |= 0x04; else @@ -434,9 +431,10 @@ static const struct lgdt330x_config pchdtv_hd5500 = { .set_ts_params = lgdt330x_set_ts_param, }; -static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) +static int nxt200x_set_ts_param(struct dvb_frontend *fe, int is_punctured) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } @@ -446,18 +444,19 @@ static const struct nxt200x_config ati_hdtvwonder = { .set_ts_params = nxt200x_set_ts_param, }; -static int cx24123_set_ts_param(struct dvb_frontend* fe, +static int cx24123_set_ts_param(struct dvb_frontend *fe, int is_punctured) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = 0x02; return 0; } -static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, +static int kworld_dvbs_100_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) @@ -473,11 +472,11 @@ static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) { - dprintk(1,"LNB Voltage OFF\n"); + dprintk(1, "LNB Voltage OFF\n"); cx_write(MO_GP0_IO, 0x0000efff); } @@ -489,7 +488,7 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { - struct cx8802_dev *dev= fe->dvb->priv; + struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; cx_set(MO_GP0_IO, 0x6040); @@ -688,6 +687,7 @@ static int cx24116_set_ts_param(struct dvb_frontend *fe, int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = 0x2; return 0; @@ -697,6 +697,7 @@ static int stv0900_set_ts_param(struct dvb_frontend *fe, int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = 0; return 0; @@ -734,6 +735,7 @@ static int ds3000_set_ts_param(struct dvb_frontend *fe, int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; + dev->ts_gen_cntrl = 4; return 0; @@ -1005,7 +1007,7 @@ static int dvb_register(struct cx8802_dev *dev) int mfe_shared = 0; /* bus not shared by default */ int res = -EINVAL; - if (0 != core->i2c_rc) { + if (core->i2c_rc != 0) { pr_err("no i2c-bus available, cannot attach dvb drivers\n"); goto frontend_detach; } @@ -1423,7 +1425,7 @@ static int dvb_register(struct cx8802_dev *dev) if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; - case CX88_BOARD_KWORLD_ATSC_120: + case CX88_BOARD_KWORLD_ATSC_120: fe0->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, &core->i2c_adap); @@ -1617,7 +1619,7 @@ static int dvb_register(struct cx8802_dev *dev) break; } - if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { + if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { pr_err("frontend initialization failed\n"); goto frontend_detach; } @@ -1653,7 +1655,8 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; - dprintk( 1, "%s\n", __func__); + + dprintk(1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -1717,7 +1720,8 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; - dprintk( 1, "%s\n", __func__); + + dprintk(1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -1740,8 +1744,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) struct vb2_dvb_frontend *fe; int i; - dprintk( 1, "%s\n", __func__); - dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", + dprintk(1, "%s\n", __func__); + dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, core->pci_bus, @@ -1753,7 +1757,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); - if (0 != err) + if (err != 0) goto fail_core; /* dvb stuff */ @@ -1811,7 +1815,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; - dprintk( 1, "%s\n", __func__); + dprintk(1, "%s\n", __func__); vb2_dvb_unregister_bus(&dev->frontends); diff --git a/drivers/media/pci/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c index 831f8db5150e..99596fe56cd2 100644 --- a/drivers/media/pci/cx88/cx88-i2c.c +++ b/drivers/media/pci/cx88/cx88-i2c.c @@ -1,31 +1,26 @@ /* - - cx88-i2c.c -- all the i2c code is here - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - & Marcus Metzler (mocm@thp.uni-koeln.de) - (c) 2002 Yurij Sysoev - (c) 1999-2003 Gerd Knorr - - (c) 2005 Mauro Carvalho Chehab - - Multituner support and i2c address binding - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ + * + * cx88-i2c.c -- all the i2c code is here + * + * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + * & Marcus Metzler (mocm@thp.uni-koeln.de) + * (c) 2002 Yurij Sysoev + * (c) 1999-2003 Gerd Knorr + * + * (c) 2005 Mauro Carvalho Chehab + * - Multituner support and i2c address binding + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "cx88.h" @@ -38,11 +33,11 @@ static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); +MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); -MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); +MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); static unsigned int i2c_udelay = 5; module_param(i2c_udelay, int, 0644); @@ -112,22 +107,22 @@ static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { /* ----------------------------------------------------------------------- */ static const char * const i2c_devs[128] = { - [ 0x1c >> 1 ] = "lgdt330x", - [ 0x86 >> 1 ] = "tda9887/cx22702", - [ 0xa0 >> 1 ] = "eeprom", - [ 0xc0 >> 1 ] = "tuner (analog)", - [ 0xc2 >> 1 ] = "tuner (analog/dvb)", - [ 0xc8 >> 1 ] = "xc5000", + [0x1c >> 1] = "lgdt330x", + [0x86 >> 1] = "tda9887/cx22702", + [0xa0 >> 1] = "eeprom", + [0xc0 >> 1] = "tuner (analog)", + [0xc2 >> 1] = "tuner (analog/dvb)", + [0xc8 >> 1] = "xc5000", }; static void do_i2c_scan(const char *name, struct i2c_client *c) { unsigned char buf; - int i,rc; + int i, rc; for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { c->addr = i; - rc = i2c_master_recv(c,&buf,0); + rc = i2c_master_recv(c, &buf, 0); if (rc < 0) continue; pr_info("i2c scan: found device @ 0x%x [%s]\n", @@ -139,14 +134,14 @@ static void do_i2c_scan(const char *name, struct i2c_client *c) int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) { /* Prevents usage of invalid delay values */ - if (i2c_udelay<5) - i2c_udelay=5; + if (i2c_udelay < 5) + i2c_udelay = 5; core->i2c_algo = cx8800_i2c_algo_template; core->i2c_adap.dev.parent = &pci->dev; - strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); + strlcpy(core->i2c_adap.name, core->name, sizeof(core->i2c_adap.name)); core->i2c_adap.owner = THIS_MODULE; core->i2c_algo.udelay = i2c_udelay; core->i2c_algo.data = core; @@ -155,18 +150,22 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) core->i2c_client.adapter = &core->i2c_adap; strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE); - cx8800_bit_setscl(core,1); - cx8800_bit_setsda(core,1); + cx8800_bit_setscl(core, 1); + cx8800_bit_setsda(core, 1); core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap); - if (0 == core->i2c_rc) { - static u8 tuner_data[] = - { 0x0b, 0xdc, 0x86, 0x52 }; - static struct i2c_msg tuner_msg = - { .flags = 0, .addr = 0xc2 >> 1, .buf = tuner_data, .len = 4 }; + if (core->i2c_rc == 0) { + static u8 tuner_data[] = { + 0x0b, 0xdc, 0x86, 0x52 }; + static struct i2c_msg tuner_msg = { + .flags = 0, + .addr = 0xc2 >> 1, + .buf = tuner_data, + .len = 4 + }; dprintk(1, "i2c register ok\n"); - switch( core->boardnr ) { + switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: @@ -177,7 +176,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) break; } if (i2c_scan) - do_i2c_scan(core->name,&core->i2c_client); + do_i2c_scan(core->name, &core->i2c_client); } else pr_err("i2c register FAILED\n"); diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index 3a05629ba6e4..c072b7ecc8d6 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -16,10 +16,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "cx88.h" @@ -58,7 +54,7 @@ struct cx88_IR { u32 mask_keyup; }; -static unsigned ir_samplerate = 4; +static unsigned int ir_samplerate = 4; module_param(ir_samplerate, uint, 0444); MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4"); @@ -67,10 +63,10 @@ module_param(ir_debug, int, 0644); /* debug level [IR] */ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); #define ir_dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg) + printk(KERN_DEBUG "%s IR: " fmt, ir->core->name, ##arg) #define dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "cx88 IR: " fmt , ##arg) + printk(KERN_DEBUG "cx88 IR: " fmt, ##arg) /* ---------------------------------------------------------------------- */ @@ -97,7 +93,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) auxgpio = cx_read(MO_GP1_IO); /* Take out the parity part */ - gpio=(gpio & 0x7fd) + (auxgpio & 0xef); + gpio = (gpio & 0x7fd) + (auxgpio & 0xef); break; case CX88_BOARD_WINFAST_DTV1000: case CX88_BOARD_WINFAST_DTV1800H: @@ -512,7 +508,7 @@ int cx88_ir_fini(struct cx88_core *core) struct cx88_IR *ir = core->ir; /* skip detach on non attached boards */ - if (NULL == ir) + if (ir == NULL) return 0; cx88_ir_stop(core); @@ -530,7 +526,7 @@ void cx88_ir_irq(struct cx88_core *core) { struct cx88_IR *ir = core->ir; u32 samples; - unsigned todo, bits; + unsigned int todo, bits; struct ir_raw_event ev; if (!ir || !ir->sampling) @@ -602,7 +598,7 @@ void cx88_i2c_init_ir(struct cx88_core *core) const unsigned short *addr_list = default_addr_list; const unsigned short *addrp; /* Instantiate the IR receiver device, if present */ - if (0 != core->i2c_rc) + if (core->i2c_rc != 0) return; memset(&info, 0, sizeof(struct i2c_board_info)); diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index ed3fcc8149bd..4533e2c6cb9f 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -42,8 +42,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CX88_VERSION); static unsigned int debug; -module_param(debug,int,0644); -MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages [mpeg]"); #define dprintk(level, fmt, arg...) do { \ if (debug + 1 > level) \ @@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); #if defined(CONFIG_MODULES) && defined(MODULE) static void request_module_async(struct work_struct *work) { - struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk); + struct cx8802_dev *dev = container_of(work, struct cx8802_dev, request_module_wk); if (dev->core->board.mpeg & CX88_MPEG_DVB) request_module("cx88-dvb"); @@ -103,8 +103,8 @@ int cx8802_start_dma(struct cx8802_dev *dev, dprintk(1, "core->active_type_id = 0x%08x\n", core->active_type_id); - if ( (core->active_type_id == CX88_MPEG_DVB) && - (core->board.mpeg & CX88_MPEG_DVB) ) { + if ((core->active_type_id == CX88_MPEG_DVB) && + (core->board.mpeg & CX88_MPEG_DVB)) { dprintk(1, "cx8802_start_dma doing .dvb\n"); /* negedge driven & software reset */ @@ -148,8 +148,8 @@ int cx8802_start_dma(struct cx8802_dev *dev, } cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); udelay(100); - } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) && - (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) { + } else if ((core->active_type_id == CX88_MPEG_BLACKBIRD) && + (core->board.mpeg & CX88_MPEG_BLACKBIRD)) { dprintk(1, "cx8802_start_dma doing .blackbird\n"); cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ @@ -185,6 +185,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, static int cx8802_stop_dma(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; + dprintk(1, "\n"); /* stop dma */ @@ -209,7 +210,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, return 0; buf = list_entry(q->active.next, struct cx88_buffer, list); - dprintk(2,"restart_queue [%p/%d]: restart dma\n", + dprintk(2, "restart_queue [%p/%d]: restart dma\n", buf, buf->vb.vb2_buf.index); cx8802_start_dma(dev, q, buf); return 0; @@ -254,7 +255,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) if (list_empty(&cx88q->active)) { dprintk(1, "queue is empty - first active\n"); list_add_tail(&buf->list, &cx88q->active); - dprintk(1,"[%p/%d] %s - first active\n", + dprintk(1, "[%p/%d] %s - first active\n", buf, buf->vb.vb2_buf.index, __func__); } else { @@ -276,13 +277,13 @@ static void do_cancel_buffers(struct cx8802_dev *dev) struct cx88_buffer *buf; unsigned long flags; - spin_lock_irqsave(&dev->slock,flags); + spin_lock_irqsave(&dev->slock, flags); while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, list); list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } - spin_unlock_irqrestore(&dev->slock,flags); + spin_unlock_irqrestore(&dev->slock, flags); } void cx8802_cancel_buffers(struct cx8802_dev *dev) @@ -292,7 +293,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev) do_cancel_buffers(dev); } -static const char * cx88_mpeg_irqs[32] = { +static const char *cx88_mpeg_irqs[32] = { "ts_risci1", NULL, NULL, NULL, "ts_risci2", NULL, NULL, NULL, "ts_oflow", NULL, NULL, NULL, @@ -356,7 +357,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id) for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | PCI_INT_TSINT); - if (0 == status) + if (status == 0) goto out; dprintk(1, "cx8802_irq\n"); dprintk(1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP); @@ -365,14 +366,14 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id) cx_write(MO_PCI_INTSTAT, status); if (status & core->pci_irqmask) - cx88_core_irq(core,status); + cx88_core_irq(core, status); if (status & PCI_INT_TSINT) cx8802_mpeg_irq(dev); } - if (MAX_IRQ_LOOP == loop) { + if (loop == MAX_IRQ_LOOP) { dprintk(0, "clearing mask\n"); pr_warn("irq loop -- clearing mask\n"); - cx_write(MO_PCI_INTMSK,0); + cx_write(MO_PCI_INTMSK, 0); } out: @@ -388,7 +389,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) if (pci_enable_device(dev->pci)) return -EIO; pci_set_master(dev->pci); - err = pci_set_dma_mask(dev->pci,DMA_BIT_MASK(32)); + err = pci_set_dma_mask(dev->pci, DMA_BIT_MASK(32)); if (err) { pr_err("Oops: no 32bit PCI DMA ???\n"); return -EIO; @@ -417,7 +418,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) cx_set(MO_PCI_INTMSK, core->pci_irqmask); /* everything worked */ - pci_set_drvdata(dev->pci,dev); + pci_set_drvdata(dev->pci, dev); return 0; } @@ -451,7 +452,7 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(dev->core); pci_save_state(pci_dev); - if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { + if (pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)) != 0) { pci_disable_device(pci_dev); dev->state.disabled = 1; } @@ -465,14 +466,14 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) int err; if (dev->state.disabled) { - err=pci_enable_device(pci_dev); + err = pci_enable_device(pci_dev); if (err) { pr_err("can't enable device\n"); return err; } dev->state.disabled = 0; } - err=pci_set_power_state(pci_dev, PCI_D0); + err = pci_set_power_state(pci_dev, PCI_D0); if (err) { pr_err("can't enable device\n"); pci_disable_device(pci_dev); @@ -489,14 +490,14 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->mpegq.active)) { pr_info("resume mpeg\n"); - cx8802_restart_queue(dev,&dev->mpegq); + cx8802_restart_queue(dev, &dev->mpegq); } spin_unlock_irqrestore(&dev->slock, flags); return 0; } -struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) +struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) { struct cx8802_driver *d; @@ -613,7 +614,7 @@ int cx8802_register_driver(struct cx8802_driver *drv) dev->core->boardnr); /* Bring up a new struct for each driver instance */ - driver = kzalloc(sizeof(*drv),GFP_KERNEL); + driver = kzalloc(sizeof(*drv), GFP_KERNEL); if (driver == NULL) { err = -ENOMEM; goto out; @@ -696,7 +697,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, /* general setup */ core = cx88_core_get(pci_dev); - if (NULL == core) + if (core == NULL) return -EINVAL; pr_info("cx2388x 8802 Driver Manager\n"); @@ -706,8 +707,8 @@ static int cx8802_probe(struct pci_dev *pci_dev, goto fail_core; err = -ENOMEM; - dev = kzalloc(sizeof(*dev),GFP_KERNEL); - if (NULL == dev) + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) goto fail_core; dev->pci = pci_dev; dev->core = core; @@ -721,7 +722,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, INIT_LIST_HEAD(&dev->drvlist); mutex_lock(&cx8802_mutex); - list_add_tail(&dev->devlist,&cx8802_devlist); + list_add_tail(&dev->devlist, &cx8802_devlist); mutex_unlock(&cx8802_mutex); /* now autoload cx88-dvb or cx88-blackbird */ @@ -732,7 +733,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, kfree(dev); fail_core: core->dvbdev = NULL; - cx88_core_put(core,pci_dev); + cx88_core_put(core, pci_dev); return err; } @@ -772,7 +773,7 @@ static void cx8802_remove(struct pci_dev *pci_dev) /* common */ cx8802_fini_common(dev); - cx88_core_put(dev->core,dev->pci); + cx88_core_put(dev->core, dev->pci); kfree(dev); } @@ -782,7 +783,7 @@ static const struct pci_device_id cx8802_pci_tbl[] = { .device = 0x8802, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - },{ + }, { /* --- end of list --- */ } }; diff --git a/drivers/media/pci/cx88/cx88-reg.h b/drivers/media/pci/cx88/cx88-reg.h index 2ec52d1cdea0..88ed8a2e4ee1 100644 --- a/drivers/media/pci/cx88/cx88-reg.h +++ b/drivers/media/pci/cx88/cx88-reg.h @@ -576,7 +576,7 @@ #define RISC_CNT_INC 0x00010000 #define RISC_CNT_RSVR 0x00020000 #define RISC_CNT_RESET 0x00030000 -#define RISC_JMP_SRP 0x01 +#define RISC_JMP_SRP 0x01 /* ---------------------------------------------------------------------- */ @@ -822,15 +822,4 @@ #define DEFAULT_SAT_U_NTSC 0x7F #define DEFAULT_SAT_V_NTSC 0x5A -typedef enum -{ - SOURCE_TUNER = 0, - SOURCE_COMPOSITE, - SOURCE_SVIDEO, - SOURCE_OTHER1, - SOURCE_OTHER2, - SOURCE_COMPVIASVIDEO, - SOURCE_CCIR656 -} VIDEOSOURCETYPE; - #endif /* _CX88_REG_H_ */ diff --git a/drivers/media/pci/cx88/cx88-tvaudio.c b/drivers/media/pci/cx88/cx88-tvaudio.c index b1d8680235e6..20f6924abe35 100644 --- a/drivers/media/pci/cx88/cx88-tvaudio.c +++ b/drivers/media/pci/cx88/cx88-tvaudio.c @@ -1,39 +1,34 @@ /* - - cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver - - (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version] - (c) 2002 Yurij Sysoev - (c) 2003 Gerd Knorr - - ----------------------------------------------------------------------- - - Lot of voodoo here. Even the data sheet doesn't help to - understand what is going on here, the documentation for the audio - part of the cx2388x chip is *very* bad. - - Some of this comes from party done linux driver sources I got from - [undocumented]. - - Some comes from the dscaler sources, one of the dscaler driver guy works - for Conexant ... - - ----------------------------------------------------------------------- - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver + * + * (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version] + * (c) 2002 Yurij Sysoev + * (c) 2003 Gerd Knorr + * + * ----------------------------------------------------------------------- + * + * Lot of voodoo here. Even the data sheet doesn't help to + * understand what is going on here, the documentation for the audio + * part of the cx2388x chip is *very* bad. + * + * Some of this comes from party done linux driver sources I got from + * [undocumented]. + * + * Some comes from the dscaler sources, one of the dscaler driver guy works + * for Conexant ... + * + * ----------------------------------------------------------------------- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "cx88.h" @@ -57,11 +52,11 @@ module_param(audio_debug, int, 0644); MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]"); static unsigned int always_analog; -module_param(always_analog,int,0644); -MODULE_PARM_DESC(always_analog,"force analog audio out"); +module_param(always_analog, int, 0644); +MODULE_PARM_DESC(always_analog, "force analog audio out"); static unsigned int radio_deemphasis; -module_param(radio_deemphasis,int,0644); +module_param(radio_deemphasis, int, 0644); MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, 0=None, 1=50us (elsewhere), 2=75us (USA)"); #define dprintk(fmt, arg...) do { \ @@ -350,7 +345,7 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode) { /* end of list */ }, }; - set_audio_start(core,SEL_NICAM); + set_audio_start(core, SEL_NICAM); switch (core->tvaudio) { case WW_L: dprintk("%s SECAM-L NICAM (status: devel)\n", __func__); @@ -770,7 +765,7 @@ void cx88_set_tvaudio(struct cx88_core *core) /* set nicam mode - otherwise AUD_NICAM_STATUS2 contains wrong values */ set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO); - if (0 == cx88_detect_nicam(core)) { + if (cx88_detect_nicam(core) == 0) { /* fall back to fm / am mono */ set_audio_standard_A2(core, EN_A2_FORCE_MONO1); core->audiomode_current = V4L2_TUNER_MODE_MONO; @@ -869,11 +864,11 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) } /* If software stereo detection is not supported... */ - if (UNSET == t->rxsubchans) { + if (t->rxsubchans == UNSET) { t->rxsubchans = V4L2_TUNER_SUB_MONO; /* If the hardware itself detected stereo, also return stereo as an available subchannel */ - if (V4L2_TUNER_MODE_STEREO == t->audmode) + if (t->audmode == V4L2_TUNER_MODE_STEREO) t->rxsubchans |= V4L2_TUNER_SUB_STEREO; } return; @@ -887,7 +882,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) if (manual) { core->audiomode_manual = mode; } else { - if (UNSET != core->audiomode_manual) + if (core->audiomode_manual != UNSET) return; } core->audiomode_current = mode; @@ -915,7 +910,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) case WW_M: case WW_I: case WW_L: - if (1 == core->use_nicam) { + if (core->use_nicam == 1) { switch (mode) { case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_LANG1: @@ -975,7 +970,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) break; } - if (UNSET != ctl) { + if (ctl != UNSET) { dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x [status=0x%x,ctl=0x%x,vol=0x%x]\n", mask, ctl, cx_read(AUD_STATUS), cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL)); @@ -1011,7 +1006,7 @@ int cx88_audio_thread(void *data) memset(&t, 0, sizeof(t)); cx88_get_stereo(core, &t); - if (UNSET != core->audiomode_manual) + if (core->audiomode_manual != UNSET) /* manually set, don't do anything. */ continue; diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 227f0f66e015..9028822f507e 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -8,8 +8,8 @@ #include static unsigned int vbi_debug; -module_param(vbi_debug,int,0644); -MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); +module_param(vbi_debug, int, 0644); +MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); #define dprintk(level, fmt, arg...) do { \ if (vbi_debug >= level) \ @@ -19,7 +19,7 @@ MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); /* ------------------------------------------------------------------ */ -int cx8800_vbi_fmt (struct file *file, void *priv, +int cx8800_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); @@ -57,9 +57,9 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24], VBI_LINE_LENGTH, buf->risc.dma); - cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup + cx_write(MO_VBOS_CONTROL, ((1 << 18) | // comb filter delay fixup (1 << 15) | // enable vbi capture - (1 << 11) )); + (1 << 11))); /* reset counter */ cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET); @@ -70,7 +70,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, cx_set(MO_VID_INTMSK, 0x0f0088); /* enable capture */ - cx_set(VID_CAPTURE_CONTROL,0x18); + cx_set(VID_CAPTURE_CONTROL, 0x18); /* start dma */ cx_set(MO_DEV_CNTRL2, (1<<5)); @@ -87,7 +87,7 @@ void cx8800_stop_vbi_dma(struct cx8800_dev *dev) cx_clear(MO_VID_DMACNTRL, 0x88); /* disable capture */ - cx_clear(VID_CAPTURE_CONTROL,0x18); + cx_clear(VID_CAPTURE_CONTROL, 0x18); /* disable irqs */ cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT); @@ -103,7 +103,7 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev, return 0; buf = list_entry(q->active.next, struct cx88_buffer, list); - dprintk(2,"restart_queue [%p/%d]: restart dma\n", + dprintk(2, "restart_queue [%p/%d]: restart dma\n", buf, buf->vb.vb2_buf.index); cx8800_start_vbi_dma(dev, q, buf); return 0; @@ -179,7 +179,7 @@ static void buffer_queue(struct vb2_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->list, &q->active); cx8800_start_vbi_dma(dev, q, buf); - dprintk(2,"[%p/%d] vbi_queue - first active\n", + dprintk(2, "[%p/%d] vbi_queue - first active\n", buf, buf->vb.vb2_buf.index); } else { @@ -187,7 +187,7 @@ static void buffer_queue(struct vb2_buffer *vb) prev = list_entry(q->active.prev, struct cx88_buffer, list); list_add_tail(&buf->list, &q->active); prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(2,"[%p/%d] buffer_queue - append to active\n", + dprintk(2, "[%p/%d] buffer_queue - append to active\n", buf, buf->vb.vb2_buf.index); } } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 3d349dfb23ff..797d5d0a4060 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -19,10 +19,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -59,17 +55,17 @@ module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); -MODULE_PARM_DESC(video_nr,"video device numbers"); -MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); -MODULE_PARM_DESC(radio_nr,"radio device numbers"); +MODULE_PARM_DESC(video_nr, "video device numbers"); +MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); +MODULE_PARM_DESC(radio_nr, "radio device numbers"); static unsigned int video_debug; -module_param(video_debug,int,0644); -MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); +module_param(video_debug, int, 0644); +MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); static unsigned int irq_debug; -module_param(irq_debug,int,0644); -MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); +module_param(irq_debug, int, 0644); +MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); #define dprintk(level, fmt, arg...) do { \ if (video_debug >= level) \ @@ -88,55 +84,55 @@ static const struct cx8800_fmt formats[] = { .cxformat = ColorFormatY8, .depth = 8, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "15 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB555, .cxformat = ColorFormatRGB15, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "15 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB555X, .cxformat = ColorFormatRGB15 | ColorFormatBSWAP, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "16 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB565, .cxformat = ColorFormatRGB16, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "16 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB565X, .cxformat = ColorFormatRGB16 | ColorFormatBSWAP, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "24 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR24, .cxformat = ColorFormatRGB24, .depth = 24, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "32 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR32, .cxformat = ColorFormatRGB32, .depth = 32, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "32 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB32, .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | ColorFormatWSWAP, .depth = 32, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .cxformat = ColorFormatYUY2, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - },{ + }, { .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .cxformat = ColorFormatYUY2 | ColorFormatBSWAP, @@ -145,7 +141,7 @@ static const struct cx8800_fmt formats[] = { }, }; -static const struct cx8800_fmt* format_by_fourcc(unsigned int fourcc) +static const struct cx8800_fmt *format_by_fourcc(unsigned int fourcc) { unsigned int i; @@ -185,7 +181,7 @@ static const struct cx88_ctrl cx8800_vid_ctls[] = { .reg = MO_CONTR_BRIGHT, .mask = 0x00ff, .shift = 0, - },{ + }, { .id = V4L2_CID_CONTRAST, .minimum = 0, .maximum = 0xff, @@ -195,7 +191,7 @@ static const struct cx88_ctrl cx8800_vid_ctls[] = { .reg = MO_CONTR_BRIGHT, .mask = 0xff00, .shift = 8, - },{ + }, { .id = V4L2_CID_HUE, .minimum = 0, .maximum = 0xff, @@ -205,7 +201,7 @@ static const struct cx88_ctrl cx8800_vid_ctls[] = { .reg = MO_HUE, .mask = 0x00ff, .shift = 0, - },{ + }, { /* strictly, this only describes only U saturation. * V saturation is handled specially through code. */ @@ -270,7 +266,7 @@ static const struct cx88_ctrl cx8800_aud_ctls[] = { .sreg = SHADOW_AUD_VOL_CTL, .mask = (1 << 6), .shift = 6, - },{ + }, { .id = V4L2_CID_AUDIO_VOLUME, .minimum = 0, .maximum = 0x3f, @@ -280,7 +276,7 @@ static const struct cx88_ctrl cx8800_aud_ctls[] = { .sreg = SHADOW_AUD_VOL_CTL, .mask = 0x3f, .shift = 0, - },{ + }, { .id = V4L2_CID_AUDIO_BALANCE, .minimum = 0, .maximum = 0x7f, @@ -304,10 +300,10 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) { /* struct cx88_core *core = dev->core; */ - dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", + dprintk(1, "video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", input, INPUT(input).vmux, - INPUT(input).gpio0,INPUT(input).gpio1, - INPUT(input).gpio2,INPUT(input).gpio3); + INPUT(input).gpio0, INPUT(input).gpio1, + INPUT(input).gpio2, INPUT(input).gpio3); core->input = input; cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input).vmux << 14); cx_write(MO_GP3_IO, INPUT(input).gpio3); @@ -374,7 +370,7 @@ static int start_video_dma(struct cx8800_dev *dev, cx_write(MO_COLOR_CTRL, dev->fmt->cxformat | ColorFormatGamma); /* reset counter */ - cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET); + cx_write(MO_VIDY_GPCNTRL, GP_COUNT_CONTROL_RESET); q->count = 0; /* enable irqs */ @@ -390,7 +386,7 @@ static int start_video_dma(struct cx8800_dev *dev, cx_set(MO_VID_INTMSK, 0x0f0011); /* enable capture */ - cx_set(VID_CAPTURE_CONTROL,0x06); + cx_set(VID_CAPTURE_CONTROL, 0x06); /* start dma */ cx_set(MO_DEV_CNTRL2, (1<<5)); @@ -408,7 +404,7 @@ static int stop_video_dma(struct cx8800_dev *dev) cx_clear(MO_VID_DMACNTRL, 0x11); /* disable capture */ - cx_clear(VID_CAPTURE_CONTROL,0x06); + cx_clear(VID_CAPTURE_CONTROL, 0x06); /* disable irqs */ cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT); @@ -423,7 +419,7 @@ static int restart_video_queue(struct cx8800_dev *dev, if (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, list); - dprintk(2,"restart_queue [%p/%d]: restart dma\n", + dprintk(2, "restart_queue [%p/%d]: restart dma\n", buf, buf->vb.vb2_buf.index); start_video_dma(dev, q, buf); } @@ -492,7 +488,7 @@ static int buffer_prepare(struct vb2_buffer *vb) core->height >> 1); break; } - dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", + dprintk(2, "[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", buf, buf->vb.vb2_buf.index, core->width, core->height, dev->fmt->depth, dev->fmt->name, (unsigned long)buf->risc.dma); @@ -526,7 +522,7 @@ static void buffer_queue(struct vb2_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->list, &q->active); - dprintk(2,"[%p/%d] buffer_queue - first active\n", + dprintk(2, "[%p/%d] buffer_queue - first active\n", buf, buf->vb.vb2_buf.index); } else { @@ -668,7 +664,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) struct cx88_core *core = container_of(ctrl->handler, struct cx88_core, audio_hdl); const struct cx88_ctrl *cc = ctrl->priv; - u32 value,mask; + u32 value, mask; /* Pass changes onto any WM8775 */ if (core->sd_wm8775) { @@ -700,7 +696,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; break; } - dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + dprintk(1, "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", ctrl->id, ctrl->name, ctrl->val, cc->reg, value, mask, cc->sreg ? " [shadowed]" : ""); if (cc->sreg) @@ -741,7 +737,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, unsigned int maxw, maxh; fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) + if (fmt == NULL) return -EINVAL; maxw = norm_maxw(core->tvnorm); @@ -782,9 +778,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - int err = vidioc_try_fmt_vid_cap (file,priv,f); + int err = vidioc_try_fmt_vid_cap(file, priv, f); - if (0 != err) + if (err != 0) return err; if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq)) return -EBUSY; @@ -804,7 +800,7 @@ void cx88_querycap(struct file *file, struct cx88_core *core, strlcpy(cap->card, core->board.name, sizeof(cap->card)); cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (UNSET != core->board.tuner_type) + if (core->board.tuner_type != UNSET) cap->device_caps |= V4L2_CAP_TUNER; switch (vdev->vfl_type) { case VFL_TYPE_RADIO: @@ -836,13 +832,13 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(formats))) return -EINVAL; - strlcpy(f->description,formats[f->index].name,sizeof(f->description)); + strlcpy(f->description, formats[f->index].name, sizeof(f->description)); f->pixelformat = formats[f->index].fourcc; return 0; @@ -866,18 +862,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) } /* only one input in this sample driver */ -int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) +int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i) { static const char * const iname[] = { - [ CX88_VMUX_COMPOSITE1 ] = "Composite1", - [ CX88_VMUX_COMPOSITE2 ] = "Composite2", - [ CX88_VMUX_COMPOSITE3 ] = "Composite3", - [ CX88_VMUX_COMPOSITE4 ] = "Composite4", - [ CX88_VMUX_SVIDEO ] = "S-Video", - [ CX88_VMUX_TELEVISION ] = "Television", - [ CX88_VMUX_CABLE ] = "Cable TV", - [ CX88_VMUX_DVB ] = "DVB", - [ CX88_VMUX_DEBUG ] = "for debug only", + [CX88_VMUX_COMPOSITE1] = "Composite1", + [CX88_VMUX_COMPOSITE2] = "Composite2", + [CX88_VMUX_COMPOSITE3] = "Composite3", + [CX88_VMUX_COMPOSITE4] = "Composite4", + [CX88_VMUX_SVIDEO] = "S-Video", + [CX88_VMUX_TELEVISION] = "Television", + [CX88_VMUX_CABLE] = "Cable TV", + [CX88_VMUX_DVB] = "DVB", + [CX88_VMUX_DEBUG] = "for debug only", }; unsigned int n = i->index; @@ -886,7 +882,7 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) if (0 == INPUT(n).type) return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name,iname[INPUT(n).type]); + strcpy(i->name, iname[INPUT(n).type]); if ((CX88_VMUX_TELEVISION == INPUT(n).type) || (CX88_VMUX_CABLE == INPUT(n).type)) { i->type = V4L2_INPUT_TYPE_TUNER; @@ -896,15 +892,16 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) } EXPORT_SYMBOL(cx88_enum_input); -static int vidioc_enum_input (struct file *file, void *priv, +static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - return cx88_enum_input (core,i); + + return cx88_enum_input(core, i); } -static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -913,7 +910,7 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) return 0; } -static int vidioc_s_input (struct file *file, void *priv, unsigned int i) +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -924,20 +921,20 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) return -EINVAL; cx88_newstation(core); - cx88_video_mux(core,i); + cx88_video_mux(core, i); return 0; } -static int vidioc_g_tuner (struct file *file, void *priv, +static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; u32 reg; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; - if (0 != t->index) + if (t->index != 0) return -EINVAL; strcpy(t->name, "Television"); @@ -945,34 +942,34 @@ static int vidioc_g_tuner (struct file *file, void *priv, t->rangehigh = 0xffffffffUL; call_all(core, tuner, g_tuner, t); - cx88_get_stereo(core ,t); + cx88_get_stereo(core, t); reg = cx_read(MO_DEVICE_STATUS); t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; return 0; } -static int vidioc_s_tuner (struct file *file, void *priv, +static int vidioc_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - if (UNSET == core->board.tuner_type) + if (core->board.tuner_type == UNSET) return -EINVAL; - if (0 != t->index) + if (t->index != 0) return -EINVAL; cx88_set_stereo(core, t->audmode, 1); return 0; } -static int vidioc_g_frequency (struct file *file, void *priv, +static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; if (f->tuner) return -EINVAL; @@ -984,12 +981,12 @@ static int vidioc_g_frequency (struct file *file, void *priv, return 0; } -int cx88_set_freq (struct cx88_core *core, +int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f) { struct v4l2_frequency new_freq = *f; - if (unlikely(UNSET == core->board.tuner_type)) + if (unlikely(core->board.tuner_type == UNSET)) return -EINVAL; if (unlikely(f->tuner != 0)) return -EINVAL; @@ -1000,14 +997,14 @@ int cx88_set_freq (struct cx88_core *core, core->freq = new_freq.frequency; /* When changing channels it is required to reset TVAUDIO */ - msleep (10); + usleep_range(10000, 20000); cx88_set_tvaudio(core); return 0; } EXPORT_SYMBOL(cx88_set_freq); -static int vidioc_s_frequency (struct file *file, void *priv, +static int vidioc_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { struct cx8800_dev *dev = video_drvdata(file); @@ -1017,7 +1014,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register (struct file *file, void *fh, +static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct cx8800_dev *dev = video_drvdata(file); @@ -1029,7 +1026,7 @@ static int vidioc_g_register (struct file *file, void *fh, return 0; } -static int vidioc_s_register (struct file *file, void *fh, +static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) { struct cx8800_dev *dev = video_drvdata(file); @@ -1044,7 +1041,7 @@ static int vidioc_s_register (struct file *file, void *fh, /* RADIO ESPECIFIC IOCTLS */ /* ----------------------------------------------------------- */ -static int radio_g_tuner (struct file *file, void *priv, +static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); @@ -1059,13 +1056,13 @@ static int radio_g_tuner (struct file *file, void *priv, return 0; } -static int radio_s_tuner (struct file *file, void *priv, +static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - if (0 != t->index) + if (t->index != 0) return -EINVAL; call_all(core, tuner, s_tuner, t); @@ -1132,19 +1129,19 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) for (loop = 0; loop < 10; loop++) { status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | PCI_INT_VIDINT); - if (0 == status) + if (status == 0) goto out; cx_write(MO_PCI_INTSTAT, status); handled = 1; if (status & core->pci_irqmask) - cx88_core_irq(core,status); + cx88_core_irq(core, status); if (status & PCI_INT_VIDINT) cx8800_vid_irq(dev); } - if (10 == loop) { + if (loop == 10) { pr_warn("irq loop -- clearing mask\n"); - cx_write(MO_PCI_INTMSK,0); + cx_write(MO_PCI_INTMSK, 0); } out: @@ -1154,8 +1151,8 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) /* ----------------------------------------------------------- */ /* exported stuff */ -static const struct v4l2_file_operations video_fops = -{ +static const struct v4l2_file_operations video_fops = { + .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, @@ -1197,7 +1194,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct video_device cx8800_video_template = { .name = "cx8800-video", .fops = &video_fops, - .ioctl_ops = &video_ioctl_ops, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX88_NORMS, }; @@ -1234,8 +1231,8 @@ static const struct video_device cx8800_vbi_template = { .tvnorms = CX88_NORMS, }; -static const struct v4l2_file_operations radio_fops = -{ +static const struct v4l2_file_operations radio_fops = { + .owner = THIS_MODULE, .open = radio_open, .poll = v4l2_ctrl_poll, @@ -1260,7 +1257,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static const struct video_device cx8800_radio_template = { .name = "cx8800-radio", .fops = &radio_fops, - .ioctl_ops = &radio_ioctl_ops, + .ioctl_ops = &radio_ioctl_ops, }; static const struct v4l2_ctrl_ops cx8800_ctrl_vid_ops = { @@ -1289,8 +1286,8 @@ static int cx8800_initdev(struct pci_dev *pci_dev, int err; int i; - dev = kzalloc(sizeof(*dev),GFP_KERNEL); - if (NULL == dev) + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) return -ENOMEM; /* pci init */ @@ -1300,7 +1297,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_free; } core = cx88_core_get(dev->pci); - if (NULL == core) { + if (core == NULL) { err = -EINVAL; goto fail_free; } @@ -1315,7 +1312,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, (unsigned long long)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); - err = pci_set_dma_mask(pci_dev,DMA_BIT_MASK(32)); + err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); if (err) { pr_err("Oops: no 32bit PCI DMA ???\n"); goto fail_core; @@ -1524,7 +1521,7 @@ fail_unreg: mutex_unlock(&core->lock); fail_core: core->v4ldev = NULL; - cx88_core_put(core,dev->pci); + cx88_core_put(core, dev->pci); fail_free: kfree(dev); return err; @@ -1555,7 +1552,7 @@ static void cx8800_finidev(struct pci_dev *pci_dev) core->v4ldev = NULL; /* free memory */ - cx88_core_put(core,dev->pci); + cx88_core_put(core, dev->pci); kfree(dev); } @@ -1584,7 +1581,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(core); pci_save_state(pci_dev); - if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { + if (pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)) != 0) { pci_disable_device(pci_dev); dev->state.disabled = 1; } @@ -1599,7 +1596,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) int err; if (dev->state.disabled) { - err=pci_enable_device(pci_dev); + err = pci_enable_device(pci_dev); if (err) { pr_err("can't enable device\n"); return err; @@ -1607,7 +1604,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) dev->state.disabled = 0; } - err= pci_set_power_state(pci_dev, PCI_D0); + err = pci_set_power_state(pci_dev, PCI_D0); if (err) { pr_err("can't set power state\n"); pci_disable_device(pci_dev); @@ -1628,11 +1625,11 @@ static int cx8800_resume(struct pci_dev *pci_dev) spin_lock_irqsave(&dev->slock, flags); if (!list_empty(&dev->vidq.active)) { pr_info("resume video\n"); - restart_video_queue(dev,&dev->vidq); + restart_video_queue(dev, &dev->vidq); } if (!list_empty(&dev->vbiq.active)) { pr_info("resume vbi\n"); - cx8800_restart_vbi_queue(dev,&dev->vbiq); + cx8800_restart_vbi_queue(dev, &dev->vbiq); } spin_unlock_irqrestore(&dev->slock, flags); @@ -1648,7 +1645,7 @@ static const struct pci_device_id cx8800_pci_tbl[] = { .device = 0x8800, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - },{ + }, { /* --- end of list --- */ } }; diff --git a/drivers/media/pci/cx88/cx88-vp3054-i2c.c b/drivers/media/pci/cx88/cx88-vp3054-i2c.c index 4f47ea2ae344..eea56ae9071e 100644 --- a/drivers/media/pci/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.c @@ -1,26 +1,20 @@ /* - - cx88-vp3054-i2c.c -- support for the secondary I2C bus of the - DNTV Live! DVB-T Pro (VP-3054), wired as: - GPIO[0] -> SCL, GPIO[1] -> SDA - - (c) 2005 Chris Pascoe - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ + * cx88-vp3054-i2c.c -- support for the secondary I2C bus of the + * DNTV Live! DVB-T Pro (VP-3054), wired as: + * GPIO[0] -> SCL, GPIO[1] -> SDA + * + * (c) 2005 Chris Pascoe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "cx88.h" #include "cx88-vp3054-i2c.h" @@ -128,11 +122,11 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) i2c_set_adapdata(&vp3054_i2c->adap, dev); vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; - vp3054_bit_setscl(dev,1); - vp3054_bit_setsda(dev,1); + vp3054_bit_setscl(dev, 1); + vp3054_bit_setsda(dev, 1); rc = i2c_bit_add_bus(&vp3054_i2c->adap); - if (0 != rc) { + if (rc != 0) { pr_err("vp3054_i2c register FAILED\n"); kfree(dev->vp3054); diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 01c1287baf93..ac1fb9fb340e 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -13,10 +13,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CX88_H @@ -58,7 +54,7 @@ /* defines and enums */ /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM/LC */ -#define CX88_NORMS (V4L2_STD_ALL \ +#define CX88_NORMS (V4L2_STD_ALL \ & ~V4L2_STD_PAL_H \ & ~V4L2_STD_NTSC_M_KR \ & ~V4L2_STD_SECAM_LC) @@ -366,12 +362,12 @@ struct cx88_core { u32 i2c_state, i2c_rc; /* config info -- analog */ - struct v4l2_device v4l2_dev; + struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler video_hdl; struct v4l2_ctrl *chroma_agc; struct v4l2_ctrl_handler audio_hdl; struct v4l2_subdev *sd_wm8775; - struct i2c_client *i2c_rtc; + struct i2c_client *i2c_rtc; unsigned int boardnr; struct cx88_board board; @@ -388,8 +384,8 @@ struct cx88_core { /* state info */ struct task_struct *kthread; v4l2_std_id tvnorm; - unsigned width, height; - unsigned field; + unsigned int width, height; + unsigned int field; enum cx88_tvaudio tvaudio; u32 audiomode_manual; u32 audiomode_current; @@ -489,7 +485,7 @@ struct cx8800_dev { /* pci i/o */ struct pci_dev *pci; - unsigned char pci_rev,pci_lat; + unsigned char pci_rev, pci_lat; const struct cx8800_fmt *fmt; @@ -552,7 +548,7 @@ struct cx8802_dev { /* pci i/o */ struct pci_dev *pci; - unsigned char pci_rev,pci_lat; + unsigned char pci_rev, pci_lat; /* dma queues */ struct cx88_dmaqueue mpegq; @@ -594,23 +590,23 @@ struct cx8802_dev { /* ----------------------------------------------------------- */ #define cx_read(reg) readl(core->lmmio + ((reg)>>2)) -#define cx_write(reg,value) writel((value), core->lmmio + ((reg)>>2)) -#define cx_writeb(reg,value) writeb((value), core->bmmio + (reg)) +#define cx_write(reg, value) writel((value), core->lmmio + ((reg)>>2)) +#define cx_writeb(reg, value) writeb((value), core->bmmio + (reg)) -#define cx_andor(reg,mask,value) \ +#define cx_andor(reg, mask, value) \ writel((readl(core->lmmio+((reg)>>2)) & ~(mask)) |\ ((value) & (mask)), core->lmmio+((reg)>>2)) -#define cx_set(reg,bit) cx_andor((reg),(bit),(bit)) -#define cx_clear(reg,bit) cx_andor((reg),(bit),0) +#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) +#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) #define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); } /* shadow registers */ #define cx_sread(sreg) (core->shadow[sreg]) -#define cx_swrite(sreg,reg,value) \ +#define cx_swrite(sreg, reg, value) \ (core->shadow[sreg] = value, \ writel(core->shadow[sreg], core->lmmio + ((reg)>>2))) -#define cx_sandor(sreg,reg,mask,value) \ +#define cx_sandor(sreg, reg, mask, value) \ (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | ((value) & (mask)), \ writel(core->shadow[sreg], core->lmmio + ((reg)>>2))) @@ -667,7 +663,7 @@ extern int cx88_stop_audio_dma(struct cx88_core *core); /* cx88-vbi.c */ /* Can be used as g_vbi_fmt, try_vbi_fmt and s_vbi_fmt */ -int cx8800_vbi_fmt (struct file *file, void *priv, +int cx8800_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f); /* @@ -708,7 +704,8 @@ int cx8802_register_driver(struct cx8802_driver *drv); int cx8802_unregister_driver(struct cx8802_driver *drv); /* Caller must hold core->lock */ -struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); +struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, + enum cx88_board_type btype); /* ----------------------------------------------------------- */ /* cx88-dsp.c */ -- cgit v1.2.3 From 7c66e12136c2fa421ae75497e02728f252108a1b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:14:37 -0300 Subject: [media] pluto2: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pluto2/pluto2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c index 655d6854a8d7..65afb71ff79f 100644 --- a/drivers/media/pci/pluto2/pluto2.c +++ b/drivers/media/pci/pluto2/pluto2.c @@ -577,12 +577,12 @@ static int pluto_read_serial(struct pluto *pluto) for (j = 0; j < 32; j += 8) { if ((val & 0xff) == 0xff) goto out; - printk("%c", val & 0xff); + printk(KERN_CONT "%c", val & 0xff); val >>= 8; } } out: - printk("\n"); + printk(KERN_CONT "\n"); pci_iounmap(pdev, cis); return 0; -- cgit v1.2.3 From 623b2f4a67f9539b1c9fef0fa4e118c5349a2753 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:27:36 -0300 Subject: [media] zoran: use KERN_CONT where needed Some continuation messages are not using KERN_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/zoran/zoran_device.c | 35 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/media/pci/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c index 4d47ddac97dc..35b552c178da 100644 --- a/drivers/media/pci/zoran/zoran_device.c +++ b/drivers/media/pci/zoran/zoran_device.c @@ -173,12 +173,8 @@ dump_guests (struct zoran *zr) guest[i] = post_office_read(zr, i, 0); } - printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); - - for (i = 1; i < 8; i++) { - printk(" 0x%02x", guest[i]); - } - printk("\n"); + printk(KERN_INFO "%s: Guests: %*ph\n", + ZR_DEVNAME(zr), 8, guest); } } @@ -216,12 +212,9 @@ detect_guest_activity (struct zoran *zr) if (j >= 8) break; } - printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr)); - for (i = 1; i < 8; i++) { - printk(" 0x%02x", guest0[i]); - } - printk("\n"); + printk(KERN_INFO "%s: Guests: %*ph\n", ZR_DEVNAME(zr), 8, guest0); + if (j == 0) { printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr)); return; @@ -822,39 +815,39 @@ print_interrupts (struct zoran *zr) printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); if ((res = zr->field_counter) < -1 || res > 1) { - printk(" FD:%d", res); + printk(KERN_CONT " FD:%d", res); } if ((res = zr->intr_counter_GIRQ1) != 0) { - printk(" GIRQ1:%d", res); + printk(KERN_CONT " GIRQ1:%d", res); noerr++; } if ((res = zr->intr_counter_GIRQ0) != 0) { - printk(" GIRQ0:%d", res); + printk(KERN_CONT " GIRQ0:%d", res); noerr++; } if ((res = zr->intr_counter_CodRepIRQ) != 0) { - printk(" CodRepIRQ:%d", res); + printk(KERN_CONT " CodRepIRQ:%d", res); noerr++; } if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { - printk(" JPEGRepIRQ:%d", res); + printk(KERN_CONT " JPEGRepIRQ:%d", res); noerr++; } if (zr->JPEG_max_missed) { - printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed, + printk(KERN_CONT " JPEG delays: max=%d min=%d", zr->JPEG_max_missed, zr->JPEG_min_missed); } if (zr->END_event_missed) { - printk(" ENDs missed: %d", zr->END_event_missed); + printk(KERN_CONT " ENDs missed: %d", zr->END_event_missed); } //if (zr->jpg_queued_num) { - printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, + printk(KERN_CONT " queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); //} if (!noerr) { - printk(": no interrupts detected."); + printk(KERN_CONT ": no interrupts detected."); } - printk("\n"); + printk(KERN_CONT "\n"); } void -- cgit v1.2.3 From ac2ac8376eae2c7c7abb90732c967942510410b4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:33:00 -0300 Subject: [media] wl128x: use KERNEL_CONT where needed Some continuation messages are not using KERNEL_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/wl128x/fmdrv_common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 6f254e80ffa6..4be07656fbc0 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -212,14 +212,14 @@ inline void dump_tx_skb_data(struct sk_buff *skb) len_org = skb->len - FM_CMD_MSG_HDR_SIZE; if (len_org > 0) { - printk("\n data(%d): ", cmd_hdr->dlen); + printk(KERN_CONT "\n data(%d): ", cmd_hdr->dlen); len = min(len_org, 14); for (index = 0; index < len; index++) - printk("%x ", + printk(KERN_CONT "%x ", skb->data[FM_CMD_MSG_HDR_SIZE + index]); - printk("%s", (len_org > 14) ? ".." : ""); + printk(KERN_CONT "%s", (len_org > 14) ? ".." : ""); } - printk("\n"); + printk(KERN_CONT "\n"); } /* To dump incoming FM Channel-8 packets */ @@ -237,14 +237,14 @@ inline void dump_rx_skb_data(struct sk_buff *skb) len_org = skb->len - FM_EVT_MSG_HDR_SIZE; if (len_org > 0) { - printk("\n data(%d): ", evt_hdr->dlen); + printk(KERN_CONT "\n data(%d): ", evt_hdr->dlen); len = min(len_org, 14); for (index = 0; index < len; index++) - printk("%x ", + printk(KERN_CONT "%x ", skb->data[FM_EVT_MSG_HDR_SIZE + index]); - printk("%s", (len_org > 14) ? ".." : ""); + printk(KERN_CONT "%s", (len_org > 14) ? ".." : ""); } - printk("\n"); + printk(KERN_CONT "\n"); } #endif -- cgit v1.2.3 From 6dc3a355633b97c03950478563807ab72b18f94b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:39:46 -0300 Subject: [media] pvrusb2: use KERNEL_CONT where needed Some continuation messages are not using KERNEL_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c index 48d837e39a9c..cc63e5f4c26c 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c @@ -491,18 +491,18 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, "read" : "write")); if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { if (cnt > 8) cnt = 8; - printk(" ["); + printk(KERN_CONT " ["); for (offs = 0; offs < (cnt>8?8:cnt); offs++) { - if (offs) printk(" "); - printk("%02x",msgs[idx].buf[offs]); + if (offs) printk(KERN_CONT " "); + printk(KERN_CONT "%02x",msgs[idx].buf[offs]); } - if (offs < cnt) printk(" ..."); - printk("]"); + if (offs < cnt) printk(KERN_CONT " ..."); + printk(KERN_CONT "]"); } if (idx+1 == num) { - printk(" result=%d",ret); + printk(KERN_CONT " result=%d",ret); } - printk("\n"); + printk(KERN_CONT "\n"); } if (!num) { printk(KERN_INFO -- cgit v1.2.3 From 61fc87498bc6a5becd30162e23928168b1e32318 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:44:05 -0300 Subject: [media] ttusb_dec: use KERNEL_CONT where needed Some continuation messages are not using KERNEL_CONT. Since commit 563873318d32 ("Merge branch 'printk-cleanups"), this won't work as expected anymore. So, let's add KERN_CONT to those lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 559c823a4fe8..fc0219f1b7df 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -329,7 +329,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, int param_length, const u8 params[], int *result_length, u8 cmd_result[]) { - int result, actual_len, i; + int result, actual_len; u8 *b; dprintk("%s\n", __func__); @@ -353,10 +353,8 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, memcpy(&b[4], params, param_length); if (debug) { - printk("%s: command: ", __func__); - for (i = 0; i < param_length + 4; i++) - printk("0x%02X ", b[i]); - printk("\n"); + printk(KERN_DEBUG "%s: command: %*ph\n", + __func__, param_length, b); } result = usb_bulk_msg(dec->udev, dec->command_pipe, b, @@ -381,10 +379,8 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, return result; } else { if (debug) { - printk("%s: result: ", __func__); - for (i = 0; i < actual_len; i++) - printk("0x%02X ", b[i]); - printk("\n"); + printk(KERN_DEBUG "%s: result: %*ph\n", + __func__, actual_len, b); } if (result_length) -- cgit v1.2.3 From a80e1d965cb9a77f20a493021e816761f8785faf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 07:58:43 -0300 Subject: [media] ttpci: cleanup debug macros and remove dead code Continuation lines without KERN_CONT won't work anymore. However, the way dprintk() was defined leads to the usage of continuation lines, with should be avoided when possible. So, redefine those macros. While hre, remove some dead code at av7110.c with also relies on continuation lines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/av7110.c | 15 --------------- drivers/media/pci/ttpci/av7110.h | 7 +++++-- drivers/media/pci/ttpci/budget.h | 8 ++++++-- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 37e7e6684e3c..6e63949d6ad0 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -443,21 +443,6 @@ static void debiirq(unsigned long cookie) case DATA_COMMON_INTERFACE: CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen); -#if 0 - { - int i; - - printk("av7110%d: ", av7110->num); - printk("%02x ", *(u8 *)av7110->debi_virt); - printk("%02x ", *(1+(u8 *)av7110->debi_virt)); - for (i = 2; i < av7110->debilen; i++) - printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt))); - for (i = 2; i < av7110->debilen; i++) - printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt))); - - printk("\n"); - } -#endif xfer = RX_BUFF; break; diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index 3707ccd02732..824c1e262fbb 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h @@ -40,8 +40,11 @@ extern int av7110_debug; -#define dprintk(level,args...) \ - do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0) +#define dprintk(level, fmt, arg...) do { \ + if (level & av7110_debug) \ + printk(KERN_DEBUG KBUILD_MODNAME ": %s(): " fmt, \ + __func__, ##arg); \ +} while (0) #define MAXFILT 32 diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h index 655eef5236ca..d5ae4438153e 100644 --- a/drivers/media/pci/ttpci/budget.h +++ b/drivers/media/pci/ttpci/budget.h @@ -21,8 +21,12 @@ extern int budget_debug; #undef dprintk #endif -#define dprintk(level,args...) \ - do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0) +#define dprintk(level, fmt, arg...) do { \ + if (level & budget_debug) \ + printk(KERN_DEBUG KBUILD_MODNAME ": %s(): " fmt, \ + __func__, ##arg); \ +} while (0) + struct budget_info { char *name; -- cgit v1.2.3 From fb11cbd1a9b84ee008c759a6075717f9273a2b3c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 08:10:15 -0300 Subject: [media] dib0070: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0070.c | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c index ee7d66997ccd..016ad09a8754 100644 --- a/drivers/media/dvb-frontends/dib0070.c +++ b/drivers/media/dvb-frontends/dib0070.c @@ -24,6 +24,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -38,12 +40,10 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { \ - if (debug) { \ - printk(KERN_DEBUG "DiB0070: "); \ - printk(args); \ - printk("\n"); \ - } \ +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ } while (0) #define DIB0070_P1D 0x00 @@ -87,7 +87,7 @@ static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -104,7 +104,7 @@ static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg) state->msg[1].len = 2; if (i2c_transfer(state->i2c, state->msg, 2) != 2) { - printk(KERN_WARNING "DiB0070 I2C read failed\n"); + pr_warn("DiB0070 I2C read failed\n"); ret = 0; } else ret = (state->i2c_read_buffer[0] << 8) @@ -119,7 +119,7 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } state->i2c_write_buffer[0] = reg; @@ -133,7 +133,7 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) state->msg[0].len = 3; if (i2c_transfer(state->i2c, state->msg, 1) != 1) { - printk(KERN_WARNING "DiB0070 I2C write failed\n"); + pr_warn("DiB0070 I2C write failed\n"); ret = -EREMOTEIO; } else ret = 0; @@ -205,7 +205,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state adc = dib0070_read_reg(state, 0x19); - dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024); + dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV\n", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024); if (adc >= 400) { adc -= 400; @@ -216,7 +216,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state } if (adc < state->adc_diff) { - dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); + dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)\n", state->captrim, adc, state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; } @@ -241,7 +241,7 @@ static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf struct dib0070_state *state = fe->tuner_priv; u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); - dprintk("CTRL_LO5: 0x%x", lo5); + dprintk("CTRL_LO5: 0x%x\n", lo5); return dib0070_write_reg(state, 0x15, lo5); } @@ -256,7 +256,7 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) dib0070_write_reg(state, 0x1b, 0x4112); if (state->cfg->vga_filter != 0) { dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); - dprintk("vga filter register is set to %x", state->cfg->vga_filter); + dprintk("vga filter register is set to %x\n", state->cfg->vga_filter); } else dib0070_write_reg(state, 0x1a, 0x0009); } @@ -380,7 +380,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe) } if (*tune_state == CT_TUNER_START) { - dprintk("Tuning for Band: %hd (%d kHz)", band, freq); + dprintk("Tuning for Band: %hd (%d kHz)\n", band, freq); if (state->current_rf != freq) { u8 REFDIV; u32 FBDiv, Rest, FREF, VCOF_kHz; @@ -458,12 +458,12 @@ static int dib0070_tune_digital(struct dvb_frontend *fe) dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); - dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); - dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); - dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); - dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); - dprintk("VCO = %hd", state->current_tune_table_index->vco_band); - dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); + dprintk("REFDIV: %hd, FREF: %d\n", REFDIV, FREF); + dprintk("FBDIV: %d, Rest: %d\n", FBDiv, Rest); + dprintk("Num: %hd, Den: %hd, SD: %hd\n", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); + dprintk("HFDIV code: %hd\n", state->current_tune_table_index->hfdiv); + dprintk("VCO = %hd\n", state->current_tune_table_index->vco_band); + dprintk("VCOF: ((%hd*%d) << 1))\n", state->current_tune_table_index->vco_multi, freq); *tune_state = CT_TUNER_STEP_0; } else { /* we are already tuned to this frequency - the configuration is correct */ @@ -625,7 +625,7 @@ static void dib0070_wbd_offset_calibration(struct dib0070_state *state) u8 gain; for (gain = 6; gain < 8; gain++) { state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); - dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); + dprintk("Gain: %d, WBDOffset (3.3V) = %hd\n", gain, state->wbd_offset_3_3[gain-6]); } } @@ -665,10 +665,10 @@ static int dib0070_reset(struct dvb_frontend *fe) state->revision = DIB0070S_P1A; /* P1F or not */ - dprintk("Revision: %x", state->revision); + dprintk("Revision: %x\n", state->revision); if (state->revision == DIB0070_P1D) { - dprintk("Error: this driver is not to be used meant for P1D or earlier"); + dprintk("Error: this driver is not to be used meant for P1D or earlier\n"); return -EINVAL; } @@ -761,7 +761,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter if (dib0070_reset(fe) != 0) goto free_mem; - printk(KERN_INFO "DiB0070: successfully identified\n"); + pr_info("DiB0070: successfully identified\n"); memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); fe->tuner_priv = state; -- cgit v1.2.3 From 4bd1a8ddadfbfaea1cb4b5f9fc7004958a043f45 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 08:16:43 -0300 Subject: [media] dib0090: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0090.c | 162 +++++++++++++++++----------------- 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 14c403254fe0..16200582f089 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -24,6 +24,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -38,12 +40,10 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { \ - if (debug) { \ - printk(KERN_DEBUG "DiB0090: "); \ - printk(args); \ - printk("\n"); \ - } \ +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ } while (0) #define CONFIG_SYS_DVBT @@ -218,7 +218,7 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -235,7 +235,7 @@ static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) state->msg[1].len = 2; if (i2c_transfer(state->i2c, state->msg, 2) != 2) { - printk(KERN_WARNING "DiB0090 I2C read failed\n"); + pr_warn("DiB0090 I2C read failed\n"); ret = 0; } else ret = (state->i2c_read_buffer[0] << 8) @@ -250,7 +250,7 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -265,7 +265,7 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) state->msg[0].len = 3; if (i2c_transfer(state->i2c, state->msg, 1) != 1) { - printk(KERN_WARNING "DiB0090 I2C write failed\n"); + pr_warn("DiB0090 I2C write failed\n"); ret = -EREMOTEIO; } else ret = 0; @@ -279,7 +279,7 @@ static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -291,7 +291,7 @@ static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) state->msg.buf = state->i2c_read_buffer; state->msg.len = 2; if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { - printk(KERN_WARNING "DiB0090 I2C read failed\n"); + pr_warn("DiB0090 I2C read failed\n"); ret = 0; } else ret = (state->i2c_read_buffer[0] << 8) @@ -306,7 +306,7 @@ static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -319,7 +319,7 @@ static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) state->msg.buf = state->i2c_write_buffer; state->msg.len = 2; if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { - printk(KERN_WARNING "DiB0090 I2C write failed\n"); + pr_warn("DiB0090 I2C write failed\n"); ret = -EREMOTEIO; } else ret = 0; @@ -351,7 +351,7 @@ static int dib0090_identify(struct dvb_frontend *fe) identity->p1g = 0; identity->in_soc = 0; - dprintk("Tuner identification (Version = 0x%04x)", v); + dprintk("Tuner identification (Version = 0x%04x)\n", v); /* without PLL lock info */ v &= ~KROSUS_PLL_LOCKED; @@ -366,19 +366,19 @@ static int dib0090_identify(struct dvb_frontend *fe) identity->in_soc = 1; switch (identity->version) { case SOC_8090_P1G_11R1: - dprintk("SOC 8090 P1-G11R1 Has been detected"); + dprintk("SOC 8090 P1-G11R1 Has been detected\n"); identity->p1g = 1; break; case SOC_8090_P1G_21R1: - dprintk("SOC 8090 P1-G21R1 Has been detected"); + dprintk("SOC 8090 P1-G21R1 Has been detected\n"); identity->p1g = 1; break; case SOC_7090_P1G_11R1: - dprintk("SOC 7090 P1-G11R1 Has been detected"); + dprintk("SOC 7090 P1-G11R1 Has been detected\n"); identity->p1g = 1; break; case SOC_7090_P1G_21R1: - dprintk("SOC 7090 P1-G21R1 Has been detected"); + dprintk("SOC 7090 P1-G21R1 Has been detected\n"); identity->p1g = 1; break; default: @@ -387,16 +387,16 @@ static int dib0090_identify(struct dvb_frontend *fe) } else { switch ((identity->version >> 5) & 0x7) { case MP001: - dprintk("MP001 : 9090/8096"); + dprintk("MP001 : 9090/8096\n"); break; case MP005: - dprintk("MP005 : Single Sband"); + dprintk("MP005 : Single Sband\n"); break; case MP008: - dprintk("MP008 : diversity VHF-UHF-LBAND"); + dprintk("MP008 : diversity VHF-UHF-LBAND\n"); break; case MP009: - dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND"); + dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n"); break; default: goto identification_error; @@ -404,21 +404,21 @@ static int dib0090_identify(struct dvb_frontend *fe) switch (identity->version & 0x1f) { case P1G_21R2: - dprintk("P1G_21R2 detected"); + dprintk("P1G_21R2 detected\n"); identity->p1g = 1; break; case P1G: - dprintk("P1G detected"); + dprintk("P1G detected\n"); identity->p1g = 1; break; case P1D_E_F: - dprintk("P1D/E/F detected"); + dprintk("P1D/E/F detected\n"); break; case P1C: - dprintk("P1C detected"); + dprintk("P1C detected\n"); break; case P1A_B: - dprintk("P1-A/B detected: driver is deactivated - not available"); + dprintk("P1-A/B detected: driver is deactivated - not available\n"); goto identification_error; break; default: @@ -441,7 +441,7 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) identity->p1g = 0; identity->in_soc = 0; - dprintk("FE: Tuner identification (Version = 0x%04x)", v); + dprintk("FE: Tuner identification (Version = 0x%04x)\n", v); /* without PLL lock info */ v &= ~KROSUS_PLL_LOCKED; @@ -456,19 +456,19 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) identity->in_soc = 1; switch (identity->version) { case SOC_8090_P1G_11R1: - dprintk("SOC 8090 P1-G11R1 Has been detected"); + dprintk("SOC 8090 P1-G11R1 Has been detected\n"); identity->p1g = 1; break; case SOC_8090_P1G_21R1: - dprintk("SOC 8090 P1-G21R1 Has been detected"); + dprintk("SOC 8090 P1-G21R1 Has been detected\n"); identity->p1g = 1; break; case SOC_7090_P1G_11R1: - dprintk("SOC 7090 P1-G11R1 Has been detected"); + dprintk("SOC 7090 P1-G11R1 Has been detected\n"); identity->p1g = 1; break; case SOC_7090_P1G_21R1: - dprintk("SOC 7090 P1-G21R1 Has been detected"); + dprintk("SOC 7090 P1-G21R1 Has been detected\n"); identity->p1g = 1; break; default: @@ -477,16 +477,16 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) } else { switch ((identity->version >> 5) & 0x7) { case MP001: - dprintk("MP001 : 9090/8096"); + dprintk("MP001 : 9090/8096\n"); break; case MP005: - dprintk("MP005 : Single Sband"); + dprintk("MP005 : Single Sband\n"); break; case MP008: - dprintk("MP008 : diversity VHF-UHF-LBAND"); + dprintk("MP008 : diversity VHF-UHF-LBAND\n"); break; case MP009: - dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND"); + dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n"); break; default: goto identification_error; @@ -494,21 +494,21 @@ static int dib0090_fw_identify(struct dvb_frontend *fe) switch (identity->version & 0x1f) { case P1G_21R2: - dprintk("P1G_21R2 detected"); + dprintk("P1G_21R2 detected\n"); identity->p1g = 1; break; case P1G: - dprintk("P1G detected"); + dprintk("P1G detected\n"); identity->p1g = 1; break; case P1D_E_F: - dprintk("P1D/E/F detected"); + dprintk("P1D/E/F detected\n"); break; case P1C: - dprintk("P1C detected"); + dprintk("P1C detected\n"); break; case P1A_B: - dprintk("P1-A/B detected: driver is deactivated - not available"); + dprintk("P1-A/B detected: driver is deactivated - not available\n"); goto identification_error; break; default: @@ -574,7 +574,7 @@ static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_ } while (--i); if (i == 0) { - dprintk("Pll: Unable to lock Pll"); + dprintk("Pll: Unable to lock Pll\n"); return; } @@ -596,7 +596,7 @@ static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib009 u16 v; int i; - dprintk("fw reset digital"); + dprintk("fw reset digital\n"); HARD_RESET(state); dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL); @@ -645,7 +645,7 @@ static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib009 } while (--i); if (i == 0) { - dprintk("Pll: Unable to lock Pll"); + dprintk("Pll: Unable to lock Pll\n"); return -EIO; } @@ -922,7 +922,7 @@ static void dib0090_wbd_target(struct dib0090_state *state, u32 rf) #endif state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset); - dprintk("wbd-target: %d dB", (u32) state->wbd_target); + dprintk("wbd-target: %d dB\n", (u32) state->wbd_target); } static const int gain_reg_addr[4] = { @@ -1019,7 +1019,7 @@ static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 gain_reg[3] |= ((bb % 10) * 100) / 125; #ifdef DEBUG_AGC - dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb, + dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb, gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]); #endif @@ -1050,7 +1050,7 @@ static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg) dib0090_write_reg(state, 0x2a, 0xffff); - dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); + dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); dib0090_write_regs(state, 0x2c, cfg + 3, 6); dib0090_write_regs(state, 0x3e, cfg + 9, 2); @@ -1069,7 +1069,7 @@ static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg) dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ dib0090_write_reg(state, 0x33, 0xffff); - dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33)); + dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33)); dib0090_write_regs(state, 0x35, cfg + 3, 4); } @@ -1122,7 +1122,7 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) /* activate the ramp generator using PWM control */ if (state->rf_ramp) - dprintk("ramp RF gain = %d BAND = %s version = %d", + dprintk("ramp RF gain = %d BAND = %s version = %d\n", state->rf_ramp[0], (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND", state->identity.version & 0x1f); @@ -1130,10 +1130,10 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) || (state->current_band == BAND_CBAND && (state->identity.version & 0x1f) <= P1D_E_F))) { - dprintk("DE-Engage mux for direct gain reg control"); + dprintk("DE-Engage mux for direct gain reg control\n"); en_pwm_rf_mux = 0; } else - dprintk("Engage mux for PWM control"); + dprintk("Engage mux for PWM control\n"); dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11)); @@ -1352,7 +1352,7 @@ u16 dib0090_get_wbd_target(struct dvb_frontend *fe) while (f_MHz > wbd->max_freq) wbd++; - dprintk("using wbd-table-entry with max freq %d", wbd->max_freq); + dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq); if (current_temp < 0) current_temp = 0; @@ -1373,8 +1373,8 @@ u16 dib0090_get_wbd_target(struct dvb_frontend *fe) wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7; state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold); - dprintk("wbd-target: %d dB", (u32) state->wbd_target); - dprintk("wbd offset applied is %d", wbd_tcold); + dprintk("wbd-target: %d dB\n", (u32) state->wbd_target); + dprintk("wbd offset applied is %d\n", wbd_tcold); return state->wbd_offset + wbd_tcold; } @@ -1415,7 +1415,7 @@ int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity) if ((!state->identity.p1g) || (!state->identity.in_soc) || ((state->identity.version != SOC_7090_P1G_21R1) && (state->identity.version != SOC_7090_P1G_11R1))) { - dprintk("%s() function can only be used for dib7090P", __func__); + dprintk("%s() function can only be used for dib7090P\n", __func__); return -ENODEV; } @@ -1598,7 +1598,7 @@ static int dib0090_reset(struct dvb_frontend *fe) dib0090_write_reg(state, 0x14, 1); else dib0090_write_reg(state, 0x14, 2); - dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); + dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ @@ -1711,7 +1711,8 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front /* fall through */ case CT_TUNER_STEP_0: - dprintk("Start/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q"); + dprintk("Start/continue DC calibration for %s path\n", + (state->dc->i == 1) ? "I" : "Q"); dib0090_write_reg(state, 0x01, state->dc->bb1); dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); @@ -1733,13 +1734,13 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front break; case CT_TUNER_STEP_5: /* found an offset */ - dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step); + dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step); if (state->step == 0 && state->adc_diff < 0) { state->min_adc_diff = -1023; - dprintk("Change of sign of the minimum adc diff"); + dprintk("Change of sign of the minimum adc diff\n"); } - dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step); + dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step); /* first turn for this frequency */ if (state->step == 0) { @@ -1758,12 +1759,12 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front } else { /* the minimum was what we have seen in the step before */ if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) { - dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff); + dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff); state->step--; } dib0090_set_trim(state); - dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step); + dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step); state->dc++; if (state->dc->addr == 0) /* done */ @@ -1819,7 +1820,7 @@ static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tu case CT_TUNER_STEP_0: state->wbd_offset = dib0090_get_slow_adc_val(state); - dprintk("WBD calibration offset = %d", state->wbd_offset); + dprintk("WBD calibration offset = %d\n", state->wbd_offset); *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ state->calibrate &= ~WBD_CAL; break; @@ -2064,7 +2065,7 @@ int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, if ((!state->identity.p1g) || (!state->identity.in_soc) || ((state->identity.version != SOC_7090_P1G_21R1) && (state->identity.version != SOC_7090_P1G_11R1))) { - dprintk("%s() function can only be used for dib7090", __func__); + dprintk("%s() function can only be used for dib7090\n", __func__); return -ENODEV; } @@ -2098,7 +2099,8 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun force_soft_search = 1; if (*tune_state == CT_TUNER_START) { - dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO"); + dprintk("Start Captrim search : %s\n", + (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO"); dib0090_write_reg(state, 0x10, 0x2B1); dib0090_write_reg(state, 0x1e, 0x0032); @@ -2140,13 +2142,13 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun dib0090_read_reg(state, 0x40); state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F; - dprintk("***Final Captrim= 0x%x", state->fcaptrim); + dprintk("***Final Captrim= 0x%x\n", state->fcaptrim); *tune_state = CT_TUNER_STEP_3; } else { /* MERGE for all krosus before P1G */ adc = dib0090_get_slow_adc_val(state); - dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024); + dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024); if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */ adc_target = 200; @@ -2162,7 +2164,7 @@ static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tun } if (adc < state->adc_diff) { - dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff); + dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; } @@ -2216,7 +2218,7 @@ static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tu val = dib0090_get_slow_adc_val(state); state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55; - dprintk("temperature: %d C", state->temperature - 30); + dprintk("temperature: %d C\n", state->temperature - 30); *tune_state = CT_TUNER_STEP_2; break; @@ -2478,13 +2480,13 @@ static int dib0090_tune(struct dvb_frontend *fe) wbd++; dib0090_write_reg(state, 0x1e, 0x07ff); - dprintk("Final Captrim: %d", (u32) state->fcaptrim); - dprintk("HFDIV code: %d", (u32) pll->hfdiv_code); - dprintk("VCO = %d", (u32) pll->vco_band); - dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request); - dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz); - dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); - dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8), + dprintk("Final Captrim: %d\n", (u32) state->fcaptrim); + dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code); + dprintk("VCO = %d\n", (u32) pll->vco_band); + dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request); + dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz); + dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); + dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3); #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ @@ -2498,7 +2500,7 @@ static int dib0090_tune(struct dvb_frontend *fe) dib0090_write_reg(state, 0x10, state->wbdmux); if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) { - dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune); + dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune); dib0090_write_reg(state, 0x09, tune->lna_bias); dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim)); } else @@ -2643,7 +2645,7 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte if (dib0090_reset(fe) != 0) goto free_mem; - printk(KERN_INFO "DiB0090: successfully identified\n"); + pr_info("DiB0090: successfully identified\n"); memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops)); return fe; @@ -2670,7 +2672,7 @@ struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_ada if (dib0090_fw_reset_digital(fe, st->config) != 0) goto free_mem; - dprintk("DiB0090 FW: successfully identified"); + dprintk("DiB0090 FW: successfully identified\n"); memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops)); return fe; -- cgit v1.2.3 From 585e3227ec583217b323cec121d3fc188ca4d23e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 08:44:10 -0300 Subject: [media] dib3000mb: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. The frontend settings also rely on continuation lines. Change it to avoid the need of adding pr_cont() calls. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib3000mb.c | 137 +++++++++++++-------------- drivers/media/dvb-frontends/dib3000mb_priv.h | 16 ++-- 2 files changed, 71 insertions(+), 82 deletions(-) diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c index 6821ecb53d63..bf9762783be4 100644 --- a/drivers/media/dvb-frontends/dib3000mb.c +++ b/drivers/media/dvb-frontends/dib3000mb.c @@ -21,6 +21,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -42,13 +44,13 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_srch(args...) dprintk(0x04,args) -#define deb_info(args...) dprintk(0x01,args) -#define deb_xfer(args...) dprintk(0x02,args) -#define deb_setf(args...) dprintk(0x04,args) -#define deb_getf(args...) dprintk(0x08,args) +#define deb_info(args...) dprintk(0x01, args) +#define deb_i2c(args...) dprintk(0x02, args) +#define deb_srch(args...) dprintk(0x04, args) +#define deb_info(args...) dprintk(0x01, args) +#define deb_xfer(args...) dprintk(0x02, args) +#define deb_setf(args...) dprintk(0x04, args) +#define deb_getf(args...) dprintk(0x08, args) static int dib3000_read_reg(struct dib3000_state *state, u16 reg) { @@ -126,103 +128,96 @@ static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner) fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - deb_setf("bandwidth: "); switch (c->bandwidth_hz) { case 8000000: - deb_setf("8 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); break; case 7000000: - deb_setf("7 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); break; case 6000000: - deb_setf("6 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); break; case 0: return -EOPNOTSUPP; default: - err("unknown bandwidth value."); + pr_err("unknown bandwidth value.\n"); return -EINVAL; } + deb_setf("bandwidth: %d MHZ\n", c->bandwidth_hz / 1000000); } wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); - deb_setf("transmission mode: "); switch (c->transmission_mode) { case TRANSMISSION_MODE_2K: - deb_setf("2k\n"); + deb_setf("transmission mode: 2k\n"); wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); break; case TRANSMISSION_MODE_8K: - deb_setf("8k\n"); + deb_setf("transmission mode: 8k\n"); wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); break; case TRANSMISSION_MODE_AUTO: - deb_setf("auto\n"); + deb_setf("transmission mode: auto\n"); break; default: return -EINVAL; } - deb_setf("guard: "); switch (c->guard_interval) { case GUARD_INTERVAL_1_32: - deb_setf("1_32\n"); + deb_setf("guard 1_32\n"); wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); break; case GUARD_INTERVAL_1_16: - deb_setf("1_16\n"); + deb_setf("guard 1_16\n"); wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); break; case GUARD_INTERVAL_1_8: - deb_setf("1_8\n"); + deb_setf("guard 1_8\n"); wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); break; case GUARD_INTERVAL_1_4: - deb_setf("1_4\n"); + deb_setf("guard 1_4\n"); wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); break; case GUARD_INTERVAL_AUTO: - deb_setf("auto\n"); + deb_setf("guard auto\n"); break; default: return -EINVAL; } - deb_setf("inversion: "); switch (c->inversion) { case INVERSION_OFF: - deb_setf("off\n"); + deb_setf("inversion off\n"); wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); break; case INVERSION_AUTO: - deb_setf("auto "); + deb_setf("inversion auto\n"); break; case INVERSION_ON: - deb_setf("on\n"); + deb_setf("inversion on\n"); wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); break; default: return -EINVAL; } - deb_setf("modulation: "); switch (c->modulation) { case QPSK: - deb_setf("qpsk\n"); + deb_setf("modulation: qpsk\n"); wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); break; case QAM_16: - deb_setf("qam16\n"); + deb_setf("modulation: qam16\n"); wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); break; case QAM_64: - deb_setf("qam64\n"); + deb_setf("modulation: qam64\n"); wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); break; case QAM_AUTO: @@ -230,69 +225,64 @@ static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner) default: return -EINVAL; } - deb_setf("hierarchy: "); switch (c->hierarchy) { case HIERARCHY_NONE: - deb_setf("none "); + deb_setf("hierarchy: none\n"); /* fall through */ case HIERARCHY_1: - deb_setf("alpha=1\n"); + deb_setf("hierarchy: alpha=1\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); break; case HIERARCHY_2: - deb_setf("alpha=2\n"); + deb_setf("hierarchy: alpha=2\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); break; case HIERARCHY_4: - deb_setf("alpha=4\n"); + deb_setf("hierarchy: alpha=4\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); break; case HIERARCHY_AUTO: - deb_setf("alpha=auto\n"); + deb_setf("hierarchy: alpha=auto\n"); break; default: return -EINVAL; } - deb_setf("hierarchy: "); if (c->hierarchy == HIERARCHY_NONE) { - deb_setf("none\n"); wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); fe_cr = c->code_rate_HP; } else if (c->hierarchy != HIERARCHY_AUTO) { - deb_setf("on\n"); wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); fe_cr = c->code_rate_LP; } - deb_setf("fec: "); switch (fe_cr) { case FEC_1_2: - deb_setf("1_2\n"); + deb_setf("fec: 1_2\n"); wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); break; case FEC_2_3: - deb_setf("2_3\n"); + deb_setf("fec: 2_3\n"); wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); break; case FEC_3_4: - deb_setf("3_4\n"); + deb_setf("fec: 3_4\n"); wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); break; case FEC_5_6: - deb_setf("5_6\n"); + deb_setf("fec: 5_6\n"); wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); break; case FEC_7_8: - deb_setf("7_8\n"); + deb_setf("fec: 7_8\n"); wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); break; case FEC_NONE: - deb_setf("none "); + deb_setf("fec: none\n"); break; case FEC_AUTO: - deb_setf("auto\n"); + deb_setf("fec: auto\n"); break; default: return -EINVAL; @@ -357,7 +347,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner) rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) msleep(1); - deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); + deb_setf("search_state after autosearch %d after %d checks\n", + search_state, as_count); if (search_state == 1) { if (dib3000mb_get_frontend(fe, c) == 0) { @@ -464,7 +455,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, return 0; dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB); - deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); + deb_getf("DDS_VAL: %x %x %x\n", dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); if (dds_val < threshold) inv_test1 = 0; else if (dds_val == threshold) @@ -473,7 +464,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, inv_test1 = 2; dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB); - deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); + deb_getf("DDS_FREQ: %x %x %x\n", dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); if (dds_val < threshold) inv_test2 = 0; else if (dds_val == threshold) @@ -490,19 +481,19 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { case DIB3000_CONSTELLATION_QPSK: - deb_getf("QPSK "); + deb_getf("QPSK\n"); c->modulation = QPSK; break; case DIB3000_CONSTELLATION_16QAM: - deb_getf("QAM16 "); + deb_getf("QAM16\n"); c->modulation = QAM_16; break; case DIB3000_CONSTELLATION_64QAM: - deb_getf("QAM64 "); + deb_getf("QAM64\n"); c->modulation = QAM_64; break; default: - err("Unexpected constellation returned by TPS (%d)", tps_val); + pr_err("Unexpected constellation returned by TPS (%d)\n", tps_val); break; } deb_getf("TPS: %d\n", tps_val); @@ -513,23 +504,23 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, c->code_rate_HP = FEC_NONE; switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { case DIB3000_ALPHA_0: - deb_getf("HIERARCHY_NONE "); + deb_getf("HIERARCHY_NONE\n"); c->hierarchy = HIERARCHY_NONE; break; case DIB3000_ALPHA_1: - deb_getf("HIERARCHY_1 "); + deb_getf("HIERARCHY_1\n"); c->hierarchy = HIERARCHY_1; break; case DIB3000_ALPHA_2: - deb_getf("HIERARCHY_2 "); + deb_getf("HIERARCHY_2\n"); c->hierarchy = HIERARCHY_2; break; case DIB3000_ALPHA_4: - deb_getf("HIERARCHY_4 "); + deb_getf("HIERARCHY_4\n"); c->hierarchy = HIERARCHY_4; break; default: - err("Unexpected ALPHA value returned by TPS (%d)", tps_val); + pr_err("Unexpected ALPHA value returned by TPS (%d)\n", tps_val); break; } deb_getf("TPS: %d\n", tps_val); @@ -546,65 +537,65 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, switch (tps_val) { case DIB3000_FEC_1_2: - deb_getf("FEC_1_2 "); + deb_getf("FEC_1_2\n"); *cr = FEC_1_2; break; case DIB3000_FEC_2_3: - deb_getf("FEC_2_3 "); + deb_getf("FEC_2_3\n"); *cr = FEC_2_3; break; case DIB3000_FEC_3_4: - deb_getf("FEC_3_4 "); + deb_getf("FEC_3_4\n"); *cr = FEC_3_4; break; case DIB3000_FEC_5_6: - deb_getf("FEC_5_6 "); + deb_getf("FEC_5_6\n"); *cr = FEC_4_5; break; case DIB3000_FEC_7_8: - deb_getf("FEC_7_8 "); + deb_getf("FEC_7_8\n"); *cr = FEC_7_8; break; default: - err("Unexpected FEC returned by TPS (%d)", tps_val); + pr_err("Unexpected FEC returned by TPS (%d)\n", tps_val); break; } deb_getf("TPS: %d\n",tps_val); switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { case DIB3000_GUARD_TIME_1_32: - deb_getf("GUARD_INTERVAL_1_32 "); + deb_getf("GUARD_INTERVAL_1_32\n"); c->guard_interval = GUARD_INTERVAL_1_32; break; case DIB3000_GUARD_TIME_1_16: - deb_getf("GUARD_INTERVAL_1_16 "); + deb_getf("GUARD_INTERVAL_1_16\n"); c->guard_interval = GUARD_INTERVAL_1_16; break; case DIB3000_GUARD_TIME_1_8: - deb_getf("GUARD_INTERVAL_1_8 "); + deb_getf("GUARD_INTERVAL_1_8\n"); c->guard_interval = GUARD_INTERVAL_1_8; break; case DIB3000_GUARD_TIME_1_4: - deb_getf("GUARD_INTERVAL_1_4 "); + deb_getf("GUARD_INTERVAL_1_4\n"); c->guard_interval = GUARD_INTERVAL_1_4; break; default: - err("Unexpected Guard Time returned by TPS (%d)", tps_val); + pr_err("Unexpected Guard Time returned by TPS (%d)\n", tps_val); break; } deb_getf("TPS: %d\n", tps_val); switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { case DIB3000_TRANSMISSION_MODE_2K: - deb_getf("TRANSMISSION_MODE_2K "); + deb_getf("TRANSMISSION_MODE_2K\n"); c->transmission_mode = TRANSMISSION_MODE_2K; break; case DIB3000_TRANSMISSION_MODE_8K: - deb_getf("TRANSMISSION_MODE_8K "); + deb_getf("TRANSMISSION_MODE_8K\n"); c->transmission_mode = TRANSMISSION_MODE_8K; break; default: - err("unexpected transmission mode return by TPS (%d)", tps_val); + pr_err("unexpected transmission mode return by TPS (%d)\n", tps_val); break; } deb_getf("TPS: %d\n", tps_val); diff --git a/drivers/media/dvb-frontends/dib3000mb_priv.h b/drivers/media/dvb-frontends/dib3000mb_priv.h index 0459d5c84314..ef7f5d136c6b 100644 --- a/drivers/media/dvb-frontends/dib3000mb_priv.h +++ b/drivers/media/dvb-frontends/dib3000mb_priv.h @@ -13,20 +13,15 @@ #ifndef __DIB3000MB_PRIV_H_INCLUDED__ #define __DIB3000MB_PRIV_H_INCLUDED__ -/* info and err, taken from usb.h, if there is anything available like by default. */ -#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg) - /* handy shortcuts */ #define rd(reg) dib3000_read_reg(state,reg) #define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \ - { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; } + { pr_err("while sending 0x%04x to 0x%04x.", val, reg); return -EREMOTEIO; } #define wr_foreach(a,v) { int i; \ if (sizeof(a) != sizeof(v)) \ - err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\ + pr_err("sizeof: %zu %zu is different", sizeof(a), sizeof(v));\ for (i=0; i < sizeof(a)/sizeof(u16); i++) \ wr(a[i],v[i]); \ } @@ -37,8 +32,11 @@ /* debug */ -#define dprintk(level,args...) \ - do { if ((debug & level)) { printk(args); } } while (0) +#define dprintk(level, fmt, arg...) do { \ + if (debug & level) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) /* mask for enabling a specific pid for the pid_filter */ #define DIB3000_ACTIVATE_PID_FILTERING (0x2000) -- cgit v1.2.3 From 441d54e3431d7956bca9cae0e23b16ed0d7b0e4e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 08:55:41 -0300 Subject: [media] dib3000mc: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib3000mc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index da0f1dc5aaf7..0f7793455da7 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -11,6 +11,8 @@ * published by the Free Software Foundation, version 2. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -27,7 +29,11 @@ static int buggy_sfn_workaround; module_param(buggy_sfn_workaround, int, 0644); MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) struct dib3000mc_state { struct dvb_frontend demod; -- cgit v1.2.3 From 7570227724405694f407a2c5e3dd3f4f8d9c2d92 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 08:57:27 -0300 Subject: [media] dib7000m: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib7000m.c | 73 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c index b3ddae8885ac..c9ebb0ff746a 100644 --- a/drivers/media/dvb-frontends/dib7000m.c +++ b/drivers/media/dvb-frontends/dib7000m.c @@ -8,6 +8,9 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -21,7 +24,11 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) struct dib7000m_state { struct dvb_frontend demod; @@ -74,7 +81,7 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -92,7 +99,7 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) state->msg[1].len = 2; if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) - dprintk("i2c read error on %d",reg); + dprintk("i2c read error on %d\n", reg); ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; mutex_unlock(&state->i2c_buffer_lock); @@ -105,7 +112,7 @@ static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -154,7 +161,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode) fifo_threshold = 1792; smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1); - dprintk( "setting output mode for demod %p to %d", &state->demod, mode); + dprintk("setting output mode for demod %p to %d\n", &state->demod, mode); switch (mode) { case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock @@ -181,7 +188,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode) outreg = 0; break; default: - dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); + dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod); break; } @@ -302,7 +309,7 @@ static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc break; } -// dprintk( "913: %x, 914: %x", reg_913, reg_914); +// dprintk("913: %x, 914: %x\n", reg_913, reg_914); ret |= dib7000m_write_word(state, 913, reg_913); ret |= dib7000m_write_word(state, 914, reg_914); @@ -320,10 +327,10 @@ static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw) state->current_bandwidth = bw; if (state->timf == 0) { - dprintk( "using default timf"); + dprintk("using default timf\n"); timf = state->timf_default; } else { - dprintk( "using updated timf"); + dprintk("using updated timf\n"); timf = state->timf; } @@ -340,7 +347,7 @@ static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff) struct dib7000m_state *state = demod->demodulator_priv; if (state->div_force_off) { - dprintk( "diversity combination deactivated - forced by COFDM parameters"); + dprintk("diversity combination deactivated - forced by COFDM parameters\n"); onoff = 0; } state->div_state = (u8)onoff; @@ -580,10 +587,10 @@ static int dib7000m_demod_reset(struct dib7000m_state *state) dib7000mc_reset_pll(state); if (dib7000m_reset_gpio(state) != 0) - dprintk( "GPIO reset was not successful."); + dprintk("GPIO reset was not successful.\n"); if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk( "OUTPUT_MODE could not be reset."); + dprintk("OUTPUT_MODE could not be reset.\n"); /* unforce divstr regardless whether i2c enumeration was done or not */ dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) ); @@ -650,7 +657,7 @@ static int dib7000m_agc_soft_split(struct dib7000m_state *state) (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); - dprintk( "AGC split_offset: %d",split_offset); + dprintk("AGC split_offset: %d\n", split_offset); // P_agc_force_split and P_agc_split_offset return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset); @@ -687,7 +694,7 @@ static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) } if (agc == NULL) { - dprintk( "no valid AGC configuration found for band 0x%02x",band); + dprintk("no valid AGC configuration found for band 0x%02x\n", band); return -EINVAL; } @@ -703,7 +710,7 @@ static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp); dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp); - dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", + dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n", state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); /* AGC continued */ @@ -724,7 +731,7 @@ static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) if (state->revision > 0x4000) { // settings for the MC dib7000m_write_word(state, 71, agc->agc1_pt3); -// dprintk( "929: %x %d %d", +// dprintk("929: %x %d %d\n", // (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel); dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); } else { @@ -742,7 +749,7 @@ static void dib7000m_update_timf(struct dib7000m_state *state) state->timf = timf * 160 / (state->current_bandwidth / 50); dib7000m_write_word(state, 23, (u16) (timf >> 16)); dib7000m_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default); + dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default); } static int dib7000m_agc_startup(struct dvb_frontend *demod) @@ -804,7 +811,7 @@ static int dib7000m_agc_startup(struct dvb_frontend *demod) dib7000m_restart_agc(state); - dprintk( "SPLIT %p: %hd", demod, agc_split); + dprintk("SPLIT %p: %hd\n", demod, agc_split); (*agc_state)++; ret = 5; @@ -1013,12 +1020,12 @@ static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg) u16 irq_pending = dib7000m_read_word(state, reg); if (irq_pending & 0x1) { // failed - dprintk( "autosearch failed"); + dprintk("autosearch failed\n"); return 1; } if (irq_pending & 0x2) { // succeeded - dprintk( "autosearch succeeded"); + dprintk("autosearch succeeded\n"); return 2; } return 0; // still pending @@ -1102,7 +1109,7 @@ static int dib7000m_wakeup(struct dvb_frontend *demod) dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) - dprintk( "could not start Slow ADC"); + dprintk("could not start Slow ADC\n"); return 0; } @@ -1121,7 +1128,7 @@ static int dib7000m_identify(struct dib7000m_state *state) u16 value; if ((value = dib7000m_read_word(state, 896)) != 0x01b3) { - dprintk( "wrong Vendor ID (0x%x)",value); + dprintk("wrong Vendor ID (0x%x)\n", value); return -EREMOTEIO; } @@ -1130,21 +1137,21 @@ static int dib7000m_identify(struct dib7000m_state *state) state->revision != 0x4001 && state->revision != 0x4002 && state->revision != 0x4003) { - dprintk( "wrong Device ID (0x%x)",value); + dprintk("wrong Device ID (0x%x)\n", value); return -EREMOTEIO; } /* protect this driver to be used with 7000PC */ if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) { - dprintk( "this driver does not work with DiB7000PC"); + dprintk("this driver does not work with DiB7000PC\n"); return -EREMOTEIO; } switch (state->revision) { - case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break; - case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break; - case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break; - case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break; + case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break; + case 0x4001: state->reg_offs = 1; dprintk("found DiB7000HC\n"); break; + case 0x4002: state->reg_offs = 1; dprintk("found DiB7000MC\n"); break; + case 0x4003: state->reg_offs = 1; dprintk("found DiB9000\n"); break; } return 0; @@ -1242,7 +1249,7 @@ static int dib7000m_set_frontend(struct dvb_frontend *fe) found = dib7000m_autosearch_is_irq(fe); } while (found == 0 && i--); - dprintk("autosearch returns: %d",found); + dprintk("autosearch returns: %d\n", found); if (found == 0 || found == 1) return 0; // no channel found @@ -1330,7 +1337,7 @@ int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) struct dib7000m_state *state = fe->demodulator_priv; u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef; val |= (onoff & 0x1) << 4; - dprintk("PID filter enabled %d", onoff); + dprintk("PID filter enabled %d\n", onoff); return dib7000m_write_word(state, 294 + state->reg_offs, val); } EXPORT_SYMBOL(dib7000m_pid_filter_ctrl); @@ -1338,7 +1345,7 @@ EXPORT_SYMBOL(dib7000m_pid_filter_ctrl); int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib7000m_state *state = fe->demodulator_priv; - dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); + dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff); return dib7000m_write_word(state, 300 + state->reg_offs + id, onoff ? (1 << 13) | pid : 0); } @@ -1362,7 +1369,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, if (dib7000m_identify(&st) != 0) { st.i2c_addr = default_addr; if (dib7000m_identify(&st) != 0) { - dprintk("DiB7000M #%d: not identified", k); + dprintk("DiB7000M #%d: not identified\n", k); return -EIO; } } @@ -1375,7 +1382,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, /* set new i2c address and force divstart */ dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2); - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); + dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); } for (k = 0; k < no_of_demods; k++) { -- cgit v1.2.3 From 5a0e2a4e936d04a1e987077729d8d01adbc78a9f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 09:35:33 -0300 Subject: [media] dib7000p: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib7000p.c | 127 +++++++++++++++++---------------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index b861d4437f2a..2cee51c08a5a 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -7,6 +7,9 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -26,7 +29,11 @@ static int buggy_sfn_workaround; module_param(buggy_sfn_workaround, int, 0644); MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) struct i2c_device { struct i2c_adapter *i2c_adap; @@ -98,7 +105,7 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -116,7 +123,7 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) state->msg[1].len = 2; if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) - dprintk("i2c read error on %d", reg); + dprintk("i2c read error on %d\n", reg); ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; mutex_unlock(&state->i2c_buffer_lock); @@ -128,7 +135,7 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -174,7 +181,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) fifo_threshold = 1792; smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); - dprintk("setting output mode for demod %p to %d", &state->demod, mode); + dprintk("setting output mode for demod %p to %d\n", &state->demod, mode); switch (mode) { case OUTMODE_MPEG2_PAR_GATED_CLK: @@ -204,7 +211,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) outreg = 0; break; default: - dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod); + dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod); break; } @@ -224,7 +231,7 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff) struct dib7000p_state *state = demod->demodulator_priv; if (state->div_force_off) { - dprintk("diversity combination deactivated - forced by COFDM parameters"); + dprintk("diversity combination deactivated - forced by COFDM parameters\n"); onoff = 0; dib7000p_write_word(state, 207, 0); } else @@ -374,10 +381,10 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) state->current_bandwidth = bw; if (state->timf == 0) { - dprintk("using default timf"); + dprintk("using default timf\n"); timf = state->cfg.bw->timf; } else { - dprintk("using updated timf"); + dprintk("using updated timf\n"); timf = state->timf; } @@ -494,7 +501,7 @@ static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth loopdiv = (reg_1856 >> 6) & 0x3f; if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { - dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); + dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); reg_1856 &= 0xf000; reg_1857 = dib7000p_read_word(state, 1857); dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15)); @@ -511,7 +518,7 @@ static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth dib7000p_write_word(state, 1857, reg_1857 | (1 << 15)); while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) - dprintk("Waiting for PLL to lock"); + dprintk("Waiting for PLL to lock\n"); return 0; } @@ -521,7 +528,7 @@ static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth static int dib7000p_reset_gpio(struct dib7000p_state *st) { /* reset the GPIOs */ - dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos); + dprintk("gpio dir: %x: val: %x, pwm_pos: %x\n", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos); dib7000p_write_word(st, 1029, st->gpio_dir); dib7000p_write_word(st, 1030, st->gpio_val); @@ -669,7 +676,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_reset_pll(state); if (dib7000p_reset_gpio(state) != 0) - dprintk("GPIO reset was not successful."); + dprintk("GPIO reset was not successful.\n"); if (state->version == SOC7090) { dib7000p_write_word(state, 899, 0); @@ -681,7 +688,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 273, (0<<6) | 30); } if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk("OUTPUT_MODE could not be reset."); + dprintk("OUTPUT_MODE could not be reset.\n"); dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); dib7000p_sad_calib(state); @@ -759,7 +766,7 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band) } if (agc == NULL) { - dprintk("no valid AGC configuration found for band 0x%02x", band); + dprintk("no valid AGC configuration found for band 0x%02x\n", band); return -EINVAL; } @@ -776,7 +783,7 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band) dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); /* AGC continued */ - dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d", + dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n", state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); if (state->wbd_ref != 0) @@ -806,7 +813,7 @@ static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz) u32 dds = state->cfg.bw->ifreq & 0x1ffffff; u8 invert = !!(state->cfg.bw->ifreq & (1 << 25)); - dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert); + dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d\n", offset_khz, internal, invert); if (offset_khz < 0) unit_khz_dds_val *= -1; @@ -902,7 +909,7 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod) dib7000p_restart_agc(state); - dprintk("SPLIT %p: %hd", demod, agc_split); + dprintk("SPLIT %p: %hd\n", demod, agc_split); (*agc_state)++; ret = 5; @@ -934,7 +941,7 @@ static void dib7000p_update_timf(struct dib7000p_state *state) state->timf = timf * 160 / (state->current_bandwidth / 50); dib7000p_write_word(state, 23, (u16) (timf >> 16)); dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf); + dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->cfg.bw->timf); } @@ -1202,7 +1209,7 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 int bw_khz = bw; u32 pha; - dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); + dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)\n", f_rel, rf_khz, xtal); if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2) return; @@ -1252,7 +1259,7 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 coef_im[k] = (1 << 24) - 1; coef_im[k] /= (1 << 15); - dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); + dprintk("PALF COEF: %d re: %d im: %d\n", k, coef_re[k], coef_im[k]); dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); @@ -1280,7 +1287,7 @@ static int dib7000p_tune(struct dvb_frontend *demod) /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); if (state->sfn_workaround_active) { - dprintk("SFN workaround is active"); + dprintk("SFN workaround is active\n"); tmp |= (1 << 9); dib7000p_write_word(state, 166, 0x4000); } else { @@ -1390,15 +1397,15 @@ static int dib7000p_sleep(struct dvb_frontend *demod) static int dib7000p_identify(struct dib7000p_state *st) { u16 value; - dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr); + dprintk("checking demod on I2C address: %d (%x)\n", st->i2c_addr, st->i2c_addr); if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { - dprintk("wrong Vendor ID (read=0x%x)", value); + dprintk("wrong Vendor ID (read=0x%x)\n", value); return -EREMOTEIO; } if ((value = dib7000p_read_word(st, 769)) != 0x4000) { - dprintk("wrong Device ID (%x)", value); + dprintk("wrong Device ID (%x)\n", value); return -EREMOTEIO; } @@ -1536,7 +1543,7 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe) found = dib7000p_autosearch_is_irq(fe); } while (found == 0 && i--); - dprintk("autosearch returns: %d", found); + dprintk("autosearch returns: %d\n", found); if (found == 0 || found == 1) return 0; @@ -1951,7 +1958,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, enum fe_status stat) time_us = dib7000p_get_time_us(demod); state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); - dprintk("Next all layers stats available in %u us.", time_us); + dprintk("Next all layers stats available in %u us.\n", time_us); dib7000p_read_ber(demod, &val); c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; @@ -2019,7 +2026,7 @@ static int dib7000pc_detection(struct i2c_adapter *i2c_adap) if (i2c_transfer(i2c_adap, msg, 2) == 2) if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); + dprintk("-D- DiB7000PC detected\n"); return 1; } @@ -2027,11 +2034,11 @@ static int dib7000pc_detection(struct i2c_adapter *i2c_adap) if (i2c_transfer(i2c_adap, msg, 2) == 2) if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); + dprintk("-D- DiB7000PC detected\n"); return 1; } - dprintk("-D- DiB7000PC not detected"); + dprintk("-D- DiB7000PC not detected\n"); kfree(rx); rx_memory_error: @@ -2050,14 +2057,14 @@ static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) struct dib7000p_state *state = fe->demodulator_priv; u16 val = dib7000p_read_word(state, 235) & 0xffef; val |= (onoff & 0x1) << 4; - dprintk("PID filter enabled %d", onoff); + dprintk("PID filter enabled %d\n", onoff); return dib7000p_write_word(state, 235, val); } static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib7000p_state *state = fe->demodulator_priv; - dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); + dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff); return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); } @@ -2100,7 +2107,7 @@ static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u /* set new i2c address and force divstart */ dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2); - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); + dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); } for (k = 0; k < no_of_demods; k++) { @@ -2136,21 +2143,21 @@ static s32 dib7000p_get_adc_power(struct dvb_frontend *fe) buf[0] = dib7000p_read_word(state, 0x184); buf[1] = dib7000p_read_word(state, 0x185); pow_i = (buf[0] << 16) | buf[1]; - dprintk("raw pow_i = %d", pow_i); + dprintk("raw pow_i = %d\n", pow_i); tmp_val = pow_i; while (tmp_val >>= 1) exp++; mant = (pow_i * 1000 / (1 << exp)); - dprintk(" mant = %d exp = %d", mant / 1000, exp); + dprintk(" mant = %d exp = %d\n", mant / 1000, exp); ix = (u8) ((mant - 1000) / 100); /* index of the LUT */ - dprintk(" ix = %d", ix); + dprintk(" ix = %d\n", ix); pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908); pow_i = (pow_i << 8) / 1000; - dprintk(" pow_i = %d", pow_i); + dprintk(" pow_i = %d\n", pow_i); return pow_i; } @@ -2185,7 +2192,7 @@ static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_ms n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1; i--; if (i == 0) - dprintk("Tuner ITF: write busy (overflow)"); + dprintk("Tuner ITF: write busy (overflow)\n"); } dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); @@ -2205,7 +2212,7 @@ static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1; i--; if (i == 0) - dprintk("TunerITF: read busy (overflow)"); + dprintk("TunerITF: read busy (overflow)\n"); } dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f)); @@ -2214,7 +2221,7 @@ static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg n_empty = dib7000p_read_word(state, 1984) & 0x1; i--; if (i == 0) - dprintk("TunerITF: read busy (empty)"); + dprintk("TunerITF: read busy (empty)\n"); } read_word = dib7000p_read_word(state, 1987); msg[1].buf[0] = (read_word >> 8) & 0xff; @@ -2435,7 +2442,7 @@ static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) { - dprintk("Configure DibStream Tx"); + dprintk("Configure DibStream Tx\n"); dib7000p_write_word(state, 1615, 1); dib7000p_write_word(state, 1603, P_Kin); @@ -2455,7 +2462,7 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout { u32 syncFreq; - dprintk("Configure DibStream Rx"); + dprintk("Configure DibStream Rx\n"); if ((P_Kin != 0) && (P_Kout != 0)) { syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize); dib7000p_write_word(state, 1542, syncFreq); @@ -2492,7 +2499,7 @@ static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff) static void dib7090_configMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) { - dprintk("Enable Mpeg mux"); + dprintk("Enable Mpeg mux\n"); dib7090_enMpegMux(state, 0); @@ -2513,17 +2520,17 @@ static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode) switch (mode) { case MPEG_ON_DIBTX: - dprintk("SET MPEG ON DIBSTREAM TX"); + dprintk("SET MPEG ON DIBSTREAM TX\n"); dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); reg_1288 |= (1<<9); break; case DIV_ON_DIBTX: - dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dprintk("SET DIV_OUT ON DIBSTREAM TX\n"); dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); reg_1288 |= (1<<8); break; case ADC_ON_DIBTX: - dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dprintk("SET ADC_OUT ON DIBSTREAM TX\n"); dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); reg_1288 |= (1<<7); break; @@ -2539,17 +2546,17 @@ static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode) switch (mode) { case DEMOUT_ON_HOSTBUS: - dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dprintk("SET DEM OUT OLD INTERF ON HOST BUS\n"); dib7090_enMpegMux(state, 0); reg_1288 |= (1<<6); break; case DIBTX_ON_HOSTBUS: - dprintk("SET DIBSTREAM TX ON HOST BUS"); + dprintk("SET DIBSTREAM TX ON HOST BUS\n"); dib7090_enMpegMux(state, 0); reg_1288 |= (1<<5); break; case MPEG_ON_HOSTBUS: - dprintk("SET MPEG MUX ON HOST BUS"); + dprintk("SET MPEG MUX ON HOST BUS\n"); reg_1288 |= (1<<4); break; default: @@ -2565,7 +2572,7 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) switch (onoff) { case 0: /* only use the internal way - not the diversity input */ - dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__); + dprintk("%s mode OFF : by default Enable Mpeg INPUT\n", __func__); dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /* Do not divide the serial clock of MPEG MUX */ @@ -2581,7 +2588,7 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) break; case 1: /* both ways */ case 2: /* only the diversity input */ - dprintk("%s ON : Enable diversity INPUT", __func__); + dprintk("%s ON : Enable diversity INPUT\n", __func__); dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); state->input_mode_mpeg = 0; break; @@ -2612,11 +2619,11 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_SERIAL: if (prefer_mpeg_mux_use) { - dprintk("setting output mode TS_SERIAL using Mpeg Mux"); + dprintk("setting output mode TS_SERIAL using Mpeg Mux\n"); dib7090_configMpegMux(state, 3, 1, 1); dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); } else {/* Use Smooth block */ - dprintk("setting output mode TS_SERIAL using Smooth bloc"); + dprintk("setting output mode TS_SERIAL using Smooth bloc\n"); dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (2<<6) | (0 << 1); } @@ -2624,24 +2631,24 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_PAR_GATED_CLK: if (prefer_mpeg_mux_use) { - dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux\n"); dib7090_configMpegMux(state, 2, 0, 0); dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); } else { /* Use Smooth block */ - dprintk("setting output mode TS_PARALLEL_GATED using Smooth block"); + dprintk("setting output mode TS_PARALLEL_GATED using Smooth block\n"); dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (0<<6); } break; case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ - dprintk("setting output mode TS_PARALLEL_CONT using Smooth block"); + dprintk("setting output mode TS_PARALLEL_CONT using Smooth block\n"); dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (1<<6); break; case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ - dprintk("setting output mode TS_FIFO using Smooth block"); + dprintk("setting output mode TS_FIFO using Smooth block\n"); dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (5<<6); smo_mode |= (3 << 1); @@ -2649,13 +2656,13 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) break; case OUTMODE_DIVERSITY: - dprintk("setting output mode MODE_DIVERSITY"); + dprintk("setting output mode MODE_DIVERSITY\n"); dib7090_setDibTxMux(state, DIV_ON_DIBTX); dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; case OUTMODE_ANALOG_ADC: - dprintk("setting output mode MODE_ANALOG_ADC"); + dprintk("setting output mode MODE_ANALOG_ADC\n"); dib7090_setDibTxMux(state, ADC_ON_DIBTX); dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; @@ -2678,7 +2685,7 @@ static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) struct dib7000p_state *state = fe->demodulator_priv; u16 en_cur_state; - dprintk("sleep dib7090: %d", onoff); + dprintk("sleep dib7090: %d\n", onoff); en_cur_state = dib7000p_read_word(state, 1922); -- cgit v1.2.3 From 8af16adfbb45dfa3b75a4217dcc631d7414854e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 10:05:46 -0300 Subject: [media] dib8000: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a\n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib8000.c | 261 +++++++++++++++++----------------- 1 file changed, 134 insertions(+), 127 deletions(-) diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index ddf9c44877a2..e501ec964df1 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -7,6 +7,9 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -31,7 +34,11 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) struct i2c_device { struct i2c_adapter *adap; @@ -147,7 +154,7 @@ static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) }; if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -157,7 +164,7 @@ static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) msg[1].buf = i2c->i2c_read_buffer; if (i2c_transfer(i2c->adap, msg, 2) != 2) - dprintk("i2c read error on %d", reg); + dprintk("i2c read error on %d\n", reg); ret = (msg[1].buf[0] << 8) | msg[1].buf[1]; mutex_unlock(i2c->i2c_buffer_lock); @@ -182,7 +189,7 @@ static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg) state->msg[1].len = 2; if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2) - dprintk("i2c read error on %d", reg); + dprintk("i2c read error on %d\n", reg); ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; @@ -194,7 +201,7 @@ static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) u16 ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -210,7 +217,7 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg) u16 rw[2]; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -228,7 +235,7 @@ static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) int ret = 0; if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -249,7 +256,7 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) int ret; if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -395,7 +402,7 @@ static void dib8000_set_acquisition_mode(struct dib8000_state *state) { u16 nud = dib8000_read_word(state, 298); nud |= (1 << 3) | (1 << 0); - dprintk("acquisition mode activated"); + dprintk("acquisition mode activated\n"); dib8000_write_word(state, 298, nud); } static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) @@ -408,7 +415,7 @@ static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) fifo_threshold = 1792; smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); - dprintk("-I- Setting output mode for demod %p to %d", + dprintk("-I- Setting output mode for demod %p to %d\n", &state->fe[0], mode); switch (mode) { @@ -443,7 +450,7 @@ static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) break; default: - dprintk("Unhandled output_mode passed to be set for demod %p", + dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->fe[0]); return -EINVAL; } @@ -464,7 +471,7 @@ static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff) struct dib8000_state *state = fe->demodulator_priv; u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0; - dprintk("set diversity input to %i", onoff); + dprintk("set diversity input to %i\n", onoff); if (!state->differential_constellation) { dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2 @@ -531,7 +538,7 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow break; } - dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280); + dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x\n", reg_774, reg_775, reg_776, reg_900, reg_1280); dib8000_write_word(state, 774, reg_774); dib8000_write_word(state, 775, reg_775); dib8000_write_word(state, 776, reg_776); @@ -619,10 +626,10 @@ static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) bw = 6000; if (state->timf == 0) { - dprintk("using default timf"); + dprintk("using default timf\n"); timf = state->timf_default; } else { - dprintk("using updated timf"); + dprintk("using updated timf\n"); timf = state->timf; } @@ -667,7 +674,7 @@ static int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) { - dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); + dprintk("ifreq: %d %x, inversion: %d\n", bw->ifreq, bw->ifreq, bw->ifreq >> 25); if (state->revision != 0x8090) { dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); @@ -704,7 +711,7 @@ static void dib8000_reset_pll(struct dib8000_state *state) clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); dib8000_write_word(state, 902, clk_cfg1); - dprintk("clk_cfg1: 0x%04x", clk_cfg1); + dprintk("clk_cfg1: 0x%04x\n", clk_cfg1); /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ if (state->cfg.pll->ADClkSrc == 0) @@ -754,7 +761,7 @@ static int dib8000_update_pll(struct dvb_frontend *fe, pll->pll_ratio == loopdiv)) return -EINVAL; - dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); + dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); if (state->revision == 0x8090) { reg_1856 &= 0xf000; reg_1857 = dib8000_read_word(state, 1857); @@ -767,11 +774,11 @@ static int dib8000_update_pll(struct dvb_frontend *fe, /* write new system clk into P_sec_len */ internal = dib8000_read32(state, 23) / 1000; - dprintk("Old Internal = %d", internal); + dprintk("Old Internal = %d\n", internal); xtal = 2 * (internal / loopdiv) * prediv; internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio; - dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000); - dprintk("New Internal = %d", internal); + dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d\n", xtal, internal/1000, internal/2000, internal/8000); + dprintk("New Internal = %d\n", internal); dib8000_write_word(state, 23, (u16) (((internal / 2) >> 16) & 0xffff)); @@ -780,22 +787,22 @@ static int dib8000_update_pll(struct dvb_frontend *fe, dib8000_write_word(state, 1857, reg_1857 | (1 << 15)); while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1) - dprintk("Waiting for PLL to lock"); + dprintk("Waiting for PLL to lock\n"); /* verify */ reg_1856 = dib8000_read_word(state, 1856); - dprintk("PLL Updated with prediv = %d and loopdiv = %d", + dprintk("PLL Updated with prediv = %d and loopdiv = %d\n", reg_1856&0x3f, (reg_1856>>6)&0x3f); } else { if (bw != state->current_demod_bw) { /** Bandwidth change => force PLL update **/ - dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv); + dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)\n", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv); if (state->cfg.pll->pll_prediv != oldprediv) { /** Full PLL change only if prediv is changed **/ /** full update => bypass and reconfigure **/ - dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio); + dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)\n", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio); dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */ dib8000_reset_pll(state); dib8000_write_word(state, 898, 0x0004); /* sad */ @@ -807,7 +814,7 @@ static int dib8000_update_pll(struct dvb_frontend *fe, if (ratio != 0) { /** ratio update => only change ratio **/ - dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio); + dprintk("PLL: Update ratio (prediv: %d, ratio: %d)\n", state->cfg.pll->pll_prediv, ratio); dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */ } } @@ -841,7 +848,7 @@ static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val) st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */ dib8000_write_word(st, 1030, st->cfg.gpio_val); - dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val); + dprintk("gpio dir: %x: gpio val: %x\n", st->cfg.gpio_dir, st->cfg.gpio_val); return 0; } @@ -958,29 +965,29 @@ static u16 dib8000_identify(struct i2c_device *client) value = dib8000_i2c_read16(client, 896); if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) { - dprintk("wrong Vendor ID (read=0x%x)", value); + dprintk("wrong Vendor ID (read=0x%x)\n", value); return 0; } value = dib8000_i2c_read16(client, 897); if (value != 0x8000 && value != 0x8001 && value != 0x8002 && value != 0x8090) { - dprintk("wrong Device ID (%x)", value); + dprintk("wrong Device ID (%x)\n", value); return 0; } switch (value) { case 0x8000: - dprintk("found DiB8000A"); + dprintk("found DiB8000A\n"); break; case 0x8001: - dprintk("found DiB8000B"); + dprintk("found DiB8000B\n"); break; case 0x8002: - dprintk("found DiB8000C"); + dprintk("found DiB8000C\n"); break; case 0x8090: - dprintk("found DiB8096P"); + dprintk("found DiB8096P\n"); break; } return value; @@ -1037,7 +1044,7 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 1287, 0x0003); if (state->revision == 0x8000) - dprintk("error : dib8000 MA not supported"); + dprintk("error : dib8000 MA not supported\n"); dibx000_reset_i2c_master(&state->i2c_master); @@ -1069,7 +1076,7 @@ static int dib8000_reset(struct dvb_frontend *fe) if (state->cfg.drives) dib8000_write_word(state, 906, state->cfg.drives); else { - dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); + dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.\n"); /* min drive SDRAM - not optimal - adjust */ dib8000_write_word(state, 906, 0x2d98); } @@ -1080,11 +1087,11 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 898, 0x0004); if (dib8000_reset_gpio(state) != 0) - dprintk("GPIO reset was not successful."); + dprintk("GPIO reset was not successful.\n"); if ((state->revision != 0x8090) && (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)) - dprintk("OUTPUT_MODE could not be resetted."); + dprintk("OUTPUT_MODE could not be resetted.\n"); state->current_agc = NULL; @@ -1176,7 +1183,7 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) } if (agc == NULL) { - dprintk("no valid AGC configuration found for band 0x%02x", band); + dprintk("no valid AGC configuration found for band 0x%02x\n", band); return -EINVAL; } @@ -1192,7 +1199,7 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp); dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp); - dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d", + dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n", state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); /* AGC continued */ @@ -1251,7 +1258,7 @@ static int dib8000_agc_soft_split(struct dib8000_state *state) (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); - dprintk("AGC split_offset: %d", split_offset); + dprintk("AGC split_offset: %d\n", split_offset); // P_agc_force_split and P_agc_split_offset dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset); @@ -1395,7 +1402,7 @@ static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) { - dprintk("Configure DibStream Tx"); + dprintk("Configure DibStream Tx\n"); dib8000_write_word(state, 1615, 1); dib8000_write_word(state, 1603, P_Kin); @@ -1414,7 +1421,7 @@ static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin, { u32 syncFreq; - dprintk("Configure DibStream Rx synchroMode = %d", synchroMode); + dprintk("Configure DibStream Rx synchroMode = %d\n", synchroMode); if ((P_Kin != 0) && (P_Kout != 0)) { syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout, @@ -1456,7 +1463,7 @@ static void dib8096p_configMpegMux(struct dib8000_state *state, { u16 reg_1287; - dprintk("Enable Mpeg mux"); + dprintk("Enable Mpeg mux\n"); dib8096p_enMpegMux(state, 0); @@ -1477,15 +1484,15 @@ static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode) switch (mode) { case MPEG_ON_DIBTX: - dprintk("SET MPEG ON DIBSTREAM TX"); + dprintk("SET MPEG ON DIBSTREAM TX\n"); dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); reg_1288 |= (1 << 9); break; case DIV_ON_DIBTX: - dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dprintk("SET DIV_OUT ON DIBSTREAM TX\n"); dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); reg_1288 |= (1 << 8); break; case ADC_ON_DIBTX: - dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dprintk("SET ADC_OUT ON DIBSTREAM TX\n"); dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); reg_1288 |= (1 << 7); break; default: @@ -1500,17 +1507,17 @@ static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode) switch (mode) { case DEMOUT_ON_HOSTBUS: - dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dprintk("SET DEM OUT OLD INTERF ON HOST BUS\n"); dib8096p_enMpegMux(state, 0); reg_1288 |= (1 << 6); break; case DIBTX_ON_HOSTBUS: - dprintk("SET DIBSTREAM TX ON HOST BUS"); + dprintk("SET DIBSTREAM TX ON HOST BUS\n"); dib8096p_enMpegMux(state, 0); reg_1288 |= (1 << 5); break; case MPEG_ON_HOSTBUS: - dprintk("SET MPEG MUX ON HOST BUS"); + dprintk("SET MPEG MUX ON HOST BUS\n"); reg_1288 |= (1 << 4); break; default: @@ -1526,7 +1533,7 @@ static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) switch (onoff) { case 0: /* only use the internal way - not the diversity input */ - dprintk("%s mode OFF : by default Enable Mpeg INPUT", + dprintk("%s mode OFF : by default Enable Mpeg INPUT\n", __func__); /* outputRate = 8 */ dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); @@ -1544,7 +1551,7 @@ static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) break; case 1: /* both ways */ case 2: /* only the diversity input */ - dprintk("%s ON : Enable diversity INPUT", __func__); + dprintk("%s ON : Enable diversity INPUT\n", __func__); dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); state->input_mode_mpeg = 0; break; @@ -1576,11 +1583,11 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_SERIAL: if (prefer_mpeg_mux_use) { - dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux"); + dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux\n"); dib8096p_configMpegMux(state, 3, 1, 1); dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); } else {/* Use Smooth block */ - dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc"); + dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc\n"); dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (2 << 6) | (0 << 1); @@ -1589,11 +1596,11 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_PAR_GATED_CLK: if (prefer_mpeg_mux_use) { - dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux\n"); dib8096p_configMpegMux(state, 2, 0, 0); dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); } else { /* Use Smooth block */ - dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block"); + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block\n"); dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (0 << 6); @@ -1601,7 +1608,7 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) break; case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ - dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block"); + dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block\n"); dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (1 << 6); break; @@ -1609,7 +1616,7 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ - dprintk("dib8096P setting output mode TS_FIFO using Smooth block"); + dprintk("dib8096P setting output mode TS_FIFO using Smooth block\n"); dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); outreg |= (5 << 6); smo_mode |= (3 << 1); @@ -1617,13 +1624,13 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) break; case OUTMODE_DIVERSITY: - dprintk("dib8096P setting output mode MODE_DIVERSITY"); + dprintk("dib8096P setting output mode MODE_DIVERSITY\n"); dib8096p_setDibTxMux(state, DIV_ON_DIBTX); dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; case OUTMODE_ANALOG_ADC: - dprintk("dib8096P setting output mode MODE_ANALOG_ADC"); + dprintk("dib8096P setting output mode MODE_ANALOG_ADC\n"); dib8096p_setDibTxMux(state, ADC_ON_DIBTX); dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; @@ -1632,7 +1639,7 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) if (mode != OUTMODE_HIGH_Z) outreg |= (1<<10); - dprintk("output_mpeg2_in_188_bytes = %d", + dprintk("output_mpeg2_in_188_bytes = %d\n", state->cfg.output_mpeg2_in_188_bytes); if (state->cfg.output_mpeg2_in_188_bytes) smo_mode |= (1 << 5); @@ -1678,7 +1685,7 @@ static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap, n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; i--; if (i == 0) - dprintk("Tuner ITF: write busy (overflow)"); + dprintk("Tuner ITF: write busy (overflow)\n"); } dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); @@ -1699,7 +1706,7 @@ static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; i--; if (i == 0) - dprintk("TunerITF: read busy (overflow)"); + dprintk("TunerITF: read busy (overflow)\n"); } dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f)); @@ -1708,7 +1715,7 @@ static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, n_empty = dib8000_read_word(state, 1984)&0x1; i--; if (i == 0) - dprintk("TunerITF: read busy (empty)"); + dprintk("TunerITF: read busy (empty)\n"); } read_word = dib8000_read_word(state, 1987); @@ -1889,7 +1896,7 @@ static int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) struct dib8000_state *state = fe->demodulator_priv; u16 en_cur_state; - dprintk("sleep dib8096p: %d", onoff); + dprintk("sleep dib8096p: %d\n", onoff); en_cur_state = dib8000_read_word(state, 1922); @@ -1958,7 +1965,7 @@ static void dib8000_update_timf(struct dib8000_state *state) dib8000_write_word(state, 29, (u16) (timf >> 16)); dib8000_write_word(state, 30, (u16) (timf & 0xffff)); - dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); + dprintk("Updated timing frequency: %d (default: %d)\n", state->timf, state->timf_default); } static u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) @@ -2118,7 +2125,7 @@ static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel) int sub_channel_prbs_group = 0; sub_channel_prbs_group = (subchannel / 3) + 1; - dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]); + dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]); switch (state->fe[0]->dtv_property_cache.transmission_mode) { case TRANSMISSION_MODE_2K: @@ -2604,7 +2611,7 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe) slist = 0; } } - dprintk("Using list for autosearch : %d", slist); + dprintk("Using list for autosearch : %d\n", slist); dib8000_set_isdbt_common_channel(state, slist, 1); @@ -2638,17 +2645,17 @@ static int dib8000_autosearch_irq(struct dvb_frontend *fe) if ((state->revision >= 0x8002) && (state->autosearch_state == AS_SEARCHING_FFT)) { if (irq_pending & 0x1) { - dprintk("dib8000_autosearch_irq: max correlation result available"); + dprintk("dib8000_autosearch_irq: max correlation result available\n"); return 3; } } else { if (irq_pending & 0x1) { /* failed */ - dprintk("dib8000_autosearch_irq failed"); + dprintk("dib8000_autosearch_irq failed\n"); return 1; } if (irq_pending & 0x2) { /* succeeded */ - dprintk("dib8000_autosearch_irq succeeded"); + dprintk("dib8000_autosearch_irq succeeded\n"); return 2; } } @@ -2699,7 +2706,7 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz) dds += abs_offset_khz * unit_khz_dds_val; } - dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val); + dprintk("setting a DDS frequency offset of %c%dkHz\n", invert ? '-' : ' ', dds / unit_khz_dds_val); if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) { /* Max dds offset is the half of the demod freq */ @@ -2738,7 +2745,7 @@ static void dib8000_set_frequency_offset(struct dib8000_state *state) } } - dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d", c->frequency - current_rf, c->frequency, current_rf, total_dds_offset_khz); + dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d\n", c->frequency - current_rf, c->frequency, current_rf, total_dds_offset_khz); /* apply dds offset now */ dib8000_set_dds(state, total_dds_offset_khz); @@ -2890,7 +2897,7 @@ static u16 dib8000_read_lock(struct dvb_frontend *fe) static int dib8090p_init_sdram(struct dib8000_state *state) { u16 reg = 0; - dprintk("init sdram"); + dprintk("init sdram\n"); reg = dib8000_read_word(state, 274) & 0xfff0; dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */ @@ -2931,7 +2938,7 @@ static int is_manual_mode(struct dtv_frontend_properties *c) * Transmission mode is only detected on auto mode, currently */ if (c->transmission_mode == TRANSMISSION_MODE_AUTO) { - dprintk("transmission mode auto"); + dprintk("transmission mode auto\n"); return 0; } @@ -2939,7 +2946,7 @@ static int is_manual_mode(struct dtv_frontend_properties *c) * Guard interval is only detected on auto mode, currently */ if (c->guard_interval == GUARD_INTERVAL_AUTO) { - dprintk("guard interval auto"); + dprintk("guard interval auto\n"); return 0; } @@ -2948,7 +2955,7 @@ static int is_manual_mode(struct dtv_frontend_properties *c) * layer should be enabled */ if (!c->isdbt_layer_enabled) { - dprintk("no layer modulation specified"); + dprintk("no layer modulation specified\n"); return 0; } @@ -2970,7 +2977,7 @@ static int is_manual_mode(struct dtv_frontend_properties *c) if ((c->layer[i].modulation == QAM_AUTO) || (c->layer[i].fec == FEC_AUTO)) { - dprintk("layer %c has either modulation or FEC auto", + dprintk("layer %c has either modulation or FEC auto\n", 'A' + i); return 0; } @@ -2981,7 +2988,7 @@ static int is_manual_mode(struct dtv_frontend_properties *c) * fallback to auto mode. */ if (n_segs == 0 || n_segs > 13) { - dprintk("number of segments is invalid"); + dprintk("number of segments is invalid\n"); return 0; } @@ -3009,7 +3016,7 @@ static int dib8000_tune(struct dvb_frontend *fe) #if 0 if (*tune_state < CT_DEMOD_STOP) - dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u jiffies = %lu", + dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u jiffies = %lu\n", state->channel_parameters_set, *tune_state, state->autosearch_state, now); #endif @@ -3022,7 +3029,7 @@ static int dib8000_tune(struct dvb_frontend *fe) state->status = FE_STATUS_TUNE_PENDING; state->channel_parameters_set = is_manual_mode(c); - dprintk("Tuning channel on %s search mode", + dprintk("Tuning channel on %s search mode\n", state->channel_parameters_set ? "manual" : "auto"); dib8000_viterbi_state(state, 0); /* force chan dec in restart */ @@ -3102,7 +3109,7 @@ static int dib8000_tune(struct dvb_frontend *fe) corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597)); corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599)); } - /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */ + /* dprintk("corm fft: %u %u %u\n", corm[0], corm[1], corm[2]); */ max_value = 0; for (find_index = 1 ; find_index < 3 ; find_index++) { @@ -3122,7 +3129,7 @@ static int dib8000_tune(struct dvb_frontend *fe) state->found_nfft = TRANSMISSION_MODE_8K; break; } - /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */ + /* dprintk("Autosearch FFT has found Mode %d\n", max_value + 1); */ *tune_state = CT_DEMOD_SEARCH_NEXT; state->autosearch_state = AS_SEARCHING_GUARD; @@ -3137,7 +3144,7 @@ static int dib8000_tune(struct dvb_frontend *fe) state->found_guard = dib8000_read_word(state, 572) & 0x3; else state->found_guard = dib8000_read_word(state, 570) & 0x3; - /* dprintk("guard interval found=%i", state->found_guard); */ + /* dprintk("guard interval found=%i\n", state->found_guard); */ *tune_state = CT_DEMOD_STEP_3; break; @@ -3233,7 +3240,7 @@ static int dib8000_tune(struct dvb_frontend *fe) /* defines timeout for mpeg lock depending on interleaver length of longest layer */ for (i = 0; i < 3; i++) { if (c->layer[i].interleaving >= deeper_interleaver) { - dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving); + dprintk("layer%i: time interleaver = %d\n", i, c->layer[i].interleaving); if (c->layer[i].segment_count > 0) { /* valid layer */ deeper_interleaver = c->layer[0].interleaving; state->longest_intlv_layer = i; @@ -3252,7 +3259,7 @@ static int dib8000_tune(struct dvb_frontend *fe) locks *= 2; *timeout = now + msecs_to_jiffies(200 * locks); /* give the mpeg lock 800ms if sram is present */ - dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %ld", + dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %ld\n", deeper_interleaver, state->longest_intlv_layer, locks, *timeout); *tune_state = CT_DEMOD_STEP_10; @@ -3263,7 +3270,7 @@ static int dib8000_tune(struct dvb_frontend *fe) case CT_DEMOD_STEP_10: /* 40 */ locks = dib8000_read_lock(fe); if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */ - dprintk("ISDB-T layer locks: Layer A %s, Layer B %s, Layer C %s", + dprintk("ISDB-T layer locks: Layer A %s, Layer B %s, Layer C %s\n", c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", c->layer[2].segment_count ? (locks >> 5) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled"); @@ -3283,7 +3290,7 @@ static int dib8000_tune(struct dvb_frontend *fe) *tune_state = CT_DEMOD_STEP_11; } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */ if (locks & (0x7 << 5)) { - dprintk("Not all ISDB-T layers locked in %d ms: Layer A %s, Layer B %s, Layer C %s", + dprintk("Not all ISDB-T layers locked in %d ms: Layer A %s, Layer B %s, Layer C %s\n", jiffies_to_msecs(now - *timeout), c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", @@ -3348,7 +3355,7 @@ static int dib8000_wakeup(struct dvb_frontend *fe) dib8000_set_power_mode(state, DIB8000_POWER_ALL); dib8000_set_adc_state(state, DIBX000_ADC_ON); if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) - dprintk("could not start Slow ADC"); + dprintk("could not start Slow ADC\n"); if (state->revision == 0x8090) dib8000_sad_calib(state); @@ -3401,11 +3408,11 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, if (!(stat & FE_HAS_SYNC)) return 0; - dprintk("dib8000_get_frontend: TMCC lock"); + dprintk("dib8000_get_frontend: TMCC lock\n"); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); if (stat&FE_HAS_SYNC) { - dprintk("TMCC lock on the slave%i", index_frontend); + dprintk("TMCC lock on the slave%i\n", index_frontend); /* synchronize the cache with the other frontends */ state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], c); for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { @@ -3437,41 +3444,41 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, switch ((val & 0x30) >> 4) { case 1: c->transmission_mode = TRANSMISSION_MODE_2K; - dprintk("dib8000_get_frontend: transmission mode 2K"); + dprintk("dib8000_get_frontend: transmission mode 2K\n"); break; case 2: c->transmission_mode = TRANSMISSION_MODE_4K; - dprintk("dib8000_get_frontend: transmission mode 4K"); + dprintk("dib8000_get_frontend: transmission mode 4K\n"); break; case 3: default: c->transmission_mode = TRANSMISSION_MODE_8K; - dprintk("dib8000_get_frontend: transmission mode 8K"); + dprintk("dib8000_get_frontend: transmission mode 8K\n"); break; } switch (val & 0x3) { case 0: c->guard_interval = GUARD_INTERVAL_1_32; - dprintk("dib8000_get_frontend: Guard Interval = 1/32 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/32\n"); break; case 1: c->guard_interval = GUARD_INTERVAL_1_16; - dprintk("dib8000_get_frontend: Guard Interval = 1/16 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/16\n"); break; case 2: - dprintk("dib8000_get_frontend: Guard Interval = 1/8 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/8\n"); c->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - dprintk("dib8000_get_frontend: Guard Interval = 1/4 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/4\n"); c->guard_interval = GUARD_INTERVAL_1_4; break; } val = dib8000_read_word(state, 505); c->isdbt_partial_reception = val & 1; - dprintk("dib8000_get_frontend: partial_reception = %d ", c->isdbt_partial_reception); + dprintk("dib8000_get_frontend: partial_reception = %d\n", c->isdbt_partial_reception); for (i = 0; i < 3; i++) { int show; @@ -3485,7 +3492,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, show = 1; if (show) - dprintk("dib8000_get_frontend: Layer %d segments = %d ", + dprintk("dib8000_get_frontend: Layer %d segments = %d\n", i, c->layer[i].segment_count); val = dib8000_read_word(state, 499 + i) & 0x3; @@ -3494,7 +3501,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, val = 4; c->layer[i].interleaving = val; if (show) - dprintk("dib8000_get_frontend: Layer %d time_intlv = %d ", + dprintk("dib8000_get_frontend: Layer %d time_intlv = %d\n", i, c->layer[i].interleaving); val = dib8000_read_word(state, 481 + i); @@ -3502,27 +3509,27 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, case 1: c->layer[i].fec = FEC_1_2; if (show) - dprintk("dib8000_get_frontend: Layer %d Code Rate = 1/2 ", i); + dprintk("dib8000_get_frontend: Layer %d Code Rate = 1/2\n", i); break; case 2: c->layer[i].fec = FEC_2_3; if (show) - dprintk("dib8000_get_frontend: Layer %d Code Rate = 2/3 ", i); + dprintk("dib8000_get_frontend: Layer %d Code Rate = 2/3\n", i); break; case 3: c->layer[i].fec = FEC_3_4; if (show) - dprintk("dib8000_get_frontend: Layer %d Code Rate = 3/4 ", i); + dprintk("dib8000_get_frontend: Layer %d Code Rate = 3/4\n", i); break; case 5: c->layer[i].fec = FEC_5_6; if (show) - dprintk("dib8000_get_frontend: Layer %d Code Rate = 5/6 ", i); + dprintk("dib8000_get_frontend: Layer %d Code Rate = 5/6\n", i); break; default: c->layer[i].fec = FEC_7_8; if (show) - dprintk("dib8000_get_frontend: Layer %d Code Rate = 7/8 ", i); + dprintk("dib8000_get_frontend: Layer %d Code Rate = 7/8\n", i); break; } @@ -3531,23 +3538,23 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, case 0: c->layer[i].modulation = DQPSK; if (show) - dprintk("dib8000_get_frontend: Layer %d DQPSK ", i); + dprintk("dib8000_get_frontend: Layer %d DQPSK\n", i); break; case 1: c->layer[i].modulation = QPSK; if (show) - dprintk("dib8000_get_frontend: Layer %d QPSK ", i); + dprintk("dib8000_get_frontend: Layer %d QPSK\n", i); break; case 2: c->layer[i].modulation = QAM_16; if (show) - dprintk("dib8000_get_frontend: Layer %d QAM16 ", i); + dprintk("dib8000_get_frontend: Layer %d QAM16\n", i); break; case 3: default: c->layer[i].modulation = QAM_64; if (show) - dprintk("dib8000_get_frontend: Layer %d QAM64 ", i); + dprintk("dib8000_get_frontend: Layer %d QAM64\n", i); break; } } @@ -3578,12 +3585,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) unsigned long delay, callback_time; if (c->frequency == 0) { - dprintk("dib8000: must at least specify frequency "); + dprintk("dib8000: must at least specify frequency\n"); return 0; } if (c->bandwidth_hz == 0) { - dprintk("dib8000: no bandwidth specified, set to default "); + dprintk("dib8000: no bandwidth specified, set to default\n"); c->bandwidth_hz = 6000000; } @@ -3671,7 +3678,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) /* we are in autosearch */ if (state->channel_parameters_set == 0) { /* searching */ if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) { - dprintk("autosearch succeeded on fe%i", index_frontend); + dprintk("autosearch succeeded on fe%i\n", index_frontend); dib8000_get_frontend(state->fe[index_frontend], c); /* we read the channel parameters from the frontend which was successful */ state->channel_parameters_set = 1; @@ -3708,11 +3715,11 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) active = 1; } if (active == 0) - dprintk("tuning done with status %d", dib8000_get_status(state->fe[0])); + dprintk("tuning done with status %d\n", dib8000_get_status(state->fe[0])); } if ((active == 1) && (callback_time == 0)) { - dprintk("strange callback time something went wrong"); + dprintk("strange callback time something went wrong\n"); active = 0; } @@ -4172,7 +4179,7 @@ static int dib8000_get_stats(struct dvb_frontend *fe, enum fe_status stat) time_us = dib8000_get_time_us(fe, -1); state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); - dprintk("Next all layers stats available in %u us.", time_us); + dprintk("Next all layers stats available in %u us.\n", time_us); dib8000_read_ber(fe, &val); c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; @@ -4239,12 +4246,12 @@ static int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_fronte while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) index_frontend++; if (index_frontend < MAX_NUMBER_OF_FRONTENDS) { - dprintk("set slave fe %p to index %i", fe_slave, index_frontend); + dprintk("set slave fe %p to index %i\n", fe_slave, index_frontend); state->fe[index_frontend] = fe_slave; return 0; } - dprintk("too many slave frontend"); + dprintk("too many slave frontend\n"); return -ENOMEM; } @@ -4256,12 +4263,12 @@ static int dib8000_remove_slave_frontend(struct dvb_frontend *fe) while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) index_frontend++; if (index_frontend != 1) { - dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1); + dprintk("remove slave fe %p (index %i)\n", state->fe[index_frontend-1], index_frontend-1); state->fe[index_frontend] = NULL; return 0; } - dprintk("no frontend to be removed"); + dprintk("no frontend to be removed\n"); return -ENODEV; } @@ -4283,18 +4290,18 @@ static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); if (!client.i2c_write_buffer) { - dprintk("%s: not enough memory", __func__); + dprintk("%s: not enough memory\n", __func__); return -ENOMEM; } client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); if (!client.i2c_read_buffer) { - dprintk("%s: not enough memory", __func__); + dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; goto error_memory_read; } client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); if (!client.i2c_buffer_lock) { - dprintk("%s: not enough memory", __func__); + dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; goto error_memory_lock; } @@ -4313,7 +4320,7 @@ static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, dib8000_i2c_write16(&client, 1287, 0x0003); client.addr = default_addr; if (dib8000_identify(&client) == 0) { - dprintk("#%d: not identified", k); + dprintk("#%d: not identified\n", k); ret = -EINVAL; goto error; } @@ -4327,7 +4334,7 @@ static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, client.addr = new_addr; dib8000_identify(&client); - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); + dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); } for (k = 0; k < no_of_demods; k++) { @@ -4385,14 +4392,14 @@ static int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) u16 val = dib8000_read_word(st, 299) & 0xffef; val |= (onoff & 0x1) << 4; - dprintk("pid filter enabled %d", onoff); + dprintk("pid filter enabled %d\n", onoff); return dib8000_write_word(st, 299, val); } static int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib8000_state *st = fe->demodulator_priv; - dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); + dprintk("Index %x, PID %d, OnOff %d\n", id, pid, onoff); return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); } @@ -4431,7 +4438,7 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad struct dvb_frontend *fe; struct dib8000_state *state; - dprintk("dib8000_init"); + dprintk("dib8000_init\n"); state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); if (state == NULL) -- cgit v1.2.3 From 3dd722622f1d2a795d8cb196eb245fab1946bee2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 10:08:40 -0300 Subject: [media] dib9000: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a\n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib9000.c | 171 ++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 82 deletions(-) diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 5897977d2d00..3c76ceb6c374 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -7,6 +7,9 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -21,7 +24,12 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) + #define MAX_NUMBER_OF_FRONTENDS 6 struct i2c_device { @@ -258,7 +266,7 @@ static int dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 *b, u32 state->msg[1].buf = b; ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0; if (ret != 0) { - dprintk("i2c read error on %d", reg); + dprintk("i2c read error on %d\n", reg); return -EREMOTEIO; } @@ -285,7 +293,7 @@ static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg) i2c->i2c_write_buffer[1] = reg & 0xff; if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) { - dprintk("read register %x error", reg); + dprintk("read register %x error\n", reg); return 0; } @@ -440,7 +448,7 @@ static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u1 return -EIO; if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } dib9000_risc_mem_setup(state, cmd | 0x80); @@ -456,7 +464,7 @@ static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 return -EIO; if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } dib9000_risc_mem_setup(state, cmd); @@ -479,13 +487,13 @@ static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u1 dib9000_write_word(state, 1025 + offs, 0); dib9000_write_word(state, 1031 + offs, key); - dprintk("going to download %dB of microcode", len); + dprintk("going to download %dB of microcode\n", len); if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) { - dprintk("error while downloading microcode for RISC %c", 'A' + risc_id); + dprintk("error while downloading microcode for RISC %c\n", 'A' + risc_id); return -EIO; } - dprintk("Microcode for RISC %c loaded", 'A' + risc_id); + dprintk("Microcode for RISC %c loaded\n", 'A' + risc_id); return 0; } @@ -511,10 +519,10 @@ static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id) } while ((reset_reg & 0x8000) && --tries); if (reset_reg & 0x8000) { - dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id); + dprintk("MBX: init ERROR, no response from RISC %c\n", 'A' + risc_id); return -EIO; } - dprintk("MBX: initialized"); + dprintk("MBX: initialized\n"); return 0; } @@ -531,30 +539,27 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, return -EINVAL; if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } tmp = MAX_MAILBOX_TRY; do { size = dib9000_read_word_attr(state, 1043, attr) & 0xff; if ((size + len + 1) > MBX_MAX_WORDS && --tmp) { - dprintk("MBX: RISC mbx full, retrying"); + dprintk("MBX: RISC mbx full, retrying\n"); msleep(100); } else break; } while (1); - /*dprintk( "MBX: size: %d", size); */ + /*dprintk( "MBX: size: %d\n", size); */ if (tmp == 0) { ret = -EINVAL; goto out; } #ifdef DUMP_MSG - dprintk("--> %02x %d ", id, len + 1); - for (i = 0; i < len; i++) - dprintk("%04x ", data[i]); - dprintk("\n"); + dprintk("--> %02x %d %*ph\n", id, len + 1, len, data); #endif /* byte-order conversion - works on big (where it is not necessary) or little endian */ @@ -596,7 +601,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, return 0; if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return 0; } if (risc_id == 1) @@ -622,13 +627,13 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, } #ifdef DUMP_MSG - dprintk("<-- "); + dprintk("<--\n"); for (i = 0; i < size + 1; i++) - dprintk("%04x ", d[i]); + dprintk("%04x\n", d[i]); dprintk("\n"); #endif } else { - dprintk("MBX: message is too big for message cache (%d), flushing message", size); + dprintk("MBX: message is too big for message cache (%d), flushing message\n", size); size--; /* Initial word already read */ while (size--) dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr); @@ -649,9 +654,11 @@ static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 si b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */ if (*b == '~') { b++; - dprintk("%s", b); + dprintk("%s\n", b); } else - dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : ""); + dprintk("RISC%d: %d.%04d %s\n", + state->fe_id, + ts / 10000, ts % 10000, *b ? b : ""); return 1; } @@ -666,7 +673,7 @@ static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr) if (*block == 0) { size = dib9000_mbx_read(state, block, 1, attr); -/* dprintk( "MBX: fetched %04x message to cache", *block); */ +/* dprintk( "MBX: fetched %04x message to cache\n", *block); */ switch (*block >> 8) { case IN_MSG_DEBUG_BUF: @@ -686,7 +693,7 @@ static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr) return 1; } } - dprintk("MBX: no free cache-slot found for new message..."); + dprintk("MBX: no free cache-slot found for new message...\n"); return -1; } @@ -706,7 +713,7 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) return -1; if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -1; } @@ -715,7 +722,7 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */ /* if (tmp) */ -/* dprintk( "cleared IRQ: %x", tmp); */ +/* dprintk( "cleared IRQ: %x\n", tmp); */ mutex_unlock(&state->platform.risc.mbx_lock); return ret; @@ -750,7 +757,7 @@ static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 } while (--timeout); if (timeout == 0) { - dprintk("waiting for message %d timed out", id); + dprintk("waiting for message %d timed out\n", id); return -1; } @@ -770,7 +777,7 @@ static int dib9000_risc_check_version(struct dib9000_state *state) return -EIO; fw_version = (r[0] << 8) | r[1]; - dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]); + dprintk("RISC: ver: %d.%02d (IC: %d)\n", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]); if ((fw_version >> 10) != 7) return -EINVAL; @@ -850,40 +857,40 @@ static u16 dib9000_identify(struct i2c_device *client) value = dib9000_i2c_read16(client, 896); if (value != 0x01b3) { - dprintk("wrong Vendor ID (0x%x)", value); + dprintk("wrong Vendor ID (0x%x)\n", value); return 0; } value = dib9000_i2c_read16(client, 897); if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) { - dprintk("wrong Device ID (0x%x)", value); + dprintk("wrong Device ID (0x%x)\n", value); return 0; } /* protect this driver to be used with 7000PC */ if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) { - dprintk("this driver does not work with DiB7000PC"); + dprintk("this driver does not work with DiB7000PC\n"); return 0; } switch (value) { case 0x4000: - dprintk("found DiB7000MA/PA/MB/PB"); + dprintk("found DiB7000MA/PA/MB/PB\n"); break; case 0x4001: - dprintk("found DiB7000HC"); + dprintk("found DiB7000HC\n"); break; case 0x4002: - dprintk("found DiB7000MC"); + dprintk("found DiB7000MC\n"); break; case 0x4003: - dprintk("found DiB9000A"); + dprintk("found DiB9000A\n"); break; case 0x4004: - dprintk("found DiB9000H"); + dprintk("found DiB9000H\n"); break; case 0x4005: - dprintk("found DiB9000M"); + dprintk("found DiB9000M\n"); break; } @@ -1013,7 +1020,7 @@ static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address if (address >= 1024 || !state->platform.risc.fw_is_running) return -EINVAL; - /* dprintk( "APB access thru rd fw %d %x", address, attribute); */ + /* dprintk( "APB access thru rd fw %d %x\n", address, attribute); */ mb[0] = (u16) address; mb[1] = len / 2; @@ -1043,7 +1050,7 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres if (len > 18) return -EINVAL; - /* dprintk( "APB access thru wr fw %d %x", address, attribute); */ + /* dprintk( "APB access thru wr fw %d %x\n", address, attribute); */ mb[0] = (u16)address; for (i = 0; i + 1 < len; i += 2) @@ -1191,7 +1198,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe) int ret = 0; if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { @@ -1534,7 +1541,7 @@ static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode) struct dib9000_state *state = fe->demodulator_priv; u16 outreg, smo_mode; - dprintk("setting output mode for demod %p to %d", fe, mode); + dprintk("setting output mode for demod %p to %d\n", fe, mode); switch (mode) { case OUTMODE_MPEG2_PAR_GATED_CLK: @@ -1556,7 +1563,7 @@ static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode) outreg = 0; break; default: - dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]); + dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->fe[0]); return -EINVAL; } @@ -1590,7 +1597,7 @@ static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] len = 16; if (dib9000_read_word(state, 790) != 0) - dprintk("TunerITF: read busy"); + dprintk("TunerITF: read busy\n"); dib9000_write_word(state, 784, (u16) (msg[index_msg].addr)); dib9000_write_word(state, 787, (len / 2) - 1); @@ -1601,7 +1608,7 @@ static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] i--; if (i == 0) - dprintk("TunerITF: read failed"); + dprintk("TunerITF: read failed\n"); for (i = 0; i < len; i += 2) { t = dib9000_read_word(state, 785); @@ -1609,13 +1616,13 @@ static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] msg[index_msg].buf[i + 1] = (t) & 0xff; } if (dib9000_read_word(state, 790) != 0) - dprintk("TunerITF: read more data than expected"); + dprintk("TunerITF: read more data than expected\n"); } else { i = 1000; while (dib9000_read_word(state, 789) && i) i--; if (i == 0) - dprintk("TunerITF: write busy"); + dprintk("TunerITF: write busy\n"); len = msg[index_msg].len; if (len > 16) @@ -1631,7 +1638,7 @@ static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] while (dib9000_read_word(state, 791) > 0 && i) i--; if (i == 0) - dprintk("TunerITF: write failed"); + dprintk("TunerITF: write failed\n"); } } return num; @@ -1676,7 +1683,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2 } if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return 0; } @@ -1759,7 +1766,7 @@ static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val) st->gpio_val |= (val & 0x01) << num; /* set the new value */ dib9000_write_word(st, 774, st->gpio_val); - dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val); + dprintk("gpio dir: %04x: gpio val: %04x\n", st->gpio_dir, st->gpio_val); return 0; } @@ -1779,7 +1786,7 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) { /* postpone the pid filtering cmd */ - dprintk("pid filter cmd postpone"); + dprintk("pid filter cmd postpone\n"); state->pid_ctrl_index++; state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL; state->pid_ctrl[state->pid_ctrl_index].onoff = onoff; @@ -1787,14 +1794,14 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) } if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } val = dib9000_read_word(state, 294 + 1) & 0xffef; val |= (onoff & 0x1) << 4; - dprintk("PID filter enabled %d", onoff); + dprintk("PID filter enabled %d\n", onoff); ret = dib9000_write_word(state, 294 + 1, val); mutex_unlock(&state->demod_lock); return ret; @@ -1809,7 +1816,7 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) if (state->pid_ctrl_index != -2) { /* postpone the pid filtering cmd */ - dprintk("pid filter postpone"); + dprintk("pid filter postpone\n"); if (state->pid_ctrl_index < 9) { state->pid_ctrl_index++; state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER; @@ -1817,15 +1824,15 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) state->pid_ctrl[state->pid_ctrl_index].pid = pid; state->pid_ctrl[state->pid_ctrl_index].onoff = onoff; } else - dprintk("can not add any more pid ctrl cmd"); + dprintk("can not add any more pid ctrl cmd\n"); return 0; } if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } - dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); + dprintk("Index %x, PID %d, OnOff %d\n", id, pid, onoff); ret = dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0); mutex_unlock(&state->demod_lock); @@ -1868,7 +1875,7 @@ static int dib9000_sleep(struct dvb_frontend *fe) int ret = 0; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { @@ -1899,7 +1906,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, if (state->get_frontend_internal == 0) { if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } } @@ -1907,7 +1914,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); if (stat & FE_HAS_SYNC) { - dprintk("TPS lock on the slave%i", index_frontend); + dprintk("TPS lock on the slave%i\n", index_frontend); /* synchronize the cache with the other frontends */ state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], c); @@ -1995,18 +2002,18 @@ static int dib9000_set_frontend(struct dvb_frontend *fe) /* check that the correct parameters are set */ if (state->fe[0]->dtv_property_cache.frequency == 0) { - dprintk("dib9000: must specify frequency "); + dprintk("dib9000: must specify frequency\n"); return 0; } if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) { - dprintk("dib9000: must specify bandwidth "); + dprintk("dib9000: must specify bandwidth\n"); return 0; } state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return 0; } @@ -2073,14 +2080,14 @@ static int dib9000_set_frontend(struct dvb_frontend *fe) /* check the tune result */ if (exit_condition == 1) { /* tune failed */ - dprintk("tune failed"); + dprintk("tune failed\n"); mutex_unlock(&state->demod_lock); /* tune failed; put all the pid filtering cmd to junk */ state->pid_ctrl_index = -1; return 0; } - dprintk("tune success on frontend%i", index_frontend_success); + dprintk("tune success on frontend%i\n", index_frontend_success); /* synchronize all the channel cache */ state->get_frontend_internal = 1; @@ -2169,7 +2176,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, enum fe_status *stat) u16 lock = 0, lock_slave = 0; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) @@ -2202,11 +2209,11 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) int ret = 0; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); ret = -EINTR; goto error; } @@ -2237,7 +2244,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) int ret = 0; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } *strength = 0; @@ -2250,7 +2257,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) } if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); ret = -EINTR; goto error; } @@ -2281,7 +2288,7 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe) u16 val; if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return 0; } if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { @@ -2320,7 +2327,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) u32 snr_master; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } snr_master = dib9000_get_snr(fe); @@ -2345,11 +2352,11 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) int ret = 0; if (mutex_lock_interruptible(&state->demod_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); return -EINTR; } if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { - dprintk("could not get the lock"); + dprintk("could not get the lock\n"); ret = -EINTR; goto error; } @@ -2376,12 +2383,12 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); if (!client.i2c_write_buffer) { - dprintk("%s: not enough memory", __func__); + dprintk("%s: not enough memory\n", __func__); return -ENOMEM; } client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); if (!client.i2c_read_buffer) { - dprintk("%s: not enough memory", __func__); + dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; goto error_memory; } @@ -2408,7 +2415,7 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul if (dib9000_identify(&client) == 0) { client.i2c_addr = default_addr; if (dib9000_identify(&client) == 0) { - dprintk("DiB9000 #%d: not identified", k); + dprintk("DiB9000 #%d: not identified\n", k); ret = -EIO; goto error; } @@ -2417,7 +2424,7 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6)); dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2); - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); + dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); } for (k = 0; k < no_of_demods; k++) { @@ -2445,12 +2452,12 @@ int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_ while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) index_frontend++; if (index_frontend < MAX_NUMBER_OF_FRONTENDS) { - dprintk("set slave fe %p to index %i", fe_slave, index_frontend); + dprintk("set slave fe %p to index %i\n", fe_slave, index_frontend); state->fe[index_frontend] = fe_slave; return 0; } - dprintk("too many slave frontend"); + dprintk("too many slave frontend\n"); return -ENOMEM; } EXPORT_SYMBOL(dib9000_set_slave_frontend); @@ -2463,12 +2470,12 @@ int dib9000_remove_slave_frontend(struct dvb_frontend *fe) while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) index_frontend++; if (index_frontend != 1) { - dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1); + dprintk("remove slave fe %p (index %i)\n", state->fe[index_frontend - 1], index_frontend - 1); state->fe[index_frontend] = NULL; return 0; } - dprintk("no frontend to be removed"); + dprintk("no frontend to be removed\n"); return -ENODEV; } EXPORT_SYMBOL(dib9000_remove_slave_frontend); -- cgit v1.2.3 From 0a6dc89ae403cb41872249d3d85efa6d50f7f097 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 10:28:42 -0300 Subject: [media] dibx000_common: use pr_foo() instead of printk() The dprintk() macro relies on continuation lines. This is not a good practice and will break after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, instead of directly calling printk(), use pr_foo() macros, adding a \n leading char on each macro call. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dibx000_common.c | 36 +++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c index 723358d7ca84..7db908ed87f6 100644 --- a/drivers/media/dvb-frontends/dibx000_common.c +++ b/drivers/media/dvb-frontends/dibx000_common.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -8,14 +10,18 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0) +#define dprintk(fmt, arg...) do { \ + if (debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ + __func__, ##arg); \ +} while (0) static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) { int ret; if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -41,7 +47,7 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) u16 ret; if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return 0; } @@ -59,7 +65,7 @@ static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) mst->msg[1].len = 2; if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2) - dprintk("i2c read error on %d", reg); + dprintk("i2c read error on %d\n", reg); ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1]; mutex_unlock(&mst->i2c_buffer_lock); @@ -192,7 +198,7 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) { if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { - dprintk("selecting interface: %d", intf); + dprintk("selecting interface: %d\n", intf); mst->selected_interface = intf; return dibx000_write_word(mst, mst->base_reg + 4, intf); } @@ -290,7 +296,7 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap, dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } @@ -337,7 +343,7 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num)); @@ -391,7 +397,7 @@ struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, i2c = &mst->master_i2c_adap_gpio67; break; default: - printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); + pr_err("incorrect I2C interface selected\n"); break; } @@ -434,7 +440,7 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, mutex_init(&mst->i2c_buffer_lock); if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); + dprintk("could not acquire lock\n"); return -EINVAL; } memset(mst->msg, 0, sizeof(struct i2c_msg)); @@ -456,29 +462,25 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, if (i2c_adapter_init (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0) - printk(KERN_ERR - "DiBX000: could not initialize the tuner i2c_adapter\n"); + pr_err("could not initialize the tuner i2c_adapter\n"); mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent; if (i2c_adapter_init (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo, "DiBX000 master GPIO12 I2C bus", mst) != 0) - printk(KERN_ERR - "DiBX000: could not initialize the master i2c_adapter\n"); + pr_err("could not initialize the master i2c_adapter\n"); mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent; if (i2c_adapter_init (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo, "DiBX000 master GPIO34 I2C bus", mst) != 0) - printk(KERN_ERR - "DiBX000: could not initialize the master i2c_adapter\n"); + pr_err("could not initialize the master i2c_adapter\n"); mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent; if (i2c_adapter_init (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo, "DiBX000 master GPIO67 I2C bus", mst) != 0) - printk(KERN_ERR - "DiBX000: could not initialize the master i2c_adapter\n"); + pr_err("could not initialize the master i2c_adapter\n"); /* initialize the i2c-master by closing the gate */ dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0); -- cgit v1.2.3 From cc8e7ff440668d3934e12139d5daae94f4be356e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Oct 2016 10:44:04 -0300 Subject: [media] af9005: remove a printk that would require a KERN_CONT The dvb-usb system has its own macro to print hexa dumps (debug_dump). Such macro doesn't support messages with KERN_CONT after commit 563873318d32 ("Merge branch 'printk-cleanups'"). So, let's get rid of a printk() that would be assuming that this would work. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/af9005.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c index 7853261906b1..f5f476841aea 100644 --- a/drivers/media/usb/dvb-usb/af9005.c +++ b/drivers/media/usb/dvb-usb/af9005.c @@ -826,7 +826,6 @@ static int af9005_frontend_attach(struct dvb_usb_adapter *adap) printk("EEPROM DUMP\n"); for (i = 0; i < 255; i += 8) { af9005_read_eeprom(adap->dev, i, buf, 8); - printk("ADDR %x ", i); debug_dump(buf, 8, printk); } } -- cgit v1.2.3 From 680d87c0a9e3aa4a13ac54aa968173c8623c0f47 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 19 Oct 2016 18:12:03 -0200 Subject: [media] tuner-core: use pr_foo, instead of internal printk macros Tuner core uses its own printk internal macros, instead of the standard debug ones, for no good reason. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/tuner-core.c | 112 +++++++++++++++-------------------- 1 file changed, 49 insertions(+), 63 deletions(-) diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index d3a6236b6b02..05b5c6652cfa 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -84,30 +84,16 @@ static const struct v4l2_subdev_ops tuner_ops; * Debug macros */ -#define tuner_warn(fmt, arg...) do { \ - printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), \ - t->i2c->addr, ##arg); \ - } while (0) - -#define tuner_info(fmt, arg...) do { \ - printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), \ - t->i2c->addr, ##arg); \ - } while (0) - -#define tuner_err(fmt, arg...) do { \ - printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), \ - t->i2c->addr, ##arg); \ - } while (0) - -#define tuner_dbg(fmt, arg...) do { \ - if (tuner_debug) \ - printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), \ - t->i2c->addr, ##arg); \ - } while (0) +#undef pr_fmt + +#define pr_fmt(fmt) KBUILD_MODNAME ": %d-%04x: " fmt, \ + i2c_adapter_id(t->i2c->adapter), t->i2c->addr + + +#define dprintk(fmt, arg...) do { \ + if (tuner_debug) \ + printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg); \ +} while (0) /* * Internal struct used inside the driver @@ -208,7 +194,7 @@ static void fe_set_params(struct dvb_frontend *fe, struct tuner *t = fe->analog_demod_priv; if (NULL == fe_tuner_ops->set_analog_params) { - tuner_warn("Tuner frontend module has no way to set freq\n"); + pr_warn("Tuner frontend module has no way to set freq\n"); return; } fe_tuner_ops->set_analog_params(fe, params); @@ -230,7 +216,7 @@ static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) if (fe_tuner_ops->set_config) return fe_tuner_ops->set_config(fe, priv_cfg); - tuner_warn("Tuner frontend module has no way to set config\n"); + pr_warn("Tuner frontend module has no way to set config\n"); return 0; } @@ -273,14 +259,14 @@ static void set_type(struct i2c_client *c, unsigned int type, int tune_now = 1; if (type == UNSET || type == TUNER_ABSENT) { - tuner_dbg("tuner 0x%02x: Tuner type absent\n", c->addr); + dprintk("tuner 0x%02x: Tuner type absent\n", c->addr); return; } t->type = type; t->config = new_config; if (tuner_callback != NULL) { - tuner_dbg("defining GPIO callback\n"); + dprintk("defining GPIO callback\n"); t->fe.callback = tuner_callback; } @@ -442,7 +428,7 @@ static void set_type(struct i2c_client *c, unsigned int type, t->sd.entity.name = t->name; #endif - tuner_dbg("type set to %s\n", t->name); + dprintk("type set to %s\n", t->name); t->mode_mask = new_mode_mask; @@ -459,13 +445,13 @@ static void set_type(struct i2c_client *c, unsigned int type, set_tv_freq(c, t->tv_freq); } - tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", + dprintk("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", c->adapter->name, c->dev.driver->name, c->addr << 1, type, t->mode_mask); return; attach_failed: - tuner_dbg("Tuner attach for type = %d failed.\n", t->type); + dprintk("Tuner attach for type = %d failed.\n", t->type); t->type = TUNER_ABSENT; return; @@ -491,7 +477,7 @@ static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner *t = to_tuner(sd); struct i2c_client *c = v4l2_get_subdevdata(sd); - tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=%p\n", + dprintk("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=%p\n", tun_setup->type, tun_setup->addr, tun_setup->mode_mask, @@ -503,7 +489,7 @@ static int tuner_s_type_addr(struct v4l2_subdev *sd, set_type(c, tun_setup->type, tun_setup->mode_mask, tun_setup->config, tun_setup->tuner_callback); } else - tuner_dbg("set addr discarded for type %i, mask %x. Asked to change tuner at addr 0x%02x, with mask %x\n", + dprintk("set addr discarded for type %i, mask %x. Asked to change tuner at addr 0x%02x, with mask %x\n", t->type, t->mode_mask, tun_setup->addr, tun_setup->mode_mask); @@ -533,7 +519,7 @@ static int tuner_s_config(struct v4l2_subdev *sd, return 0; } - tuner_dbg("Tuner frontend module has no way to set config\n"); + dprintk("Tuner frontend module has no way to set config\n"); return 0; } @@ -622,7 +608,7 @@ static int tuner_probe(struct i2c_client *client, memset(buffer, 0, sizeof(buffer)); rc = i2c_master_recv(client, buffer, sizeof(buffer)); if (rc >= 0) - tuner_info("I2C RECV = %*ph\n", rc, buffer); + pr_info("I2C RECV = %*ph\n", rc, buffer); } /* autodetection code based on the i2c addr */ @@ -650,7 +636,7 @@ static int tuner_probe(struct i2c_client *client, since it can be tda9887*/ if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter, t->i2c->addr) >= 0) { - tuner_dbg("tda829x detected\n"); + dprintk("tda829x detected\n"); } else { /* Default is being tda9887 */ t->type = TUNER_TDA9887; @@ -687,7 +673,7 @@ static int tuner_probe(struct i2c_client *client, t->mode_mask = T_ANALOG_TV; if (radio == NULL) t->mode_mask |= T_RADIO; - tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask); + dprintk("Setting mode_mask to 0x%02x\n", t->mode_mask); } /* Should be just before return */ @@ -716,7 +702,7 @@ register_client: } if (ret < 0) { - tuner_err("failed to initialize media entity!\n"); + pr_err("failed to initialize media entity!\n"); kfree(t); return ret; } @@ -729,7 +715,7 @@ register_client: set_type(client, t->type, t->mode_mask, t->config, t->fe.callback); list_add_tail(&t->list, &tuner_list); - tuner_info("Tuner %d found with type(s)%s%s.\n", + pr_info("Tuner %d found with type(s)%s%s.\n", t->type, t->mode_mask & T_RADIO ? " Radio" : "", t->mode_mask & T_ANALOG_TV ? " TV" : ""); @@ -806,7 +792,7 @@ static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) if (mode != t->mode) { if (check_mode(t, mode) == -EINVAL) { - tuner_dbg("Tuner doesn't support mode %d. Putting tuner to sleep\n", + dprintk("Tuner doesn't support mode %d. Putting tuner to sleep\n", mode); t->standby = true; if (analog_ops->standby) @@ -814,7 +800,7 @@ static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) return -EINVAL; } t->mode = mode; - tuner_dbg("Changing to mode %d\n", mode); + dprintk("Changing to mode %d\n", mode); } return 0; } @@ -861,15 +847,15 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) }; if (t->type == UNSET) { - tuner_warn("tuner type not set\n"); + pr_warn("tuner type not set\n"); return; } if (NULL == analog_ops->set_params) { - tuner_warn("Tuner has no way to set tv freq\n"); + pr_warn("Tuner has no way to set tv freq\n"); return; } if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) { - tuner_dbg("TV freq (%d.%02d) out of range (%d-%d)\n", + dprintk("TV freq (%d.%02d) out of range (%d-%d)\n", freq / 16, freq % 16 * 100 / 16, tv_range[0], tv_range[1]); /* V4L2 spec: if the freq is not possible then the closest @@ -880,7 +866,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) freq = tv_range[1] * 16; } params.frequency = freq; - tuner_dbg("tv freq set to %d.%02d\n", + dprintk("tv freq set to %d.%02d\n", freq / 16, freq % 16 * 100 / 16); t->tv_freq = freq; t->standby = false; @@ -930,7 +916,7 @@ static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) return V4L2_STD_PAL_Nc; return V4L2_STD_PAL_N; default: - tuner_warn("pal= argument not recognised\n"); + pr_warn("pal= argument not recognised\n"); break; } } @@ -956,7 +942,7 @@ static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) return V4L2_STD_SECAM_LC; return V4L2_STD_SECAM_L; default: - tuner_warn("secam= argument not recognised\n"); + pr_warn("secam= argument not recognised\n"); break; } } @@ -973,7 +959,7 @@ static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) case 'K': return V4L2_STD_NTSC_M_KR; default: - tuner_info("ntsc= argument not recognised\n"); + pr_info("ntsc= argument not recognised\n"); break; } } @@ -1002,15 +988,15 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) }; if (t->type == UNSET) { - tuner_warn("tuner type not set\n"); + pr_warn("tuner type not set\n"); return; } if (NULL == analog_ops->set_params) { - tuner_warn("tuner has no way to set radio frequency\n"); + pr_warn("tuner has no way to set radio frequency\n"); return; } if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) { - tuner_dbg("radio freq (%d.%02d) out of range (%d-%d)\n", + dprintk("radio freq (%d.%02d) out of range (%d-%d)\n", freq / 16000, freq % 16000 * 100 / 16000, radio_range[0], radio_range[1]); /* V4L2 spec: if the freq is not possible then the closest @@ -1021,7 +1007,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) freq = radio_range[1] * 16000; } params.frequency = freq; - tuner_dbg("radio freq set to %d.%02d\n", + dprintk("radio freq set to %d.%02d\n", freq / 16000, freq % 16000 * 100 / 16000); t->radio_freq = freq; t->standby = false; @@ -1072,10 +1058,10 @@ static void tuner_status(struct dvb_frontend *fe) freq = t->tv_freq / 16; freq_fraction = (t->tv_freq % 16) * 100 / 16; } - tuner_info("Tuner mode: %s%s\n", p, + pr_info("Tuner mode: %s%s\n", p, t->standby ? " on standby mode" : ""); - tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); - tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); + pr_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); + pr_info("Standard: 0x%08lx\n", (unsigned long)t->std); if (t->mode != V4L2_TUNER_RADIO) return; if (fe_tuner_ops->get_status) { @@ -1083,15 +1069,15 @@ static void tuner_status(struct dvb_frontend *fe) fe_tuner_ops->get_status(&t->fe, &tuner_status); if (tuner_status & TUNER_STATUS_LOCKED) - tuner_info("Tuner is locked.\n"); + pr_info("Tuner is locked.\n"); if (tuner_status & TUNER_STATUS_STEREO) - tuner_info("Stereo: yes\n"); + pr_info("Stereo: yes\n"); } if (analog_ops->has_signal) { u16 signal; if (!analog_ops->has_signal(fe, &signal)) - tuner_info("Signal strength: %hu\n", signal); + pr_info("Signal strength: %hu\n", signal); } } @@ -1124,13 +1110,13 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on) if (on) { if (t->standby && set_mode(t, t->mode) == 0) { - tuner_dbg("Waking up tuner\n"); + dprintk("Waking up tuner\n"); set_freq(t, 0); } return 0; } - tuner_dbg("Putting tuner to sleep\n"); + dprintk("Putting tuner to sleep\n"); t->standby = true; if (analog_ops->standby) analog_ops->standby(&t->fe); @@ -1146,7 +1132,7 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) t->std = tuner_fixup_std(t, std); if (t->std != std) - tuner_dbg("Fixup standard %llx to %llx\n", std, t->std); + dprintk("Fixup standard %llx to %llx\n", std, t->std); set_freq(t, 0); return 0; } @@ -1295,7 +1281,7 @@ static int tuner_suspend(struct device *dev) struct tuner *t = to_tuner(i2c_get_clientdata(c)); struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; - tuner_dbg("suspend\n"); + dprintk("suspend\n"); if (t->fe.ops.tuner_ops.suspend) t->fe.ops.tuner_ops.suspend(&t->fe); @@ -1310,7 +1296,7 @@ static int tuner_resume(struct device *dev) struct i2c_client *c = to_i2c_client(dev); struct tuner *t = to_tuner(i2c_get_clientdata(c)); - tuner_dbg("resume\n"); + dprintk("resume\n"); if (t->fe.ops.tuner_ops.resume) t->fe.ops.tuner_ops.resume(&t->fe); -- cgit v1.2.3 From a41231d52ff755597d67ce83bb36e16c47dfec91 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 08:35:08 -0200 Subject: [media] v4l2-common: add a debug macro to be used with dev_foo() Currently, there's a mess at the V4L2 printk macros: some drivers use their own macros, others use pr_foo() or v4l_foo() macros, while more modern drivers use dev_foo() macros. The best is to get rid of v4l_foo() macros, as they can be replaced by either dev_foo() or pr_foo(). Yet, such change can be disruptive, as dev_foo() cannot use KERN_CONT. So, the best is to do such change driver by driver. There are replacements for most v4l_foo() macros, but it lacks a way to enable debug messages per level. So, add such macro, in order to make the conversion easier. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 350cbf9fb10e..aac8b7b6e691 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -55,6 +55,13 @@ v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ } while (0) +/* Add a version of v4l_dbg to be used on drivers using dev_foo() macros */ +#define dev_dbg_lvl(__dev, __level, __debug, __fmt, __arg...) \ + do { \ + if (__debug >= (__level)) \ + dev_printk(KERN_DEBUG, __dev, __fmt, ##__arg); \ + } while (0) + /* ------------------------------------------------------------------------- */ /* These printk constructs can be used with v4l2_device and v4l2_subdev */ -- cgit v1.2.3 From b68d75b955a62a6ade9e004b656415f346c3ad40 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Oct 2016 08:03:00 -0200 Subject: [media] msp3400-driver: don't use KERN_CONT Drivers using dev_foo() macro should not use KERN_CONT, as, internally, those macros work as if all strings were terminated by a \n. So, doing: dev_info(&client->dev, "%s ", client->name); printk(KERN_CONT "supports radio, mode is autodetect and autoselect"); Would produce the following output: msp3400 6-0044: msp3400 supports radio, mode is autodetect and autoselect As there's no good reason to use KERN_CONT, let's rewrite the code to avoid that, allowing this driver to be converted to dev_foo(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/msp3400-driver.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index 503b7c4f0a9b..ae396b965ef2 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -670,6 +670,13 @@ static const struct v4l2_subdev_ops msp_ops = { /* ----------------------------------------------------------------------- */ + +static const char * const opmode_str[] = { + [OPMODE_MANUAL] = "manual", + [OPMODE_AUTODETECT] = "autodetect", + [OPMODE_AUTOSELECT] = "autodetect and autoselect", +}; + static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct msp_state *state; @@ -791,7 +798,8 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3; state->opmode = opmode; - if (state->opmode == OPMODE_AUTO) { + if (state->opmode < OPMODE_MANUAL + || state->opmode > OPMODE_AUTOSELECT) { /* MSP revision G and up have both autodetect and autoselect */ if (msp_revision >= 'G') state->opmode = OPMODE_AUTOSELECT; @@ -829,36 +837,28 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) v4l2_ctrl_cluster(2, &state->volume); v4l2_ctrl_handler_setup(hdl); - /* hello world :-) */ - v4l_info(client, "MSP%d4%02d%c-%c%d found @ 0x%x (%s)\n", - msp_family, msp_product, - msp_revision, msp_hard, msp_rom, - client->addr << 1, client->adapter->name); - v4l_info(client, "%s ", client->name); - if (state->has_nicam && state->has_radio) - printk(KERN_CONT "supports nicam and radio, "); - else if (state->has_nicam) - printk(KERN_CONT "supports nicam, "); - else if (state->has_radio) - printk(KERN_CONT "supports radio, "); - printk(KERN_CONT "mode is "); + dev_info(&client->dev, + "MSP%d4%02d%c-%c%d found on %s: supports %s%s%s, mode is %s\n", + msp_family, msp_product, + msp_revision, msp_hard, msp_rom, + client->adapter->name, + (state->has_nicam) ? "nicam" : "", + (state->has_nicam && state->has_radio) ? " and " : "", + (state->has_radio) ? "radio" : "", + opmode_str[state->opmode]); /* version-specific initialization */ switch (state->opmode) { case OPMODE_MANUAL: - printk(KERN_CONT "manual"); thread_func = msp3400c_thread; break; case OPMODE_AUTODETECT: - printk(KERN_CONT "autodetect"); thread_func = msp3410d_thread; break; case OPMODE_AUTOSELECT: - printk(KERN_CONT "autodetect and autoselect"); thread_func = msp34xxg_thread; break; } - printk(KERN_CONT "\n"); /* startup control thread if needed */ if (thread_func) { -- cgit v1.2.3 From 39ad799a85e2afb2eeb0295cabe81e183b011b95 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 09:10:14 -0200 Subject: [media] msp3400: convert it to use dev_foo() macros Instead of using the v4l_foo() macros, just use the kernel-wide dev_foo() macros, as there's no good reason to use something else. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/msp3400-driver.c | 54 ++++++++-------- drivers/media/i2c/msp3400-kthreads.c | 115 +++++++++++++++++------------------ 2 files changed, 84 insertions(+), 85 deletions(-) diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index ae396b965ef2..201a9800ea52 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -146,11 +146,11 @@ int msp_reset(struct i2c_client *client) }, }; - v4l_dbg(3, msp_debug, client, "msp_reset\n"); + dev_dbg_lvl(&client->dev, 3, msp_debug, "msp_reset\n"); if (i2c_transfer(client->adapter, &reset[0], 1) != 1 || i2c_transfer(client->adapter, &reset[1], 1) != 1 || i2c_transfer(client->adapter, test, 2) != 2) { - v4l_err(client, "chip reset failed\n"); + dev_err(&client->dev, "chip reset failed\n"); return -1; } return 0; @@ -182,17 +182,17 @@ static int msp_read(struct i2c_client *client, int dev, int addr) for (err = 0; err < 3; err++) { if (i2c_transfer(client->adapter, msgs, 2) == 2) break; - v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, + dev_warn(&client->dev, "I/O error #%d (read 0x%02x/0x%02x)\n", err, dev, addr); schedule_timeout_interruptible(msecs_to_jiffies(10)); } if (err == 3) { - v4l_warn(client, "resetting chip, sound will go off.\n"); + dev_warn(&client->dev, "resetting chip, sound will go off.\n"); msp_reset(client); return -1; } retval = read[0] << 8 | read[1]; - v4l_dbg(3, msp_debug, client, "msp_read(0x%x, 0x%x): 0x%x\n", + dev_dbg_lvl(&client->dev, 3, msp_debug, "msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); return retval; } @@ -218,17 +218,17 @@ static int msp_write(struct i2c_client *client, int dev, int addr, int val) buffer[3] = val >> 8; buffer[4] = val & 0xff; - v4l_dbg(3, msp_debug, client, "msp_write(0x%x, 0x%x, 0x%x)\n", + dev_dbg_lvl(&client->dev, 3, msp_debug, "msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); for (err = 0; err < 3; err++) { if (i2c_master_send(client, buffer, 5) == 5) break; - v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, + dev_warn(&client->dev, "I/O error #%d (write 0x%02x/0x%02x)\n", err, dev, addr); schedule_timeout_interruptible(msecs_to_jiffies(10)); } if (err == 3) { - v4l_warn(client, "resetting chip, sound will go off.\n"); + dev_warn(&client->dev, "resetting chip, sound will go off.\n"); msp_reset(client); return -1; } @@ -301,7 +301,7 @@ void msp_set_scart(struct i2c_client *client, int in, int out) } else state->acb = 0xf60; /* Mute Input and SCART 1 Output */ - v4l_dbg(1, msp_debug, client, "scart switch: %s => %d (ACB=0x%04x)\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "scart switch: %s => %d (ACB=0x%04x)\n", scart_names[in], out, state->acb); msp_write_dsp(client, 0x13, state->acb); @@ -359,7 +359,7 @@ static int msp_s_ctrl(struct v4l2_ctrl *ctrl) if (!reallymuted) val = (val * 0x7f / 65535) << 8; - v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "mute=%s scanning=%s volume=%d\n", state->muted->val ? "on" : "off", state->scan_in_progress ? "yes" : "no", state->volume->val); @@ -426,7 +426,7 @@ static int msp_s_radio(struct v4l2_subdev *sd) if (state->radio) return 0; state->radio = 1; - v4l_dbg(1, msp_debug, client, "switching to radio mode\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "switching to radio mode\n"); state->watch_stereo = 0; switch (state->opmode) { case OPMODE_MANUAL: @@ -461,7 +461,7 @@ static int msp_querystd(struct v4l2_subdev *sd, v4l2_std_id *id) *id &= state->detected_std; - v4l_dbg(2, msp_debug, client, + dev_dbg_lvl(&client->dev, 2, msp_debug, "detected standard: %s(0x%08Lx)\n", msp_standard_std_name(state->std), state->detected_std); @@ -555,7 +555,7 @@ static int msp_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq) struct msp_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", freq); + dev_dbg_lvl(&client->dev, 1, msp_debug, "Setting I2S speed to %d\n", freq); switch (freq) { case 1024000: @@ -579,7 +579,7 @@ static int msp_log_status(struct v4l2_subdev *sd) if (state->opmode == OPMODE_AUTOSELECT) msp_detect_stereo(client); - v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", + dev_info(&client->dev, "%s rev1 = 0x%04x rev2 = 0x%04x\n", client->name, state->rev1, state->rev2); snprintf(prefix, sizeof(prefix), "%s: Audio: ", sd->name); v4l2_ctrl_handler_log_status(&state->hdl, prefix); @@ -596,23 +596,23 @@ static int msp_log_status(struct v4l2_subdev *sd) default: p = "unknown"; break; } if (state->mode == MSP_MODE_EXTERN) { - v4l_info(client, "Mode: %s\n", p); + dev_info(&client->dev, "Mode: %s\n", p); } else if (state->opmode == OPMODE_MANUAL) { - v4l_info(client, "Mode: %s (%s%s)\n", p, + dev_info(&client->dev, "Mode: %s (%s%s)\n", p, (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); } else { if (state->opmode == OPMODE_AUTODETECT) - v4l_info(client, "Mode: %s\n", p); - v4l_info(client, "Standard: %s (%s%s)\n", + dev_info(&client->dev, "Mode: %s\n", p); + dev_info(&client->dev, "Standard: %s (%s%s)\n", msp_standard_std_name(state->std), (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); } - v4l_info(client, "Audmode: 0x%04x\n", state->audmode); - v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n", + dev_info(&client->dev, "Audmode: 0x%04x\n", state->audmode); + dev_info(&client->dev, "Routing: 0x%08x (input) 0x%08x (output)\n", state->route_in, state->route_out); - v4l_info(client, "ACB: 0x%04x\n", state->acb); + dev_info(&client->dev, "ACB: 0x%04x\n", state->acb); return 0; } @@ -620,7 +620,7 @@ static int msp_log_status(struct v4l2_subdev *sd) static int msp_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - v4l_dbg(1, msp_debug, client, "suspend\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "suspend\n"); msp_reset(client); return 0; } @@ -628,7 +628,7 @@ static int msp_suspend(struct device *dev) static int msp_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - v4l_dbg(1, msp_debug, client, "resume\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "resume\n"); msp_wake_thread(client); return 0; } @@ -696,7 +696,7 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) strlcpy(client->name, "msp3400", sizeof(client->name)); if (msp_reset(client) == -1) { - v4l_dbg(1, msp_debug, client, "msp3400 not found\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3400 not found\n"); return -ENODEV; } @@ -731,10 +731,10 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) state->rev1 = msp_read_dsp(client, 0x1e); if (state->rev1 != -1) state->rev2 = msp_read_dsp(client, 0x1f); - v4l_dbg(1, msp_debug, client, "rev1=0x%04x, rev2=0x%04x\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2); if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) { - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "not an msp3400 (cannot read chip version)\n"); return -ENODEV; } @@ -865,7 +865,7 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) state->kthread = kthread_run(thread_func, client, "msp34xx"); if (IS_ERR(state->kthread)) - v4l_warn(client, "kernel_thread() failed\n"); + dev_warn(&client->dev, "kernel_thread() failed\n"); msp_wake_thread(client); } return 0; diff --git a/drivers/media/i2c/msp3400-kthreads.c b/drivers/media/i2c/msp3400-kthreads.c index 17120804fab7..eec7aa4c6f98 100644 --- a/drivers/media/i2c/msp3400-kthreads.c +++ b/drivers/media/i2c/msp3400-kthreads.c @@ -220,7 +220,7 @@ void msp3400c_set_mode(struct i2c_client *client, int mode) int tuner = (state->route_in >> 3) & 1; int i; - v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); + dev_dbg_lvl(&client->dev, 1, msp_debug, "set_mode: %d\n", mode); state->mode = mode; state->rxsubchans = V4L2_TUNER_SUB_MONO; @@ -266,7 +266,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) /* this method would break everything, let's make sure * it's never called */ - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "set_audmode called with mode=%d instead of set_source (ignored)\n", state->audmode); return; @@ -295,7 +295,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) /* switch demodulator */ switch (state->mode) { case MSP_MODE_FM_TERRA: - v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr); + dev_dbg_lvl(&client->dev, 1, msp_debug, "FM set_audmode: %s\n", modestr); switch (audmode) { case V4L2_TUNER_MODE_STEREO: msp_write_dsp(client, 0x000e, 0x3001); @@ -309,7 +309,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) } break; case MSP_MODE_FM_SAT: - v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr); + dev_dbg_lvl(&client->dev, 1, msp_debug, "SAT set_audmode: %s\n", modestr); switch (audmode) { case V4L2_TUNER_MODE_MONO: msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); @@ -329,31 +329,31 @@ static void msp3400c_set_audmode(struct i2c_client *client) case MSP_MODE_FM_NICAM1: case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "NICAM set_audmode: %s\n", modestr); if (state->nicam_on) src = 0x0100; /* NICAM */ break; case MSP_MODE_BTSC: - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "BTSC set_audmode: %s\n", modestr); break; case MSP_MODE_EXTERN: - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "extern set_audmode: %s\n", modestr); src = 0x0200; /* SCART */ break; case MSP_MODE_FM_RADIO: - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "FM-Radio set_audmode: %s\n", modestr); break; default: - v4l_dbg(1, msp_debug, client, "mono set_audmode\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "mono set_audmode\n"); return; } /* switch audio */ - v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); + dev_dbg_lvl(&client->dev, 1, msp_debug, "set audmode %d\n", audmode); switch (audmode) { case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: @@ -361,7 +361,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) break; case V4L2_TUNER_MODE_MONO: if (state->mode == MSP_MODE_AM_NICAM) { - v4l_dbg(1, msp_debug, client, "switching to AM mono\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "switching to AM mono\n"); /* AM mono decoding is handled by tuner, not MSP chip */ /* SCART switching control register */ msp_set_scart(client, SCART_MONO, 0); @@ -377,7 +377,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) src |= 0x0010; break; } - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "set_audmode final source/matrix = 0x%x\n", src); msp_set_source(client, src); @@ -388,23 +388,23 @@ static void msp3400c_print_mode(struct i2c_client *client) struct msp_state *state = to_state(i2c_get_clientdata(client)); if (state->main == state->second) - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "mono sound carrier: %d.%03d MHz\n", state->main / 910000, (state->main / 910) % 1000); else - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "main sound carrier: %d.%03d MHz\n", state->main / 910000, (state->main / 910) % 1000); if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2) - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "NICAM/FM carrier : %d.%03d MHz\n", state->second / 910000, (state->second/910) % 1000); if (state->mode == MSP_MODE_AM_NICAM) - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "NICAM/AM carrier : %d.%03d MHz\n", state->second / 910000, (state->second / 910) % 1000); if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) { - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "FM-stereo carrier : %d.%03d MHz\n", state->second / 910000, (state->second / 910) % 1000); } @@ -425,7 +425,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client) val = msp_read_dsp(client, 0x18); if (val > 32767) val -= 65536; - v4l_dbg(2, msp_debug, client, + dev_dbg_lvl(&client->dev, 2, msp_debug, "stereo detect register: %d\n", val); if (val > 8192) { rxsubchans = V4L2_TUNER_SUB_STEREO; @@ -440,7 +440,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client) case MSP_MODE_FM_NICAM2: case MSP_MODE_AM_NICAM: val = msp_read_dem(client, 0x23); - v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n", + dev_dbg_lvl(&client->dev, 2, msp_debug, "nicam sync=%d, mode=%d\n", val & 1, (val & 0x1e) >> 1); if (val & 1) { @@ -471,14 +471,14 @@ static int msp3400c_detect_stereo(struct i2c_client *client) } if (rxsubchans != state->rxsubchans) { update = 1; - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "watch: rxsubchans %02x => %02x\n", state->rxsubchans, rxsubchans); state->rxsubchans = rxsubchans; } if (newnicam != state->nicam_on) { update = 1; - v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "watch: nicam %d => %d\n", state->nicam_on, newnicam); state->nicam_on = newnicam; } @@ -508,23 +508,23 @@ int msp3400c_thread(void *data) struct msp3400c_carrier_detect *cd; int count, max1, max2, val1, val2, val, i; - v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3400 daemon started\n"); state->detected_std = V4L2_STD_ALL; set_freezable(); for (;;) { - v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3400 thread: sleep\n"); msp_sleep(state, -1); - v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3400 thread: wakeup\n"); restart: - v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "thread: restart scan\n"); state->restart = 0; if (kthread_should_stop()) break; if (state->radio || MSP_MODE_EXTERN == state->mode) { /* no carrier scan, just unmute */ - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: no carrier scan\n"); state->scan_in_progress = 0; msp_update_volume(state); @@ -553,7 +553,7 @@ restart: /* autodetect doesn't work well with AM ... */ max1 = 3; count = 0; - v4l_dbg(1, msp_debug, client, "AM sound override\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "AM sound override\n"); } for (i = 0; i < count; i++) { @@ -565,7 +565,7 @@ restart: val -= 65536; if (val1 < val) val1 = val, max1 = i; - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "carrier1 val: %5d / %s\n", val, cd[i].name); } @@ -602,7 +602,7 @@ restart: val -= 65536; if (val2 < val) val2 = val, max2 = i; - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "carrier2 val: %5d / %s\n", val, cd[i].name); } @@ -687,7 +687,7 @@ no_second: watch_stereo(client); } } - v4l_dbg(1, msp_debug, client, "thread: exit\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n"); return 0; } @@ -698,23 +698,23 @@ int msp3410d_thread(void *data) struct msp_state *state = to_state(i2c_get_clientdata(client)); int val, i, std, count; - v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3410 daemon started\n"); state->detected_std = V4L2_STD_ALL; set_freezable(); for (;;) { - v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3410 thread: sleep\n"); msp_sleep(state, -1); - v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3410 thread: wakeup\n"); restart: - v4l_dbg(2, msp_debug, client, "thread: restart scan\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "thread: restart scan\n"); state->restart = 0; if (kthread_should_stop()) break; if (state->mode == MSP_MODE_EXTERN) { /* no carrier scan needed, just unmute */ - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: no carrier scan\n"); state->scan_in_progress = 0; msp_update_volume(state); @@ -740,7 +740,7 @@ restart: goto restart; if (msp_debug) - v4l_dbg(2, msp_debug, client, + dev_dbg_lvl(&client->dev, 2, msp_debug, "setting standard: %s (0x%04x)\n", msp_standard_std_name(std), std); @@ -758,14 +758,14 @@ restart: val = msp_read_dem(client, 0x7e); if (val < 0x07ff) break; - v4l_dbg(2, msp_debug, client, + dev_dbg_lvl(&client->dev, 2, msp_debug, "detection still in progress\n"); } } for (i = 0; msp_stdlist[i].name != NULL; i++) if (msp_stdlist[i].retval == val) break; - v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "current standard: %s (0x%04x)\n", msp_standard_std_name(val), val); state->main = msp_stdlist[i].main; state->second = msp_stdlist[i].second; @@ -775,8 +775,7 @@ restart: if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) { /* autodetection has failed, let backup */ - v4l_dbg(1, msp_debug, client, "autodetection failed," - " switching to backup standard: %s (0x%04x)\n", + dev_dbg_lvl(&client->dev, 1, msp_debug, "autodetection failed, switching to backup standard: %s (0x%04x)\n", msp_stdlist[8].name ? msp_stdlist[8].name : "unknown", val); state->std = val = 0x0009; @@ -850,7 +849,7 @@ restart: watch_stereo(client); } } - v4l_dbg(1, msp_debug, client, "thread: exit\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n"); return 0; } @@ -867,23 +866,23 @@ static int msp34xxg_modus(struct i2c_client *client) struct msp_state *state = to_state(i2c_get_clientdata(client)); if (state->radio) { - v4l_dbg(1, msp_debug, client, "selected radio modus\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "selected radio modus\n"); return 0x0001; } if (state->v4l2_std == V4L2_STD_NTSC_M_JP) { - v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (EIA-J) modus\n"); return 0x4001; } if (state->v4l2_std == V4L2_STD_NTSC_M_KR) { - v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (A2) modus\n"); return 0x0001; } if (state->v4l2_std == V4L2_STD_SECAM_L) { - v4l_dbg(1, msp_debug, client, "selected SECAM-L modus\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "selected SECAM-L modus\n"); return 0x6001; } if (state->v4l2_std & V4L2_STD_MN) { - v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (BTSC) modus\n"); return 0x2001; } return 0x7001; @@ -927,7 +926,7 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) else source = (in << 8) | matrix; - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "set source to %d (0x%x) for output %02x\n", in, source, reg); msp_write_dsp(client, reg, source); } @@ -996,23 +995,23 @@ int msp34xxg_thread(void *data) struct msp_state *state = to_state(i2c_get_clientdata(client)); int val, i; - v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "msp34xxg daemon started\n"); state->detected_std = V4L2_STD_ALL; set_freezable(); for (;;) { - v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp34xxg thread: sleep\n"); msp_sleep(state, -1); - v4l_dbg(2, msp_debug, client, "msp34xxg thread: wakeup\n"); + dev_dbg_lvl(&client->dev, 2, msp_debug, "msp34xxg thread: wakeup\n"); restart: - v4l_dbg(1, msp_debug, client, "thread: restart scan\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: restart scan\n"); state->restart = 0; if (kthread_should_stop()) break; if (state->mode == MSP_MODE_EXTERN) { /* no carrier scan needed, just unmute */ - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: no carrier scan\n"); state->scan_in_progress = 0; msp_update_volume(state); @@ -1029,7 +1028,7 @@ restart: goto unmute; /* watch autodetect */ - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "started autodetect, waiting for result\n"); for (i = 0; i < 10; i++) { if (msp_sleep(state, 100)) @@ -1041,17 +1040,17 @@ restart: state->std = val; break; } - v4l_dbg(2, msp_debug, client, + dev_dbg_lvl(&client->dev, 2, msp_debug, "detection still in progress\n"); } if (state->std == 1) { - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "detection still in progress after 10 tries. giving up.\n"); continue; } unmute: - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "detected standard: %s (0x%04x)\n", msp_standard_std_name(state->std), state->std); state->detected_std = msp_standard_std(state->std); @@ -1084,7 +1083,7 @@ unmute: goto restart; } } - v4l_dbg(1, msp_debug, client, "thread: exit\n"); + dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n"); return 0; } @@ -1111,7 +1110,7 @@ static int msp34xxg_detect_stereo(struct i2c_client *client) state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; } - v4l_dbg(1, msp_debug, client, + dev_dbg_lvl(&client->dev, 1, msp_debug, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", status, is_stereo, is_bilingual, state->rxsubchans); return (oldrx != state->rxsubchans); -- cgit v1.2.3 From ce8591ff023ef8e04750c2cc2882523619a80b58 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Oct 2016 08:42:03 -0200 Subject: [media] em28xx: convert it from pr_foo() to dev_foo() Instead of using pr_foo(), use dev_foo(), with provides a better output. As this device is a multi-interface one, we'll set the device name to show the chipset and the driver used. While here, get rid of printk continuation messages. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 64 ++++--- drivers/media/usb/em28xx/em28xx-camera.c | 60 ++++--- drivers/media/usb/em28xx/em28xx-cards.c | 131 +++++++------- drivers/media/usb/em28xx/em28xx-core.c | 154 +++++++++-------- drivers/media/usb/em28xx/em28xx-dvb.c | 89 ++++++---- drivers/media/usb/em28xx/em28xx-i2c.c | 284 ++++++++++++++++--------------- drivers/media/usb/em28xx/em28xx-input.c | 42 +++-- drivers/media/usb/em28xx/em28xx-vbi.c | 6 +- drivers/media/usb/em28xx/em28xx-video.c | 127 ++++++++------ drivers/media/usb/em28xx/em28xx.h | 3 - 10 files changed, 536 insertions(+), 424 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 06e495615296..cd2545ca5e39 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -55,9 +55,10 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define EM28XX_MIN_AUDIO_PACKETS 64 #define dprintk(fmt, arg...) do { \ - if (debug) \ - printk(KERN_DEBUG pr_fmt("audio: %s: " fmt), \ - __func__, ##arg); } while (0) + if (debug) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "video: %s: " fmt, __func__, ## arg); \ +} while (0) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; @@ -91,7 +92,8 @@ static void em28xx_audio_isocirq(struct urb *urb) struct snd_pcm_runtime *runtime; if (dev->disconnected) { - dprintk("device disconnected while streaming. URB status=%d.\n", urb->status); + dprintk("device disconnected while streaming. URB status=%d.\n", + urb->status); atomic_set(&dev->adev.stream_started, 0); return; } @@ -164,8 +166,9 @@ static void em28xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) - pr_err("resubmit of audio urb failed (error=%i)\n", - status); + dev_err(&dev->udev->dev, + "resubmit of audio urb failed (error=%i)\n", + status); return; } @@ -182,8 +185,9 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - pr_err("submit of audio urb failed (error=%i)\n", - errCode); + dev_err(&dev->udev->dev, + "submit of audio urb failed (error=%i)\n", + errCode); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); return errCode; @@ -197,6 +201,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size) { + struct em28xx *dev = snd_pcm_substream_chip(subs); struct snd_pcm_runtime *runtime = subs->runtime; dprintk("Allocating vbuffer\n"); @@ -254,7 +259,8 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) int nonblock, ret = 0; if (!dev) { - pr_err("BUG: em28xx can't find device struct. Can't proceed with open\n"); + dev_err(&dev->udev->dev, + "BUG: em28xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -317,7 +323,8 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) err: mutex_unlock(&dev->lock); - pr_err("Error while configuring em28xx mixer\n"); + dev_err(&dev->udev->dev, + "Error while configuring em28xx mixer\n"); return ret; } @@ -755,7 +762,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) intf = usb_ifnum_to_if(dev->udev, dev->ifnum); if (intf->num_altsetting <= alt) { - pr_err("alt %d doesn't exist on interface %d\n", + dev_err(&dev->udev->dev, "alt %d doesn't exist on interface %d\n", dev->ifnum, alt); return -ENODEV; } @@ -771,18 +778,17 @@ static int em28xx_audio_urb_init(struct em28xx *dev) } if (!ep) { - pr_err("Couldn't find an audio endpoint"); + dev_err(&dev->udev->dev, "Couldn't find an audio endpoint"); return -ENODEV; } ep_size = em28xx_audio_ep_packet_size(dev->udev, ep); interval = 1 << (ep->bInterval - 1); - pr_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", - EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), - dev->ifnum, alt, - interval, - ep_size); + dev_info(&dev->udev->dev, + "Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", + EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), + dev->ifnum, alt, interval, ep_size); /* Calculate the number and size of URBs to better fit the audio samples */ @@ -819,8 +825,9 @@ static int em28xx_audio_urb_init(struct em28xx *dev) if (urb_size > ep_size * npackets) npackets = DIV_ROUND_UP(urb_size, ep_size); - pr_info("Number of URBs: %d, with %d packets and %d size\n", - num_urb, npackets, urb_size); + dev_info(&dev->udev->dev, + "Number of URBs: %d, with %d packets and %d size\n", + num_urb, npackets, urb_size); /* Estimate the bytes per period */ dev->adev.period = urb_size * npackets; @@ -857,7 +864,8 @@ static int em28xx_audio_urb_init(struct em28xx *dev) buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - pr_err("usb_alloc_coherent failed!\n"); + dev_err(&dev->udev->dev, + "usb_alloc_coherent failed!\n"); em28xx_audio_free_urb(dev); return -ENOMEM; } @@ -897,12 +905,14 @@ static int em28xx_audio_init(struct em28xx *dev) return 0; } - pr_info("Binding audio extension\n"); + dev_info(&dev->udev->dev, "Binding audio extension\n"); kref_get(&dev->ref); - pr_info("em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); - pr_info("em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); + dev_info(&dev->udev->dev, + "em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); + dev_info(&dev->udev->dev, + "em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Em28xx Audio", THIS_MODULE, 0, &card); @@ -952,7 +962,7 @@ static int em28xx_audio_init(struct em28xx *dev) if (err < 0) goto urb_free; - pr_info("Audio extension successfully initialized\n"); + dev_info(&dev->udev->dev, "Audio extension successfully initialized\n"); return 0; urb_free: @@ -977,7 +987,7 @@ static int em28xx_audio_fini(struct em28xx *dev) return 0; } - pr_info("Closing audio extension\n"); + dev_info(&dev->udev->dev, "Closing audio extension\n"); if (dev->adev.sndcard) { snd_card_disconnect(dev->adev.sndcard); @@ -1001,7 +1011,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - pr_info("Suspending audio extension\n"); + dev_info(&dev->udev->dev, "Suspending audio extension\n"); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); return 0; @@ -1015,7 +1025,7 @@ static int em28xx_audio_resume(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - pr_info("Resuming audio extension\n"); + dev_info(&dev->udev->dev, "Resuming audio extension\n"); /* Nothing to do other than schedule_work() ?? */ schedule_work(&dev->adev.wq_trigger); return 0; diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index a24695474212..2e24b65901ec 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -22,6 +22,7 @@ #include "em28xx.h" #include +#include #include #include #include @@ -120,14 +121,16 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) ret = i2c_master_send(&client, ®, 1); if (ret < 0) { if (ret != -ENXIO) - pr_err("couldn't read from i2c device 0x%02x: error %i\n", + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } id = be16_to_cpu(id_be); @@ -135,14 +138,16 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) reg = 0xff; ret = i2c_master_send(&client, ®, 1); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } /* Validate chip ID to be sure we have a Micron device */ @@ -180,14 +185,17 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_MT9M001; break; default: - pr_info("unknown Micron sensor detected: 0x%04x\n", id); + dev_info(&dev->udev->dev, + "unknown Micron sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - pr_info("unsupported sensor detected: %s\n", name); + dev_info(&dev->udev->dev, + "unsupported sensor detected: %s\n", name); else - pr_info("sensor %s detected\n", name); + dev_info(&dev->udev->dev, + "sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; return 0; @@ -217,16 +225,18 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { if (ret != -ENXIO) - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } id = ret << 8; reg = 0x1d; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } id += ret; @@ -237,16 +247,18 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x0a; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } id = ret << 8; reg = 0x0b; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - pr_err("couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + dev_err(&dev->udev->dev, + "couldn't read from i2c device 0x%02x: error %i\n", + client.addr << 1, ret); continue; } id += ret; @@ -284,15 +296,18 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) name = "OV9655"; break; default: - pr_info("unknown OmniVision sensor detected: 0x%04x\n", + dev_info(&dev->udev->dev, + "unknown OmniVision sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - pr_info("unsupported sensor detected: %s\n", name); + dev_info(&dev->udev->dev, + "unsupported sensor detected: %s\n", name); else - pr_info("sensor %s detected\n", name); + dev_info(&dev->udev->dev, + "sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; return 0; @@ -316,7 +331,8 @@ int em28xx_detect_sensor(struct em28xx *dev) */ if (dev->em28xx_sensor == EM28XX_NOSENSOR && ret < 0) { - pr_info("No sensor detected\n"); + dev_info(&dev->udev->dev, + "No sensor detected\n"); return -ENODEV; } diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 898fab136534..b516c691b9eb 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2677,7 +2677,7 @@ static int em28xx_wait_until_ac97_features_equals(struct em28xx *dev, msleep(50); } - pr_warn("AC97 registers access is not reliable !\n"); + dev_warn(&dev->udev->dev, "AC97 registers access is not reliable !\n"); return -ETIMEDOUT; } @@ -2831,12 +2831,13 @@ static int em28xx_hint_board(struct em28xx *dev) dev->model = em28xx_eeprom_hash[i].model; dev->tuner_type = em28xx_eeprom_hash[i].tuner; - pr_err("Your board has no unique USB ID.\n"); - pr_err("A hint were successfully done, based on eeprom hash.\n"); - pr_err("This method is not 100%% failproof.\n"); - pr_err("If the board were missdetected, please email this log to:\n"); - pr_err("\tV4L Mailing List \n"); - pr_err("Board detected as %s\n", + dev_err(&dev->udev->dev, + "Your board has no unique USB ID.\n" + "A hint were successfully done, based on eeprom hash.\n" + "This method is not 100%% failproof.\n" + "If the board were missdetected, please email this log to:\n" + "\tV4L Mailing List \n" + "Board detected as %s\n", em28xx_boards[dev->model].name); return 0; @@ -2860,28 +2861,33 @@ static int em28xx_hint_board(struct em28xx *dev) if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { dev->model = em28xx_i2c_hash[i].model; dev->tuner_type = em28xx_i2c_hash[i].tuner; - pr_err("Your board has no unique USB ID.\n"); - pr_err("A hint were successfully done, based on i2c devicelist hash.\n"); - pr_err("This method is not 100%% failproof.\n"); - pr_err("If the board were missdetected, please email this log to:\n"); - pr_err("\tV4L Mailing List \n"); - pr_err("Board detected as %s\n", - em28xx_boards[dev->model].name); + dev_err(&dev->udev->dev, + "Your board has no unique USB ID.\n" + "A hint were successfully done, based on i2c devicelist hash.\n" + "This method is not 100%% failproof.\n" + "If the board were missdetected, please email this log to:\n" + "\tV4L Mailing List \n" + "Board detected as %s\n", + em28xx_boards[dev->model].name); return 0; } } - pr_err("Your board has no unique USB ID and thus need a hint to be detected.\n"); - pr_err("You may try to use card= insmod option to workaround that.\n"); - pr_err("Please send an email with this log to:\n"); - pr_err("\tV4L Mailing List \n"); - pr_err("Board eeprom hash is 0x%08lx\n", dev->hash); - pr_err("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); - - pr_err("Here is a list of valid choices for the card= insmod option:\n"); + dev_err(&dev->udev->dev, + "Your board has no unique USB ID and thus need a hint to be detected.\n" + "You may try to use card= insmod option to workaround that.\n" + "Please send an email with this log to:\n" + "\tV4L Mailing List \n" + "Board eeprom hash is 0x%08lx\n" + "Board i2c devicelist hash is 0x%08lx\n", + dev->hash, dev->i2c_hash); + + dev_err(&dev->udev->dev, + "Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { - pr_err(" card=%d -> %s\n", i, em28xx_boards[i].name); + dev_err(&dev->udev->dev, + " card=%d -> %s\n", i, em28xx_boards[i].name); } return -1; } @@ -2915,7 +2921,7 @@ static void em28xx_card_setup(struct em28xx *dev) * hash identities which has not been determined as yet. */ if (em28xx_hint_board(dev) < 0) - pr_err("Board not discovered\n"); + dev_err(&dev->udev->dev, "Board not discovered\n"); else { em28xx_set_model(dev); em28xx_pre_card_setup(dev); @@ -2925,7 +2931,7 @@ static void em28xx_card_setup(struct em28xx *dev) em28xx_set_model(dev); } - pr_info("Identified as %s (card=%d)\n", + dev_info(&dev->udev->dev, "Identified as %s (card=%d)\n", dev->board.name, dev->model); dev->tuner_type = em28xx_boards[dev->model].tuner_type; @@ -3024,10 +3030,11 @@ static void em28xx_card_setup(struct em28xx *dev) } if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { - pr_err("\n\n"); - pr_err("The support for this board weren't valid yet.\n"); - pr_err("Please send a report of having this working\n"); - pr_err("not to V4L mailing list (and/or to other addresses)\n\n"); + dev_err(&dev->udev->dev, + "\n\n" + "The support for this board weren't valid yet.\n" + "Please send a report of having this working\n" + "not to V4L mailing list (and/or to other addresses)\n\n"); } /* Free eeprom data memory */ @@ -3154,7 +3161,7 @@ static int em28xx_media_device_init(struct em28xx *dev, else if (udev->manufacturer) media_device_usb_init(mdev, udev, udev->manufacturer); else - media_device_usb_init(mdev, udev, dev->name); + media_device_usb_init(mdev, udev, dev_name(&dev->udev->dev)); dev->media_dev = mdev; #endif @@ -3210,7 +3217,7 @@ void em28xx_free_device(struct kref *ref) { struct em28xx *dev = kref_to_dev(ref); - pr_info("Freeing device\n"); + dev_info(&dev->udev->dev, "Freeing device\n"); if (!dev->disconnected) em28xx_release_resources(dev); @@ -3315,19 +3322,18 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, dev->wait_after_write = 0; dev->eeprom_addrwidth_16bit = 1; break; - default: - pr_info("unknown em28xx chip ID (%d)\n", dev->chip_id); } } - if (chip_name != default_chip_name) - pr_info("chip ID is %s\n", chip_name); + dev_set_name(&dev->udev->dev, "%d-%s: %s#%d", + dev->udev->bus->busnum, dev->udev->devpath, + chip_name, dev->devno); - /* - * For em2820/em2710, the name may change latter, after checking - * if the device has a sensor (so, it is em2710) or not. - */ - snprintf(dev->name, sizeof(dev->name), "%s #%d", chip_name, dev->devno); + if (chip_name == default_chip_name) + dev_info(&dev->udev->dev, + "unknown em28xx chip ID (%d)\n", dev->chip_id); + else + dev_info(&dev->udev->dev, "chip ID is %s\n", chip_name); em28xx_media_device_init(dev, udev); @@ -3346,7 +3352,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, /* Resets I2C speed */ retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); if (retval < 0) { - pr_err("%s: em28xx_write_reg failed! retval [%d]\n", + dev_err(&dev->udev->dev, + "%s: em28xx_write_reg failed! retval [%d]\n", __func__, retval); return retval; } @@ -3360,7 +3367,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, else retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - pr_err("%s: em28xx_i2c_register bus 0 - error [%d]!\n", + dev_err(&dev->udev->dev, + "%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); return retval; } @@ -3374,7 +3382,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_i2c_register(dev, 1, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - pr_err("%s: em28xx_i2c_register bus 1 - error [%d]!\n", + dev_err(&dev->udev->dev, + "%s: em28xx_i2c_register bus 1 - error [%d]!\n", __func__, retval); em28xx_i2c_unregister(dev, 0); @@ -3414,7 +3423,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ - pr_err("Driver supports up to %i em28xx boards.\n", + dev_err(&udev->dev, + "Driver supports up to %i em28xx boards.\n", EM28XX_MAXBOARDS); retval = -ENOMEM; goto err_no_slot; @@ -3423,7 +3433,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - pr_err("audio device (%04x:%04x): interface %i, class %i\n", + dev_err(&udev->dev, + "audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), ifnum, @@ -3483,7 +3494,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (usb_endpoint_xfer_isoc(e)) { has_vendor_audio = true; } else { - pr_err("error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); + dev_err(&udev->dev, + "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); } break; case 0x84: @@ -3556,7 +3568,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - pr_info("New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", + dev_err(&udev->dev, + "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", speed, @@ -3571,8 +3584,9 @@ static int em28xx_usb_probe(struct usb_interface *interface, * not enough even for most Digital TV streams. */ if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { - pr_err("Device initialization failed.\n"); - pr_err("Device must be connected to a high-speed USB 2.0 port.\n"); + dev_err(&udev->dev, "Device initialization failed.\n"); + dev_err(&udev->dev, + "Device must be connected to a high-speed USB 2.0 port.\n"); retval = -ENODEV; goto err_free; } @@ -3585,7 +3599,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev->ifnum = ifnum; if (has_vendor_audio) { - pr_info("Audio interface %i found (Vendor Class)\n", ifnum); + dev_err(&udev->dev, + "Audio interface %i found (Vendor Class)\n", ifnum); dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; } /* Checks if audio is provided by a USB Audio Class interface */ @@ -3594,7 +3609,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) - pr_err("em28xx: device seems to have vendor AND usb audio class interfaces !\n" + dev_err(&udev->dev, + "em28xx: device seems to have vendor AND usb audio class interfaces !\n" "\t\tThe vendor interface will be ignored. Please contact the developers \n"); dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; break; @@ -3602,12 +3618,12 @@ static int em28xx_usb_probe(struct usb_interface *interface, } if (has_video) - pr_info("Video interface %i found:%s%s\n", + dev_err(&udev->dev, "Video interface %i found:%s%s\n", ifnum, dev->analog_ep_bulk ? " bulk" : "", dev->analog_ep_isoc ? " isoc" : ""); if (has_dvb) - pr_info("DVB interface %i found:%s%s\n", + dev_err(&udev->dev, "DVB interface %i found:%s%s\n", ifnum, dev->dvb_ep_bulk ? " bulk" : "", dev->dvb_ep_isoc ? " isoc" : ""); @@ -3639,7 +3655,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Disable V4L2 if the device doesn't have a decoder */ if (has_video && dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) { - pr_err("Currently, V4L2 is not supported on this model\n"); + dev_err(&udev->dev, + "Currently, V4L2 is not supported on this model\n"); has_video = false; dev->has_video = false; } @@ -3648,13 +3665,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (has_video) { if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) dev->analog_xfer_bulk = 1; - pr_info("analog set to %s mode.\n", + dev_err(&udev->dev, "analog set to %s mode.\n", dev->analog_xfer_bulk ? "bulk" : "isoc"); } if (has_dvb) { if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) dev->dvb_xfer_bulk = 1; - pr_info("dvb set to %s mode.\n", + dev_err(&udev->dev, "dvb set to %s mode.\n", dev->dvb_xfer_bulk ? "bulk" : "isoc"); } @@ -3702,7 +3719,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) dev->disconnected = 1; - pr_info("Disconnecting %s\n", dev->name); + dev_err(&dev->udev->dev, "Disconnecting\n"); flush_request_modules(dev); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index a413ff7c30d7..7f1fe5d9d685 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -50,25 +50,29 @@ static unsigned int core_debug; module_param(core_debug, int, 0644); MODULE_PARM_DESC(core_debug, "enable debug messages [core and isoc]"); -#define em28xx_coredbg(fmt, arg...) do {\ - if (core_debug) \ - printk(KERN_DEBUG pr_fmt("core: %s: " fmt), \ - __func__, ##arg); } while (0) +#define em28xx_coredbg(fmt, arg...) do { \ + if (core_debug) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "core: %s: " fmt, __func__, ## arg); \ +} while (0) static unsigned int reg_debug; module_param(reg_debug, int, 0644); MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); -#define em28xx_regdbg(fmt, arg...) do {\ - if (reg_debug) \ - printk(KERN_DEBUG pr_fmt("reg: %s: " fmt), \ - __func__, ##arg); } while (0) -/* FIXME */ -#define em28xx_isocdbg(fmt, arg...) do {\ - if (core_debug) \ - printk(KERN_DEBUG pr_fmt("isoc: %s: " fmt), \ - __func__, ##arg); } while (0) +#define em28xx_regdbg(fmt, arg...) do { \ + if (reg_debug) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "reg: %s: " fmt, __func__, ## arg); \ +} while (0) + +/* FIXME: don't abuse core_debug */ +#define em28xx_isocdbg(fmt, arg...) do { \ + if (core_debug) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "core: %s: " fmt, __func__, ## arg); \ +} while (0) /* * em28xx_read_reg_req() @@ -86,23 +90,22 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (len > URB_MAX_CTRL_SIZE) return -EINVAL; - if (reg_debug) { - printk(KERN_DEBUG - "(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x ", - pipe, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - req, 0, 0, - reg & 0xff, reg >> 8, - len & 0xff, len >> 8); - } + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x ", + pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8); mutex_lock(&dev->ctrl_urb_lock); ret = usb_control_msg(dev->udev, pipe, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, reg, dev->urb_buf, len, HZ); if (ret < 0) { - if (reg_debug) - pr_cont(" failed!\n"); + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed\n", + pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8); mutex_unlock(&dev->ctrl_urb_lock); return usb_translate_errors(ret); } @@ -112,14 +115,11 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, mutex_unlock(&dev->ctrl_urb_lock); - if (reg_debug) { - int byte; - - pr_cont("<<<"); - for (byte = 0; byte < len; byte++) - pr_cont(" %02x", (unsigned char)buf[byte]); - pr_cont("\n"); - } + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed <<< %*ph\n", + pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, len, buf); return ret; } @@ -162,21 +162,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) return -EINVAL; - if (reg_debug) { - int byte; - - printk(KERN_DEBUG - "(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", - pipe, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - req, 0, 0, - reg & 0xff, reg >> 8, - len & 0xff, len >> 8); - - for (byte = 0; byte < len; byte++) - pr_cont(" %02x", (unsigned char)buf[byte]); - pr_cont("\n"); - } + em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph\n", + pipe, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, len, buf); mutex_lock(&dev->ctrl_urb_lock); memcpy(dev->urb_buf, buf, len); @@ -267,7 +258,8 @@ static int em28xx_is_ac97_ready(struct em28xx *dev) msleep(5); } - pr_warn("AC97 command still being executed: not handled properly!\n"); + dev_warn(&dev->udev->dev, + "AC97 command still being executed: not handled properly!\n"); return -EBUSY; } @@ -360,8 +352,9 @@ static int set_ac97_input(struct em28xx *dev) ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); if (ret < 0) - pr_warn("couldn't setup AC97 register %d\n", - inputs[i].reg); + dev_warn(&dev->udev->dev, + "couldn't setup AC97 register %d\n", + inputs[i].reg); } return 0; } @@ -444,8 +437,9 @@ int em28xx_audio_analog_set(struct em28xx *dev) for (i = 0; i < ARRAY_SIZE(outputs); i++) { ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); if (ret < 0) - pr_warn("couldn't setup AC97 register %d\n", - outputs[i].reg); + dev_warn(&dev->udev->dev, + "couldn't setup AC97 register %d\n", + outputs[i].reg); } } @@ -482,8 +476,9 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_write_ac97(dev, outputs[i].reg, vol); if (ret < 0) - pr_warn("couldn't setup AC97 register %d\n", - outputs[i].reg); + dev_warn(&dev->udev->dev, + "couldn't setup AC97 register %d\n", + outputs[i].reg); } if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { @@ -519,7 +514,7 @@ int em28xx_audio_setup(struct em28xx *dev) /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); - pr_info("Config register raw data: 0x%02x\n", cfg); + dev_info(&dev->udev->dev, "Config register raw data: 0x%02x\n", cfg); if (cfg < 0) { /* Register read error */ /* Be conservative */ dev->int_audio_type = EM28XX_INT_AUDIO_AC97; @@ -540,7 +535,7 @@ int em28xx_audio_setup(struct em28xx *dev) i2s_samplerates = 5; else i2s_samplerates = 3; - pr_info("I2S Audio (%d sample rate(s))\n", + dev_info(&dev->udev->dev, "I2S Audio (%d sample rate(s))\n", i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; @@ -558,7 +553,8 @@ int em28xx_audio_setup(struct em28xx *dev) * Note: (some) em2800 devices without eeprom reports 0x91 on * CHIPCFG register, even not having an AC97 chip */ - pr_warn("AC97 chip type couldn't be determined\n"); + dev_warn(&dev->udev->dev, + "AC97 chip type couldn't be determined\n"); dev->audio_mode.ac97 = EM28XX_NO_AC97; if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR) dev->usb_audio_type = EM28XX_USB_AUDIO_NONE; @@ -571,13 +567,13 @@ int em28xx_audio_setup(struct em28xx *dev) goto init_audio; vid = vid1 << 16 | vid2; - pr_warn("AC97 vendor ID = 0x%08x\n", vid); + dev_warn(&dev->udev->dev, "AC97 vendor ID = 0x%08x\n", vid); feat = em28xx_read_ac97(dev, AC97_RESET); if (feat < 0) goto init_audio; - pr_warn("AC97 features = 0x%04x\n", feat); + dev_warn(&dev->udev->dev, "AC97 features = 0x%04x\n", feat); /* Try to identify what audio processor we have */ if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) @@ -589,17 +585,20 @@ init_audio: /* Reports detected AC97 processor */ switch (dev->audio_mode.ac97) { case EM28XX_NO_AC97: - pr_info("No AC97 audio processor\n"); + dev_info(&dev->udev->dev, "No AC97 audio processor\n"); break; case EM28XX_AC97_EM202: - pr_info("Empia 202 AC97 audio processor detected\n"); + dev_info(&dev->udev->dev, + "Empia 202 AC97 audio processor detected\n"); break; case EM28XX_AC97_SIGMATEL: - pr_info("Sigmatel audio processor detected (stac 97%02x)\n", - vid & 0xff); + dev_info(&dev->udev->dev, + "Sigmatel audio processor detected (stac 97%02x)\n", + vid & 0xff); break; case EM28XX_AC97_OTHER: - pr_warn("Unknown AC97 audio processor detected!\n"); + dev_warn(&dev->udev->dev, + "Unknown AC97 audio processor detected!\n"); break; default: break; @@ -883,21 +882,23 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if (mode == EM28XX_DIGITAL_MODE) { if ((xfer_bulk && !dev->dvb_ep_bulk) || (!xfer_bulk && !dev->dvb_ep_isoc)) { - pr_err("no endpoint for DVB mode and transfer type %d\n", - xfer_bulk > 0); + dev_err(&dev->udev->dev, + "no endpoint for DVB mode and transfer type %d\n", + xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.digital_bufs; } else if (mode == EM28XX_ANALOG_MODE) { if ((xfer_bulk && !dev->analog_ep_bulk) || (!xfer_bulk && !dev->analog_ep_isoc)) { - pr_err("no endpoint for analog mode and transfer type %d\n", - xfer_bulk > 0); + dev_err(&dev->udev->dev, + "no endpoint for analog mode and transfer type %d\n", + xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.analog_bufs; } else { - pr_err("invalid mode selected\n"); + dev_err(&dev->udev->dev, "invalid mode selected\n"); return -EINVAL; } @@ -939,7 +940,8 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + dev_err(&dev->udev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); em28xx_uninit_usb_xfer(dev, mode); @@ -1021,7 +1023,8 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, if (xfer_bulk) { rc = usb_clear_halt(dev->udev, usb_bufs->urb[0]->pipe); if (rc < 0) { - pr_err("failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", + dev_err(&dev->udev->dev, + "failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", rc); em28xx_uninit_usb_xfer(dev, mode); return rc; @@ -1037,7 +1040,8 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, for (i = 0; i < usb_bufs->num_bufs; i++) { rc = usb_submit_urb(usb_bufs->urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, rc); + dev_err(&dev->udev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); em28xx_uninit_usb_xfer(dev, mode); return rc; } @@ -1085,7 +1089,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) } list_del(&ops->next); mutex_unlock(&em28xx_devlist_mutex); - pr_info("Em28xx: Removed (%s) extension\n", ops->name); + pr_info("em28xx: Removed (%s) extension\n", ops->name); } EXPORT_SYMBOL(em28xx_unregister_extension); @@ -1119,7 +1123,7 @@ int em28xx_suspend_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - pr_info("Suspending extensions\n"); + dev_info(&dev->udev->dev, "Suspending extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->suspend) @@ -1133,7 +1137,7 @@ int em28xx_resume_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - pr_info("Resuming extensions\n"); + dev_info(&dev->udev->dev, "Resuming extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->resume) diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 6feb0e416eac..445e51db636f 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -73,9 +73,10 @@ MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ - printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "dvb: " fmt, ## arg); \ } while (0) struct em28xx_dvb { @@ -735,7 +736,7 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) ret = gpio_request_one(dvb->lna_gpio, flags, NULL); if (ret) - pr_err("gpio request failed %d\n", ret); + dev_err(&dev->udev->dev, "gpio request failed %d\n", ret); else gpio_free(dvb->lna_gpio); @@ -935,19 +936,20 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) cfg.ctrl = &ctl; if (!dev->dvb->fe[0]) { - pr_err("dvb frontend not attached. Can't attach xc3028\n"); + dev_err(&dev->udev->dev, + "dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); if (!fe) { - pr_err("xc3028 attach failed\n"); + dev_err(&dev->udev->dev, "xc3028 attach failed\n"); dvb_frontend_detach(dev->dvb->fe[0]); dev->dvb->fe[0] = NULL; return -EINVAL; } - pr_info("xc3028 attached\n"); + dev_info(&dev->udev->dev, "xc3028 attached\n"); return 0; } @@ -963,11 +965,13 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, mutex_init(&dvb->lock); /* register adapter */ - result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, - adapter_nr); + result = dvb_register_adapter(&dvb->adapter, + dev_name(&dev->udev->dev), module, + device, adapter_nr); if (result < 0) { - pr_warn("dvb_register_adapter failed (errno = %d)\n", - result); + dev_warn(&dev->udev->dev, + "dvb_register_adapter failed (errno = %d)\n", + result); goto fail_adapter; } #ifdef CONFIG_MEDIA_CONTROLLER_DVB @@ -984,8 +988,9 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]); if (result < 0) { - pr_warn("dvb_register_frontend failed (errno = %d)\n", - result); + dev_warn(&dev->udev->dev, + "dvb_register_frontend failed (errno = %d)\n", + result); goto fail_frontend0; } @@ -993,8 +998,9 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, if (dvb->fe[1]) { result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); if (result < 0) { - pr_warn("2nd dvb_register_frontend failed (errno = %d)\n", - result); + dev_warn(&dev->udev->dev, + "2nd dvb_register_frontend failed (errno = %d)\n", + result); goto fail_frontend1; } } @@ -1011,7 +1017,9 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - pr_warn("dvb_dmx_init failed (errno = %d)\n", result); + dev_warn(&dev->udev->dev, + "dvb_dmx_init failed (errno = %d)\n", + result); goto fail_dmx; } @@ -1020,29 +1028,35 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - pr_warn("dvb_dmxdev_init failed (errno = %d)\n", result); + dev_warn(&dev->udev->dev, + "dvb_dmxdev_init failed (errno = %d)\n", + result); goto fail_dmxdev; } dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - pr_warn("add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", - result); + dev_warn(&dev->udev->dev, + "add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", + result); goto fail_fe_hw; } dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - pr_warn("add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", - result); + dev_warn(&dev->udev->dev, + "add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + result); goto fail_fe_mem; } result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - pr_warn("connect_frontend failed (errno = %d)\n", result); + dev_warn(&dev->udev->dev, + "connect_frontend failed (errno = %d)\n", + result); goto fail_fe_conn; } @@ -1114,7 +1128,7 @@ static int em28xx_dvb_init(struct em28xx *dev) return 0; } - pr_info("Binding DVB extension\n"); + dev_info(&dev->udev->dev, "Binding DVB extension\n"); dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (!dvb) @@ -1138,7 +1152,8 @@ static int em28xx_dvb_init(struct em28xx *dev) EM28XX_DVB_NUM_ISOC_PACKETS); } if (result) { - pr_err("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n"); + dev_err(&dev->udev->dev, + "failed to pre-allocate USB transfer buffers for DVB.\n"); kfree(dvb); dev->dvb = NULL; return result; @@ -1317,8 +1332,9 @@ static int em28xx_dvb_init(struct em28xx *dev) result = gpio_request_one(dvb->lna_gpio, GPIOF_OUT_INIT_LOW, NULL); if (result) - pr_err("gpio request failed %d\n", - result); + dev_err(&dev->udev->dev, + "gpio request failed %d\n", + result); else gpio_free(dvb->lna_gpio); @@ -1933,11 +1949,12 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; default: - pr_err("The frontend of your DVB/ATSC card isn't supported yet\n"); + dev_err(&dev->udev->dev, + "The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { - pr_err("frontend initialization failed\n"); + dev_err(&dev->udev->dev, "frontend initialization failed\n"); result = -EINVAL; goto out_free; } @@ -1952,7 +1969,7 @@ static int em28xx_dvb_init(struct em28xx *dev) if (result < 0) goto out_free; - pr_info("DVB extension successfully initialized\n"); + dev_info(&dev->udev->dev, "DVB extension successfully initialized\n"); kref_get(&dev->ref); @@ -1992,7 +2009,7 @@ static int em28xx_dvb_fini(struct em28xx *dev) if (!dev->dvb) return 0; - pr_info("Closing DVB extension\n"); + dev_info(&dev->udev->dev, "Closing DVB extension\n"); dvb = dev->dvb; @@ -2050,17 +2067,17 @@ static int em28xx_dvb_suspend(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - pr_info("Suspending DVB extension\n"); + dev_info(&dev->udev->dev, "Suspending DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_suspend(dvb->fe[0]); - pr_info("fe0 suspend %d\n", ret); + dev_info(&dev->udev->dev, "fe0 suspend %d\n", ret); } if (dvb->fe[1]) { dvb_frontend_suspend(dvb->fe[1]); - pr_info("fe1 suspend %d\n", ret); + dev_info(&dev->udev->dev, "fe1 suspend %d\n", ret); } } @@ -2077,18 +2094,18 @@ static int em28xx_dvb_resume(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - pr_info("Resuming DVB extension\n"); + dev_info(&dev->udev->dev, "Resuming DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_resume(dvb->fe[0]); - pr_info("fe0 resume %d\n", ret); + dev_info(&dev->udev->dev, "fe0 resume %d\n", ret); } if (dvb->fe[1]) { ret = dvb_frontend_resume(dvb->fe[1]); - pr_info("fe1 resume %d\n", ret); + dev_info(&dev->udev->dev, "fe1 resume %d\n", ret); } } diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index b7a5b4c5ceff..00e39edc0837 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -44,6 +44,13 @@ static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)"); +#define dprintk(level, fmt, arg...) do { \ + if (i2c_debug > level) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "i2c: %s: " fmt, __func__, ## arg); \ +} while (0) + + /* * em2800_i2c_send_bytes() * send up to 4 bytes to the em2800 i2c device @@ -71,7 +78,8 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) /* trigger write */ ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); if (ret != 2 + len) { - pr_warn("failed to trigger write to i2c address 0x%x (error=%i)\n", + dev_warn(&dev->udev->dev, + "failed to trigger write to i2c address 0x%x (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; } @@ -81,20 +89,18 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) if (ret == 0x80 + len - 1) return len; if (ret == 0x94 + len - 1) { - if (i2c_debug == 1) - pr_warn("R05 returned 0x%02x: I2C ACK error\n", - ret); + dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } if (ret < 0) { - pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", + dev_warn(&dev->udev->dev, + "failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; } msleep(5); } - if (i2c_debug) - pr_warn("write to i2c device at 0x%x timed out\n", addr); + dprintk(0, "write to i2c device at 0x%x timed out\n", addr); return -ETIMEDOUT; } @@ -117,8 +123,9 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) buf2[0] = addr; ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); if (ret != 2) { - pr_warn("failed to trigger read from i2c address 0x%x (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "failed to trigger read from i2c address 0x%x (error=%i)\n", + addr, ret); return (ret < 0) ? ret : -EIO; } @@ -128,29 +135,28 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) if (ret == 0x84 + len - 1) break; if (ret == 0x94 + len - 1) { - if (i2c_debug == 1) - pr_warn("R05 returned 0x%02x: I2C ACK error\n", - ret); + dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", + ret); return -ENXIO; } if (ret < 0) { - pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + dev_warn(&dev->udev->dev, + "failed to get i2c transfer status from bridge register (error=%i)\n", + ret); return ret; } msleep(5); } if (ret != 0x84 + len - 1) { - if (i2c_debug) - pr_warn("read from i2c device at 0x%x timed out\n", - addr); + dprintk(0, "read from i2c device at 0x%x timed out\n", addr); } /* get the received message */ ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); if (ret != len) { - pr_warn("reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", + addr, ret); return (ret < 0) ? ret : -EIO; } for (i = 0; i < len; i++) @@ -194,12 +200,14 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); if (ret != len) { if (ret < 0) { - pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "writing to i2c device at 0x%x failed (error=%i)\n", + addr, ret); return ret; } else { - pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); + dev_warn(&dev->udev->dev, + "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + len, addr, ret); return -EIO; } } @@ -210,14 +218,14 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret == 0) /* success */ return len; if (ret == 0x10) { - if (i2c_debug == 1) - pr_warn("I2C ACK error on writing to addr 0x%02x\n", - addr); + dprintk(1, "I2C ACK error on writing to addr 0x%02x\n", + addr); return -ENXIO; } if (ret < 0) { - pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + dev_warn(&dev->udev->dev, + "failed to get i2c transfer status from bridge register (error=%i)\n", + ret); return ret; } msleep(5); @@ -230,14 +238,15 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (ret == 0x02 || ret == 0x04) { /* NOTE: these errors seem to be related to clock stretching */ - if (i2c_debug) - pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", - addr, ret); + dprintk(0, + "write to i2c device at 0x%x timed out (status=%i)\n", + addr, ret); return -ETIMEDOUT; } - pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "write to i2c device at 0x%x failed with unknown error (status=%i)\n", + addr, ret); return -EIO; } @@ -259,8 +268,9 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) /* Read data from i2c device */ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); if (ret < 0) { - pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "reading from i2c device at 0x%x failed (error=%i)\n", + addr, ret); return ret; } /* @@ -277,27 +287,28 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) if (ret == 0) /* success */ return len; if (ret < 0) { - pr_warn("failed to get i2c transfer status from bridge register (error=%i)\n", - ret); + dev_warn(&dev->udev->dev, + "failed to get i2c transfer status from bridge register (error=%i)\n", + ret); return ret; } if (ret == 0x10) { - if (i2c_debug == 1) - pr_warn("I2C ACK error on writing to addr 0x%02x\n", - addr); + dprintk(1, "I2C ACK error on writing to addr 0x%02x\n", + addr); return -ENXIO; } if (ret == 0x02 || ret == 0x04) { /* NOTE: these errors seem to be related to clock stretching */ - if (i2c_debug) - pr_warn("write to i2c device at 0x%x timed out (status=%i)\n", - addr, ret); + dprintk(0, + "write to i2c device at 0x%x timed out (status=%i)\n", + addr, ret); return -ETIMEDOUT; } - pr_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "write to i2c device at 0x%x failed with unknown error (status=%i)\n", + addr, ret); return -EIO; } @@ -336,12 +347,14 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len); if (ret != len) { if (ret < 0) { - pr_warn("writing to i2c device at 0x%x failed (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "writing to i2c device at 0x%x failed (error=%i)\n", + addr, ret); return ret; } else { - pr_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", - len, addr, ret); + dev_warn(&dev->udev->dev, + "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", + len, addr, ret); return -EIO; } } @@ -354,9 +367,7 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (!ret) return len; else if (ret > 0) { - if (i2c_debug == 1) - pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", - ret); + dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -387,8 +398,9 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, /* Read value */ ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); if (ret < 0) { - pr_warn("reading from i2c device at 0x%x failed (error=%i)\n", - addr, ret); + dev_warn(&dev->udev->dev, + "reading from i2c device at 0x%x failed (error=%i)\n", + addr, ret); return ret; } /* @@ -409,9 +421,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, if (!ret) return len; else if (ret > 0) { - if (i2c_debug == 1) - pr_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", - ret); + dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); return -ENXIO; } @@ -529,57 +539,46 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, } for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - if (i2c_debug > 1) - printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", - dev->name, __func__ , - (msgs[i].flags & I2C_M_RD) ? "read" : "write", - i == num - 1 ? "stop" : "nonstop", - addr, msgs[i].len); if (!msgs[i].len) { /* * no len: check only for device presence * This code is only called during device probe. */ rc = i2c_check_for_device(i2c_bus, addr); - if (rc < 0) { - if (rc == -ENXIO) { - if (i2c_debug > 1) - pr_cont(" no device\n"); - rc = -ENODEV; - } else { - if (i2c_debug > 1) - pr_cont(" ERROR: %i\n", rc); - } - rt_mutex_unlock(&dev->i2c_bus_lock); - return rc; - } + + if (rc == -ENXIO) + rc = -ENODEV; } else if (msgs[i].flags & I2C_M_RD) { /* read bytes */ rc = i2c_recv_bytes(i2c_bus, msgs[i]); - - if (i2c_debug > 1 && rc >= 0) - pr_cont(" %*ph", - msgs[i].len, msgs[i].buf); } else { - if (i2c_debug > 1) - pr_cont(" %*ph", - msgs[i].len, msgs[i].buf); - /* write bytes */ rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1); } - if (rc < 0) { - if (i2c_debug > 1) - pr_cont(" ERROR: %i\n", rc); - rt_mutex_unlock(&dev->i2c_bus_lock); - return rc; - } - if (i2c_debug > 1) - pr_cont("\n"); + + if (rc < 0) + goto error; + + dprintk(2, "%s %s addr=%02x len=%d: %*ph\n", + (msgs[i].flags & I2C_M_RD) ? "read" : "write", + i == num - 1 ? "stop" : "nonstop", + addr, msgs[i].len, + msgs[i].len, msgs[i].buf); } rt_mutex_unlock(&dev->i2c_bus_lock); return num; + +error: + dprintk(2, "%s %s addr=%02x len=%d: %sERROR: %i\n", + (msgs[i].flags & I2C_M_RD) ? "read" : "write", + i == num - 1 ? "stop" : "nonstop", + addr, msgs[i].len, + (rc == -ENODEV) ? "no device " : "", + rc); + + rt_mutex_unlock(&dev->i2c_bus_lock); + return rc; } /* @@ -673,7 +672,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); if (err < 0) { - pr_info("board has no eeprom\n"); + dev_info(&dev->udev->dev, "board has no eeprom\n"); return -ENODEV; } @@ -686,17 +685,19 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->eeprom_addrwidth_16bit, len, data); if (err != len) { - pr_err("failed to read eeprom (err=%d)\n", err); + dev_err(&dev->udev->dev, + "failed to read eeprom (err=%d)\n", err); goto error; } if (i2c_debug) { /* Display eeprom content */ - print_hex_dump(KERN_INFO, "eeprom ", DUMP_PREFIX_OFFSET, + print_hex_dump(KERN_DEBUG, "em28xx eeprom ", DUMP_PREFIX_OFFSET, 16, 1, data, len, true); if (dev->eeprom_addrwidth_16bit) - pr_info("eeprom %06x: ... (skipped)\n", 256); + dev_info(&dev->udev->dev, + "eeprom %06x: ... (skipped)\n", 256); } if (dev->eeprom_addrwidth_16bit && @@ -708,11 +709,14 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->hash = em28xx_hash_mem(data, len, 32); mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ - pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); - pr_info("EEPROM info:\n"); - pr_info("\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", - mc_start, data[2]); + dev_info(&dev->udev->dev, + "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", + data[0], data[1], data[2], data[3], dev->hash); + dev_info(&dev->udev->dev, + "EEPROM info:\n"); + dev_info(&dev->udev->dev, + "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", + mc_start, data[2]); /* * boot configuration (address 0x0002): * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz @@ -730,8 +734,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, data); if (err != 2) { - pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", - err); + dev_err(&dev->udev->dev, + "failed to read hardware configuration data from eeprom (err=%d)\n", + err); goto error; } @@ -748,8 +753,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, data); if (err != len) { - pr_err("failed to read hardware configuration data from eeprom (err=%d)\n", - err); + dev_err(&dev->udev->dev, + "failed to read hardware configuration data from eeprom (err=%d)\n", + err); goto error; } @@ -757,7 +763,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* NOTE: not all devices provide this type of dataset */ if (data[0] != 0x1a || data[1] != 0xeb || data[2] != 0x67 || data[3] != 0x95) { - pr_info("\tno hardware configuration dataset found in eeprom\n"); + dev_info(&dev->udev->dev, + "\tno hardware configuration dataset found in eeprom\n"); kfree(data); return 0; } @@ -768,11 +775,14 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data[0] == 0x1a && data[1] == 0xeb && data[2] == 0x67 && data[3] == 0x95) { dev->hash = em28xx_hash_mem(data, len, 32); - pr_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - data[0], data[1], data[2], data[3], dev->hash); - pr_info("EEPROM info:\n"); + dev_info(&dev->udev->dev, + "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", + data[0], data[1], data[2], data[3], dev->hash); + dev_info(&dev->udev->dev, + "EEPROM info:\n"); } else { - pr_info("unknown eeprom format or eeprom corrupted !\n"); + dev_info(&dev->udev->dev, + "unknown eeprom format or eeprom corrupted !\n"); err = -ENODEV; goto error; } @@ -783,50 +793,55 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { case 0: - pr_info("\tNo audio on board.\n"); + dev_info(&dev->udev->dev, "\tNo audio on board.\n"); break; case 1: - pr_info("\tAC97 audio (5 sample rates)\n"); + dev_info(&dev->udev->dev, "\tAC97 audio (5 sample rates)\n"); break; case 2: if (dev->chip_id < CHIP_ID_EM2860) - pr_info("\tI2S audio, sample rate=32k\n"); + dev_info(&dev->udev->dev, + "\tI2S audio, sample rate=32k\n"); else - pr_info("\tI2S audio, 3 sample rates\n"); + dev_info(&dev->udev->dev, + "\tI2S audio, 3 sample rates\n"); break; case 3: if (dev->chip_id < CHIP_ID_EM2860) - pr_info("\tI2S audio, 3 sample rates\n"); + dev_info(&dev->udev->dev, + "\tI2S audio, 3 sample rates\n"); else - pr_info("\tI2S audio, 5 sample rates\n"); + dev_info(&dev->udev->dev, + "\tI2S audio, 5 sample rates\n"); break; } if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) - pr_info("\tUSB Remote wakeup capable\n"); + dev_info(&dev->udev->dev, "\tUSB Remote wakeup capable\n"); if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) - pr_info("\tUSB Self power capable\n"); + dev_info(&dev->udev->dev, "\tUSB Self power capable\n"); switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { case 0: - pr_info("\t500mA max power\n"); + dev_info(&dev->udev->dev, "\t500mA max power\n"); break; case 1: - pr_info("\t400mA max power\n"); + dev_info(&dev->udev->dev, "\t400mA max power\n"); break; case 2: - pr_info("\t300mA max power\n"); + dev_info(&dev->udev->dev, "\t300mA max power\n"); break; case 3: - pr_info("\t200mA max power\n"); + dev_info(&dev->udev->dev, "\t200mA max power\n"); break; } - pr_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", - dev_config->string_idx_table, - le16_to_cpu(dev_config->string1), - le16_to_cpu(dev_config->string2), - le16_to_cpu(dev_config->string3)); + dev_info(&dev->udev->dev, + "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", + dev_config->string_idx_table, + le16_to_cpu(dev_config->string1), + le16_to_cpu(dev_config->string2), + le16_to_cpu(dev_config->string3)); return 0; @@ -915,8 +930,9 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) if (rc < 0) continue; i2c_devicelist[i] = i; - pr_info("found i2c device @ 0x%x on bus %d [%s]\n", - i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); + dev_info(&dev->udev->dev, + "found i2c device @ 0x%x on bus %d [%s]\n", + i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); } if (bus == dev->def_i2c_bus) @@ -941,7 +957,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, dev->i2c_adap[bus] = em28xx_adap_template; dev->i2c_adap[bus].dev.parent = &dev->udev->dev; - strcpy(dev->i2c_adap[bus].name, dev->name); + strcpy(dev->i2c_adap[bus].name, dev_name(&dev->udev->dev)); dev->i2c_bus[bus].bus = bus; dev->i2c_bus[bus].algo_type = algo_type; @@ -950,8 +966,9 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { - pr_err("%s: i2c_add_adapter failed! retval [%d]\n", - __func__, retval); + dev_err(&dev->udev->dev, + "%s: i2c_add_adapter failed! retval [%d]\n", + __func__, retval); return retval; } @@ -962,8 +979,9 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, if (!bus) { retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { - pr_err("%s: em28xx_i2_eeprom failed! retval [%d]\n", - __func__, retval); + dev_err(&dev->udev->dev, + "%s: em28xx_i2_eeprom failed! retval [%d]\n", + __func__, retval); return retval; } diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 0e23e65eff15..a1904e2230ea 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -41,10 +41,11 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); #define MODULE_NAME "em28xx" -#define dprintk(fmt, arg...) \ - if (ir_debug) { \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ - } +#define dprintk( fmt, arg...) do { \ + if (ir_debug) \ + dev_printk(KERN_DEBUG, &ir->dev->udev->dev, \ + "input: %s: " fmt, __func__, ## arg); \ +} while (0) /********************************************************** Polling structure used by em28xx IR's @@ -458,8 +459,9 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) case CHIP_ID_EM28178: return em2874_ir_change_protocol(rc_dev, rc_type); default: - pr_err("Unrecognized em28xx chip id 0x%02x: IR not supported\n", - dev->chip_id); + dev_err(&ir->dev->udev->dev, + "Unrecognized em28xx chip id 0x%02x: IR not supported\n", + dev->chip_id); return -EINVAL; } } @@ -567,7 +569,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) struct input_dev *input_dev; int err; - pr_info("Registering snapshot button...\n"); + dev_info(&dev->udev->dev, "Registering snapshot button...\n"); input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; @@ -591,7 +593,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) err = input_register_device(input_dev); if (err) { - pr_err("input_register_device failed\n"); + dev_err(&dev->udev->dev, "input_register_device failed\n"); input_free_device(input_dev); return err; } @@ -631,7 +633,8 @@ static void em28xx_init_buttons(struct em28xx *dev) } else if (button->role == EM28XX_BUTTON_ILLUMINATION) { /* Check sanity */ if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) { - pr_err("BUG: illumination button defined, but no illumination LED.\n"); + dev_err(&dev->udev->dev, + "BUG: illumination button defined, but no illumination LED.\n"); goto next_button; } } @@ -667,7 +670,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) dev->num_button_polling_addresses = 0; /* Deregister input devices */ if (dev->sbutton_input_dev != NULL) { - pr_info("Deregistering snapshot button\n"); + dev_info(&dev->udev->dev, "Deregistering snapshot button\n"); input_unregister_device(dev->sbutton_input_dev); dev->sbutton_input_dev = NULL; } @@ -696,18 +699,20 @@ static int em28xx_ir_init(struct em28xx *dev) i2c_rc_dev_addr = em28xx_probe_i2c_ir(dev); if (!i2c_rc_dev_addr) { dev->board.has_ir_i2c = 0; - pr_warn("No i2c IR remote control device found.\n"); + dev_warn(&dev->udev->dev, + "No i2c IR remote control device found.\n"); return -ENODEV; } } if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { /* No remote control support */ - pr_warn("Remote control support is not available for this card.\n"); + dev_warn(&dev->udev->dev, + "Remote control support is not available for this card.\n"); return 0; } - pr_info("Registering input extension\n"); + dev_info(&dev->udev->dev, "Registering input extension\n"); ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) @@ -791,7 +796,8 @@ static int em28xx_ir_init(struct em28xx *dev) ir->polling = 100; /* ms */ /* init input device */ - snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", dev->name); + snprintf(ir->name, sizeof(ir->name), "%s IR", + dev_name(&dev->udev->dev)); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); @@ -810,7 +816,7 @@ static int em28xx_ir_init(struct em28xx *dev) if (err) goto error; - pr_info("Input extension successfully initalized\n"); + dev_info(&dev->udev->dev, "Input extension successfully initalized\n"); return 0; @@ -831,7 +837,7 @@ static int em28xx_ir_fini(struct em28xx *dev) return 0; } - pr_info("Closing input extension\n"); + dev_info(&dev->udev->dev, "Closing input extension\n"); em28xx_shutdown_buttons(dev); @@ -860,7 +866,7 @@ static int em28xx_ir_suspend(struct em28xx *dev) if (dev->is_audio_only) return 0; - pr_info("Suspending input extension\n"); + dev_info(&dev->udev->dev, "Suspending input extension\n"); if (ir) cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&dev->buttons_query_work); @@ -877,7 +883,7 @@ static int em28xx_ir_resume(struct em28xx *dev) if (dev->is_audio_only) return 0; - pr_info("Resuming input extension\n"); + dev_info(&dev->udev->dev, "Resuming input extension\n"); /* if suspend calls ir_raw_event_unregister(), the should call ir_raw_event_register() */ if (ir) diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 744b3300b153..1b21d001cc7e 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "em28xx-v4l.h" @@ -64,8 +65,9 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb) size = v4l2->vbi_width * v4l2->vbi_height * 2; if (vb2_plane_size(vb, 0) < size) { - pr_info("%s data will not fit into plane (%lu < %lu)\n", - __func__, vb2_plane_size(vb, 0), size); + dev_info(&dev->udev->dev, + "%s data will not fit into plane (%lu < %lu)\n", + __func__, vb2_plane_size(vb, 0), size); return -EINVAL; } vb2_set_plane_payload(vb, 0, size); diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 8b5e13bbfb07..2d282ed9aac0 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -64,15 +64,17 @@ static int alt; module_param(alt, int, 0644); MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); -#define em28xx_videodbg(fmt, arg...) do {\ - if (video_debug) \ - printk(KERN_DEBUG pr_fmt("video: %s: " fmt), \ - __func__, ##arg); } while (0) +#define em28xx_videodbg(fmt, arg...) do { \ + if (video_debug) \ + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "video: %s: " fmt, __func__, ## arg); \ +} while (0) #define em28xx_isocdbg(fmt, arg...) do {\ if (isoc_debug) \ - printk(KERN_DEBUG pr_fmt("isoc: %s: " fmt), \ - __func__, ##arg); } while (0) + dev_printk(KERN_DEBUG, &dev->udev->dev, \ + "isoc: %s: " fmt, __func__, ## arg); \ +} while (0) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); @@ -411,8 +413,9 @@ set_alt: dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); if (errCode < 0) { - pr_err("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); + dev_err(&dev->udev->dev, + "cannot change alternate number to %d (error=%i)\n", + dev->alt, errCode); return errCode; } return 0; @@ -923,10 +926,11 @@ static int em28xx_enable_analog_tuner(struct em28xx *dev) ret = media_entity_setup_link(link, flags); if (ret) { - pr_err("Couldn't change link %s->%s to %s. Error %d\n", - source->name, sink->name, - flags ? "enabled" : "disabled", - ret); + dev_err(&dev->udev->dev, + "Couldn't change link %s->%s to %s. Error %d\n", + source->name, sink->name, + flags ? "enabled" : "disabled", + ret); return ret; } else em28xx_videodbg("link %s->%s was %s\n", @@ -954,14 +958,16 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) v4l2->video_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&v4l2->vdev.entity, 1, &v4l2->video_pad); if (ret < 0) - pr_err("failed to initialize video media entity!\n"); + dev_err(&dev->udev->dev, + "failed to initialize video media entity!\n"); if (em28xx_vbi_supported(dev)) { v4l2->vbi_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&v4l2->vbi_dev.entity, 1, &v4l2->vbi_pad); if (ret < 0) - pr_err("failed to initialize vbi media entity!\n"); + dev_err(&dev->udev->dev, + "failed to initialize vbi media entity!\n"); } /* Webcams don't have input connectors */ @@ -994,11 +1000,13 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]); if (ret < 0) - pr_err("failed to initialize input pad[%d]!\n", i); + dev_err(&dev->udev->dev, + "failed to initialize input pad[%d]!\n", i); ret = media_device_register_entity(dev->media_dev, ent); if (ret < 0) - pr_err("failed to register input entity %d!\n", i); + dev_err(&dev->udev->dev, + "failed to register input entity %d!\n", i); } #endif } @@ -2045,7 +2053,8 @@ static int em28xx_v4l2_open(struct file *filp) ret = v4l2_fh_open(filp); if (ret) { - pr_err("%s: v4l2_fh_open() returned error %d\n", + dev_err(&dev->udev->dev, + "%s: v4l2_fh_open() returned error %d\n", __func__, ret); mutex_unlock(&dev->lock); return ret; @@ -2100,7 +2109,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) if (v4l2 == NULL) return 0; - pr_info("Closing video extension\n"); + dev_info(&dev->udev->dev, "Closing video extension\n"); mutex_lock(&dev->lock); @@ -2111,17 +2120,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) em28xx_v4l2_media_release(dev); if (video_is_registered(&v4l2->radio_dev)) { - pr_info("V4L2 device %s deregistered\n", + dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - pr_info("V4L2 device %s deregistered\n", + dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - pr_info("V4L2 device %s deregistered\n", + dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } @@ -2151,7 +2160,7 @@ static int em28xx_v4l2_suspend(struct em28xx *dev) if (!dev->has_video) return 0; - pr_info("Suspending video extension\n"); + dev_info(&dev->udev->dev, "Suspending video extension\n"); em28xx_stop_urbs(dev); return 0; } @@ -2164,7 +2173,7 @@ static int em28xx_v4l2_resume(struct em28xx *dev) if (!dev->has_video) return 0; - pr_info("Resuming video extension\n"); + dev_info(&dev->udev->dev, "Resuming video extension\n"); /* what do we do here */ return 0; } @@ -2201,8 +2210,9 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_videodbg("setting alternate 0\n"); errCode = usb_set_interface(dev->udev, 0, 0); if (errCode < 0) { - pr_err("cannot change alternate number to 0 (error=%i)\n", - errCode); + dev_err(&dev->udev->dev, + "cannot change alternate number to 0 (error=%i)\n", + errCode); } } @@ -2335,7 +2345,7 @@ static void em28xx_vdev_init(struct em28xx *dev, vfd->tvnorms = 0; snprintf(vfd->name, sizeof(vfd->name), "%s %s", - dev->name, type_name); + dev_name(&dev->udev->dev), type_name); video_set_drvdata(vfd, dev); } @@ -2419,7 +2429,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) return 0; } - pr_info("Registering V4L2 extension\n"); + dev_info(&dev->udev->dev, "Registering V4L2 extension\n"); mutex_lock(&dev->lock); @@ -2437,7 +2447,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) #endif ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev); if (ret < 0) { - pr_err("Call to v4l2_device_register() failed!\n"); + dev_err(&dev->udev->dev, + "Call to v4l2_device_register() failed!\n"); goto err; } @@ -2521,8 +2532,9 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Configure audio */ ret = em28xx_audio_setup(dev); if (ret < 0) { - pr_err("%s: Error while setting audio - error [%d]!\n", - __func__, ret); + dev_err(&dev->udev->dev, + "%s: Error while setting audio - error [%d]!\n", + __func__, ret); goto unregister_dev; } if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { @@ -2549,16 +2561,18 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Send a reset to other chips via gpio */ ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); if (ret < 0) { - pr_err("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", - __func__, ret); + dev_err(&dev->udev->dev, + "%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", + __func__, ret); goto unregister_dev; } msleep(3); ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); if (ret < 0) { - pr_err("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", - __func__, ret); + dev_err(&dev->udev->dev, + "%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", + __func__, ret); goto unregister_dev; } msleep(3); @@ -2659,7 +2673,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - pr_err("unable to register video device (error=%i).\n", ret); + dev_err(&dev->udev->dev, + "unable to register video device (error=%i).\n", ret); goto unregister_dev; } @@ -2688,7 +2703,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - pr_err("unable to register vbi device\n"); + dev_err(&dev->udev->dev, + "unable to register vbi device\n"); goto unregister_dev; } } @@ -2699,11 +2715,13 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - pr_err("can't register radio device\n"); + dev_err(&dev->udev->dev, + "can't register radio device\n"); goto unregister_dev; } - pr_info("Registered radio device as %s\n", - video_device_node_name(&v4l2->radio_dev)); + dev_info(&dev->udev->dev, + "Registered radio device as %s\n", + video_device_node_name(&v4l2->radio_dev)); } /* Init entities at the Media Controller */ @@ -2712,18 +2730,21 @@ static int em28xx_v4l2_init(struct em28xx *dev) #ifdef CONFIG_MEDIA_CONTROLLER ret = v4l2_mc_create_media_graph(dev->media_dev); if (ret) { - pr_err("failed to create media graph\n"); + dev_err(&dev->udev->dev, + "failed to create media graph\n"); em28xx_v4l2_media_release(dev); goto unregister_dev; } #endif - pr_info("V4L2 video device registered as %s\n", - video_device_node_name(&v4l2->vdev)); + dev_info(&dev->udev->dev, + "V4L2 video device registered as %s\n", + video_device_node_name(&v4l2->vdev)); if (video_is_registered(&v4l2->vbi_dev)) - pr_info("V4L2 VBI device registered as %s\n", - video_device_node_name(&v4l2->vbi_dev)); + dev_info(&dev->udev->dev, + "V4L2 VBI device registered as %s\n", + video_device_node_name(&v4l2->vbi_dev)); /* Save some power by putting tuner to sleep */ v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); @@ -2731,7 +2752,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* initialize videobuf2 stuff */ em28xx_vb2_setup(dev); - pr_info("V4L2 extension successfully initialized\n"); + dev_info(&dev->udev->dev, + "V4L2 extension successfully initialized\n"); kref_get(&dev->ref); @@ -2740,18 +2762,21 @@ static int em28xx_v4l2_init(struct em28xx *dev) unregister_dev: if (video_is_registered(&v4l2->radio_dev)) { - pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->radio_dev)); + dev_info(&dev->udev->dev, + "V4L2 device %s deregistered\n", + video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vbi_dev)); + dev_info(&dev->udev->dev, + "V4L2 device %s deregistered\n", + video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - pr_info("V4L2 device %s deregistered\n", - video_device_node_name(&v4l2->vdev)); + dev_info(&dev->udev->dev, + "V4L2 device %s deregistered\n", + video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 0f6830f5078b..3e5ace497a4e 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -29,8 +29,6 @@ #define EM28XX_VERSION "0.2.2" #define DRIVER_DESC "Empia em28xx device driver" -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -612,7 +610,6 @@ struct em28xx { struct em28xx_IR *ir; /* generic device properties */ - char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ int devno; /* marks the number of this device */ enum em28xx_chip_id chip_id; -- cgit v1.2.3 From 257e29f84e377d00f29fbb3a78bad25b7e4eb915 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 08:58:05 -0200 Subject: [media] tvp5150: convert it to use dev_foo() macros Instead of using v4l_foo(), use the dev_foo() macros, as most modern media drivers. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 49 ++++++++++++++++----------------- drivers/media/usb/em28xx/em28xx-audio.c | 3 +- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 4740da39d698..569eb7c0968a 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -74,11 +74,11 @@ static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) rc = i2c_smbus_read_byte_data(c, addr); if (rc < 0) { - v4l2_err(sd, "i2c i/o error: rc == %d\n", rc); + dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc); return rc; } - v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, rc); + dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: read 0x%02x = %02x\n", addr, rc); return rc; } @@ -89,10 +89,10 @@ static int tvp5150_write(struct v4l2_subdev *sd, unsigned char addr, struct i2c_client *c = v4l2_get_subdevdata(sd); int rc; - v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", addr, value); + dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: writing %02x %02x\n", addr, value); rc = i2c_smbus_write_byte_data(c, addr, value); if (rc < 0) - v4l2_err(sd, "i2c i/o error: rc == %d\n", rc); + dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc); return rc; } @@ -280,8 +280,7 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd) break; } - v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i " - "=> tvp5150 input=%i, opmode=%i\n", + dev_dbg_lvl(sd->dev, 1, debug, "Selecting video route: route input=%i, output=%i => tvp5150 input=%i, opmode=%i\n", decoder->input, decoder->output, input, opmode); @@ -293,7 +292,7 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd) */ val = tvp5150_read(sd, TVP5150_MISC_CTL); if (val < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", __func__, val); + dev_err(sd->dev, "%s: failed with error = %d\n", __func__, val); return; } @@ -611,7 +610,7 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, const struct i2c_vbi_ram_value *regs = vbi_ram_default; int line; - v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n"); + dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n"); memset(cap, 0, sizeof *cap); while (regs->reg != (u16)-1 ) { @@ -649,7 +648,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd, int pos=0; if (std == V4L2_STD_ALL) { - v4l2_err(sd, "VBI can't be configured without knowing number of lines\n"); + dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); return 0; } else if (std & V4L2_STD_625_50) { /* Don't follow NTSC Line number convension */ @@ -697,7 +696,7 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, int i, ret = 0; if (std == V4L2_STD_ALL) { - v4l2_err(sd, "VBI can't be configured without knowing number of lines\n"); + dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); return 0; } else if (std & V4L2_STD_625_50) { /* Don't follow NTSC Line number convension */ @@ -712,7 +711,7 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, for (i = 0; i <= 1; i++) { ret = tvp5150_read(sd, reg + i); if (ret < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", + dev_err(sd->dev, "%s: failed with error = %d\n", __func__, ret); return 0; } @@ -749,7 +748,7 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std) fmt = VIDEO_STD_SECAM_BIT; } - v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt); + dev_dbg_lvl(sd->dev, 1, debug, "Set video std register to %d.\n", fmt); tvp5150_write(sd, TVP5150_VIDEO_STD, fmt); return 0; } @@ -866,7 +865,7 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd, f->field = V4L2_FIELD_ALTERNATE; f->colorspace = V4L2_COLORSPACE_SMPTE170M; - v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", f->width, + dev_dbg_lvl(sd->dev, 1, debug, "width = %d, height = %d\n", f->width, f->height); return 0; } @@ -884,7 +883,7 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd, sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n", + dev_dbg_lvl(sd->dev, 1, debug, "%s left=%d, top=%d, width=%d, height=%d\n", __func__, rect.left, rect.top, rect.width, rect.height); /* tvp5150 has some special limits */ @@ -1148,7 +1147,7 @@ static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register * res = tvp5150_read(sd, reg->reg & 0xff); if (res < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", __func__, res); + dev_err(sd->dev, "%s: failed with error = %d\n", __func__, res); return res; } @@ -1288,21 +1287,21 @@ static int tvp5150_detect_version(struct tvp5150 *core) core->dev_id = (regs[0] << 8) | regs[1]; core->rom_ver = (regs[2] << 8) | regs[3]; - v4l2_info(sd, "tvp%04x (%u.%u) chip found @ 0x%02x (%s)\n", + dev_info(sd->dev, "tvp%04x (%u.%u) chip found @ 0x%02x (%s)\n", core->dev_id, regs[2], regs[3], c->addr << 1, c->adapter->name); if (core->dev_id == 0x5150 && core->rom_ver == 0x0321) { - v4l2_info(sd, "tvp5150a detected.\n"); + dev_info(sd->dev, "tvp5150a detected.\n"); } else if (core->dev_id == 0x5150 && core->rom_ver == 0x0400) { - v4l2_info(sd, "tvp5150am1 detected.\n"); + dev_info(sd->dev, "tvp5150am1 detected.\n"); /* ITU-T BT.656.4 timing */ tvp5150_write(sd, TVP5150_REV_SELECT, 0); } else if (core->dev_id == 0x5151 && core->rom_ver == 0x0100) { - v4l2_info(sd, "tvp5151 detected.\n"); + dev_info(sd->dev, "tvp5151 detected.\n"); } else { - v4l2_info(sd, "*** unknown tvp%04x chip detected.\n", + dev_info(sd->dev, "*** unknown tvp%04x chip detected.\n", core->dev_id); } @@ -1381,7 +1380,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) for_each_available_child_of_node(connectors, child) { ret = of_property_read_u32(child, "input", &input_type); if (ret) { - v4l2_err(&decoder->sd, + dev_err(decoder->sd.dev, "missing type property in node %s\n", child->name); goto err_connector; @@ -1396,7 +1395,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) /* Each input connector can only be defined once */ if (input->name) { - v4l2_err(&decoder->sd, + dev_err(decoder->sd.dev, "input %s with same type already exists\n", input->name); ret = -EINVAL; @@ -1417,7 +1416,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) ret = of_property_read_string(child, "label", &name); if (ret < 0) { - v4l2_err(&decoder->sd, + dev_err(decoder->sd.dev, "missing label property in node %s\n", child->name); goto err_connector; @@ -1465,7 +1464,7 @@ static int tvp5150_probe(struct i2c_client *c, if (IS_ENABLED(CONFIG_OF) && np) { res = tvp5150_parse_dt(core, np); if (res) { - v4l2_err(sd, "DT parsing error: %d\n", res); + dev_err(sd->dev, "DT parsing error: %d\n", res); return res; } } else { @@ -1549,7 +1548,7 @@ static int tvp5150_remove(struct i2c_client *c) struct v4l2_subdev *sd = i2c_get_clientdata(c); struct tvp5150 *decoder = to_tvp5150(sd); - v4l2_dbg(1, debug, sd, + dev_dbg_lvl(sd->dev, 1, debug, "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", c->addr << 1); diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index cd2545ca5e39..7060e5146e31 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -259,8 +259,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) int nonblock, ret = 0; if (!dev) { - dev_err(&dev->udev->dev, - "BUG: em28xx can't find device struct. Can't proceed with open\n"); + pr_err("em28xx-audio: BUG: em28xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } -- cgit v1.2.3 From ad0e374470684692d7ec1f31ac23065dab4d9d53 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Nov 2016 05:34:12 -0200 Subject: [media] tvp5150: Get rid of direct calls to printk() When returning results via v4l2_subdev_core_ops.log_status, use dev_foo() call, instead of just calling printk() directly, without even specifying the log message level. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 218 ++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 108 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 569eb7c0968a..d0dbdd7ea233 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -36,6 +36,8 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-2)"); +#define dprintk0(__dev, __arg...) dev_dbg_lvl(__dev, 0, 0, __arg) + struct tvp5150 { struct v4l2_subdev sd; #ifdef CONFIG_MEDIA_CONTROLLER @@ -118,120 +120,120 @@ static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init, static int tvp5150_log_status(struct v4l2_subdev *sd) { - printk("tvp5150: Video input source selection #1 = 0x%02x\n", - tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1)); - printk("tvp5150: Analog channel controls = 0x%02x\n", - tvp5150_read(sd, TVP5150_ANAL_CHL_CTL)); - printk("tvp5150: Operation mode controls = 0x%02x\n", - tvp5150_read(sd, TVP5150_OP_MODE_CTL)); - printk("tvp5150: Miscellaneous controls = 0x%02x\n", - tvp5150_read(sd, TVP5150_MISC_CTL)); - printk("tvp5150: Autoswitch mask= 0x%02x\n", - tvp5150_read(sd, TVP5150_AUTOSW_MSK)); - printk("tvp5150: Color killer threshold control = 0x%02x\n", - tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL)); - printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", - tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_1), - tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_2), - tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_3)); - printk("tvp5150: Brightness control = 0x%02x\n", - tvp5150_read(sd, TVP5150_BRIGHT_CTL)); - printk("tvp5150: Color saturation control = 0x%02x\n", - tvp5150_read(sd, TVP5150_SATURATION_CTL)); - printk("tvp5150: Hue control = 0x%02x\n", - tvp5150_read(sd, TVP5150_HUE_CTL)); - printk("tvp5150: Contrast control = 0x%02x\n", - tvp5150_read(sd, TVP5150_CONTRAST_CTL)); - printk("tvp5150: Outputs and data rates select = 0x%02x\n", - tvp5150_read(sd, TVP5150_DATA_RATE_SEL)); - printk("tvp5150: Configuration shared pins = 0x%02x\n", - tvp5150_read(sd, TVP5150_CONF_SHARED_PIN)); - printk("tvp5150: Active video cropping start = 0x%02x%02x\n", - tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_MSB), - tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_LSB)); - printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", - tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_MSB), - tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_LSB)); - printk("tvp5150: Genlock/RTC = 0x%02x\n", - tvp5150_read(sd, TVP5150_GENLOCK)); - printk("tvp5150: Horizontal sync start = 0x%02x\n", - tvp5150_read(sd, TVP5150_HORIZ_SYNC_START)); - printk("tvp5150: Vertical blanking start = 0x%02x\n", - tvp5150_read(sd, TVP5150_VERT_BLANKING_START)); - printk("tvp5150: Vertical blanking stop = 0x%02x\n", - tvp5150_read(sd, TVP5150_VERT_BLANKING_STOP)); - printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", - tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_1), - tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_2)); - printk("tvp5150: Interrupt reset register B = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_RESET_REG_B)); - printk("tvp5150: Interrupt enable register B = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_ENABLE_REG_B)); - printk("tvp5150: Interrupt configuration register B = 0x%02x\n", - tvp5150_read(sd, TVP5150_INTT_CONFIG_REG_B)); - printk("tvp5150: Video standard = 0x%02x\n", - tvp5150_read(sd, TVP5150_VIDEO_STD)); - printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", - tvp5150_read(sd, TVP5150_CB_GAIN_FACT), - tvp5150_read(sd, TVP5150_CR_GAIN_FACTOR)); - printk("tvp5150: Macrovision on counter = 0x%02x\n", - tvp5150_read(sd, TVP5150_MACROVISION_ON_CTR)); - printk("tvp5150: Macrovision off counter = 0x%02x\n", - tvp5150_read(sd, TVP5150_MACROVISION_OFF_CTR)); - printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", - (tvp5150_read(sd, TVP5150_REV_SELECT) & 1) ? 3 : 4); - printk("tvp5150: Device ID = %02x%02x\n", - tvp5150_read(sd, TVP5150_MSB_DEV_ID), - tvp5150_read(sd, TVP5150_LSB_DEV_ID)); - printk("tvp5150: ROM version = (hex) %02x.%02x\n", - tvp5150_read(sd, TVP5150_ROM_MAJOR_VER), - tvp5150_read(sd, TVP5150_ROM_MINOR_VER)); - printk("tvp5150: Vertical line count = 0x%02x%02x\n", - tvp5150_read(sd, TVP5150_VERT_LN_COUNT_MSB), - tvp5150_read(sd, TVP5150_VERT_LN_COUNT_LSB)); - printk("tvp5150: Interrupt status register B = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_STATUS_REG_B)); - printk("tvp5150: Interrupt active register B = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_ACTIVE_REG_B)); - printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", - tvp5150_read(sd, TVP5150_STATUS_REG_1), - tvp5150_read(sd, TVP5150_STATUS_REG_2), - tvp5150_read(sd, TVP5150_STATUS_REG_3), - tvp5150_read(sd, TVP5150_STATUS_REG_4), - tvp5150_read(sd, TVP5150_STATUS_REG_5)); + dprintk0(sd->dev, "tvp5150: Video input source selection #1 = 0x%02x\n", + tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1)); + dprintk0(sd->dev, "tvp5150: Analog channel controls = 0x%02x\n", + tvp5150_read(sd, TVP5150_ANAL_CHL_CTL)); + dprintk0(sd->dev, "tvp5150: Operation mode controls = 0x%02x\n", + tvp5150_read(sd, TVP5150_OP_MODE_CTL)); + dprintk0(sd->dev, "tvp5150: Miscellaneous controls = 0x%02x\n", + tvp5150_read(sd, TVP5150_MISC_CTL)); + dprintk0(sd->dev, "tvp5150: Autoswitch mask= 0x%02x\n", + tvp5150_read(sd, TVP5150_AUTOSW_MSK)); + dprintk0(sd->dev, "tvp5150: Color killer threshold control = 0x%02x\n", + tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL)); + dprintk0(sd->dev, "tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", + tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_1), + tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_2), + tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_3)); + dprintk0(sd->dev, "tvp5150: Brightness control = 0x%02x\n", + tvp5150_read(sd, TVP5150_BRIGHT_CTL)); + dprintk0(sd->dev, "tvp5150: Color saturation control = 0x%02x\n", + tvp5150_read(sd, TVP5150_SATURATION_CTL)); + dprintk0(sd->dev, "tvp5150: Hue control = 0x%02x\n", + tvp5150_read(sd, TVP5150_HUE_CTL)); + dprintk0(sd->dev, "tvp5150: Contrast control = 0x%02x\n", + tvp5150_read(sd, TVP5150_CONTRAST_CTL)); + dprintk0(sd->dev, "tvp5150: Outputs and data rates select = 0x%02x\n", + tvp5150_read(sd, TVP5150_DATA_RATE_SEL)); + dprintk0(sd->dev, "tvp5150: Configuration shared pins = 0x%02x\n", + tvp5150_read(sd, TVP5150_CONF_SHARED_PIN)); + dprintk0(sd->dev, "tvp5150: Active video cropping start = 0x%02x%02x\n", + tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_MSB), + tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_LSB)); + dprintk0(sd->dev, "tvp5150: Active video cropping stop = 0x%02x%02x\n", + tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_MSB), + tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_LSB)); + dprintk0(sd->dev, "tvp5150: Genlock/RTC = 0x%02x\n", + tvp5150_read(sd, TVP5150_GENLOCK)); + dprintk0(sd->dev, "tvp5150: Horizontal sync start = 0x%02x\n", + tvp5150_read(sd, TVP5150_HORIZ_SYNC_START)); + dprintk0(sd->dev, "tvp5150: Vertical blanking start = 0x%02x\n", + tvp5150_read(sd, TVP5150_VERT_BLANKING_START)); + dprintk0(sd->dev, "tvp5150: Vertical blanking stop = 0x%02x\n", + tvp5150_read(sd, TVP5150_VERT_BLANKING_STOP)); + dprintk0(sd->dev, "tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", + tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_1), + tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_2)); + dprintk0(sd->dev, "tvp5150: Interrupt reset register B = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_RESET_REG_B)); + dprintk0(sd->dev, "tvp5150: Interrupt enable register B = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_ENABLE_REG_B)); + dprintk0(sd->dev, "tvp5150: Interrupt configuration register B = 0x%02x\n", + tvp5150_read(sd, TVP5150_INTT_CONFIG_REG_B)); + dprintk0(sd->dev, "tvp5150: Video standard = 0x%02x\n", + tvp5150_read(sd, TVP5150_VIDEO_STD)); + dprintk0(sd->dev, "tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", + tvp5150_read(sd, TVP5150_CB_GAIN_FACT), + tvp5150_read(sd, TVP5150_CR_GAIN_FACTOR)); + dprintk0(sd->dev, "tvp5150: Macrovision on counter = 0x%02x\n", + tvp5150_read(sd, TVP5150_MACROVISION_ON_CTR)); + dprintk0(sd->dev, "tvp5150: Macrovision off counter = 0x%02x\n", + tvp5150_read(sd, TVP5150_MACROVISION_OFF_CTR)); + dprintk0(sd->dev, "tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", + (tvp5150_read(sd, TVP5150_REV_SELECT) & 1) ? 3 : 4); + dprintk0(sd->dev, "tvp5150: Device ID = %02x%02x\n", + tvp5150_read(sd, TVP5150_MSB_DEV_ID), + tvp5150_read(sd, TVP5150_LSB_DEV_ID)); + dprintk0(sd->dev, "tvp5150: ROM version = (hex) %02x.%02x\n", + tvp5150_read(sd, TVP5150_ROM_MAJOR_VER), + tvp5150_read(sd, TVP5150_ROM_MINOR_VER)); + dprintk0(sd->dev, "tvp5150: Vertical line count = 0x%02x%02x\n", + tvp5150_read(sd, TVP5150_VERT_LN_COUNT_MSB), + tvp5150_read(sd, TVP5150_VERT_LN_COUNT_LSB)); + dprintk0(sd->dev, "tvp5150: Interrupt status register B = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_STATUS_REG_B)); + dprintk0(sd->dev, "tvp5150: Interrupt active register B = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_ACTIVE_REG_B)); + dprintk0(sd->dev, "tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", + tvp5150_read(sd, TVP5150_STATUS_REG_1), + tvp5150_read(sd, TVP5150_STATUS_REG_2), + tvp5150_read(sd, TVP5150_STATUS_REG_3), + tvp5150_read(sd, TVP5150_STATUS_REG_4), + tvp5150_read(sd, TVP5150_STATUS_REG_5)); dump_reg_range(sd, "Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, TVP5150_TELETEXT_FIL1_END, 8); dump_reg_range(sd, "Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, TVP5150_TELETEXT_FIL2_END, 8); - printk("tvp5150: Teletext filter enable = 0x%02x\n", - tvp5150_read(sd, TVP5150_TELETEXT_FIL_ENA)); - printk("tvp5150: Interrupt status register A = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_STATUS_REG_A)); - printk("tvp5150: Interrupt enable register A = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_ENABLE_REG_A)); - printk("tvp5150: Interrupt configuration = 0x%02x\n", - tvp5150_read(sd, TVP5150_INT_CONF)); - printk("tvp5150: VDP status register = 0x%02x\n", - tvp5150_read(sd, TVP5150_VDP_STATUS_REG)); - printk("tvp5150: FIFO word count = 0x%02x\n", - tvp5150_read(sd, TVP5150_FIFO_WORD_COUNT)); - printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", - tvp5150_read(sd, TVP5150_FIFO_INT_THRESHOLD)); - printk("tvp5150: FIFO reset = 0x%02x\n", - tvp5150_read(sd, TVP5150_FIFO_RESET)); - printk("tvp5150: Line number interrupt = 0x%02x\n", - tvp5150_read(sd, TVP5150_LINE_NUMBER_INT)); - printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", - tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_HIGH), - tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_LOW)); - printk("tvp5150: FIFO output control = 0x%02x\n", - tvp5150_read(sd, TVP5150_FIFO_OUT_CTRL)); - printk("tvp5150: Full field enable = 0x%02x\n", - tvp5150_read(sd, TVP5150_FULL_FIELD_ENA)); - printk("tvp5150: Full field mode register = 0x%02x\n", - tvp5150_read(sd, TVP5150_FULL_FIELD_MODE_REG)); + dprintk0(sd->dev, "tvp5150: Teletext filter enable = 0x%02x\n", + tvp5150_read(sd, TVP5150_TELETEXT_FIL_ENA)); + dprintk0(sd->dev, "tvp5150: Interrupt status register A = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_STATUS_REG_A)); + dprintk0(sd->dev, "tvp5150: Interrupt enable register A = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_ENABLE_REG_A)); + dprintk0(sd->dev, "tvp5150: Interrupt configuration = 0x%02x\n", + tvp5150_read(sd, TVP5150_INT_CONF)); + dprintk0(sd->dev, "tvp5150: VDP status register = 0x%02x\n", + tvp5150_read(sd, TVP5150_VDP_STATUS_REG)); + dprintk0(sd->dev, "tvp5150: FIFO word count = 0x%02x\n", + tvp5150_read(sd, TVP5150_FIFO_WORD_COUNT)); + dprintk0(sd->dev, "tvp5150: FIFO interrupt threshold = 0x%02x\n", + tvp5150_read(sd, TVP5150_FIFO_INT_THRESHOLD)); + dprintk0(sd->dev, "tvp5150: FIFO reset = 0x%02x\n", + tvp5150_read(sd, TVP5150_FIFO_RESET)); + dprintk0(sd->dev, "tvp5150: Line number interrupt = 0x%02x\n", + tvp5150_read(sd, TVP5150_LINE_NUMBER_INT)); + dprintk0(sd->dev, "tvp5150: Pixel alignment register = 0x%02x%02x\n", + tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_HIGH), + tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_LOW)); + dprintk0(sd->dev, "tvp5150: FIFO output control = 0x%02x\n", + tvp5150_read(sd, TVP5150_FIFO_OUT_CTRL)); + dprintk0(sd->dev, "tvp5150: Full field enable = 0x%02x\n", + tvp5150_read(sd, TVP5150_FULL_FIELD_ENA)); + dprintk0(sd->dev, "tvp5150: Full field mode register = 0x%02x\n", + tvp5150_read(sd, TVP5150_FULL_FIELD_MODE_REG)); dump_reg_range(sd, "CC data", TVP5150_CC_DATA_INI, TVP5150_CC_DATA_END, 8); -- cgit v1.2.3 From e513411489202fc642c0d651479b9ccdff961ed0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Oct 2016 11:36:42 -0200 Subject: [media] tvp5150: get rid of KERN_CONT Unfortunately, KERN_CONT doesn't work with dev_foo(), producing weird messages like: tvp5150 6-005c: tvp5150: read 0xf6 = 0xff ff So, we need to get rid of it. As we're always printing read/write in hexa when dumping multiple register values, also remove the "0x" from the read/write debug messages too. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index d0dbdd7ea233..6737685d5be5 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -102,20 +102,22 @@ static int tvp5150_write(struct v4l2_subdev *sd, unsigned char addr, static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init, const u8 end, int max_line) { - int i = 0; + u8 buf[16]; + int i = 0, j, len; - while (init != (u8)(end + 1)) { - if ((i % max_line) == 0) { - if (i > 0) - printk("\n"); - printk("tvp5150: %s reg 0x%02x = ", s, init); - } - printk("%02x ", tvp5150_read(sd, init)); + if (max_line > 16) { + dprintk0(sd->dev, "too much data to dump\n"); + return; + } + + for (i = init; i < end; i += max_line) { + len = (end - i > max_line) ? max_line : end - i; + + for (j = 0; j < len; j++) + buf[j] = tvp5150_read(sd, i + j); - init++; - i++; + dprintk0(sd->dev, "%s reg %02x = %*ph\n", s, i, len, buf); } - printk("\n"); } static int tvp5150_log_status(struct v4l2_subdev *sd) -- cgit v1.2.3 From d3d96820d0deb86de3d8237b4026c9c15cb0e47f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Oct 2016 15:04:39 -0200 Subject: [media] rc-main: use pr_foo() macros Instead of calling printk() directly, use pr_foo() macro. That should make the rc_core messages be formatted with the right prefix. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 5087e76dfb03..adb10fac63e4 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -12,6 +12,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -66,7 +68,7 @@ struct rc_map *rc_map_get(const char *name) if (!map) { int rc = request_module("%s", name); if (rc < 0) { - printk(KERN_ERR "Couldn't load IR keymap %s\n", name); + pr_err("Couldn't load IR keymap %s\n", name); return NULL; } msleep(20); /* Give some time for IR to register */ @@ -75,7 +77,7 @@ struct rc_map *rc_map_get(const char *name) } #endif if (!map) { - printk(KERN_ERR "IR keymap %s not found\n", name); + pr_err("IR keymap %s not found\n", name); return NULL; } @@ -1620,7 +1622,7 @@ static int __init rc_core_init(void) { int rc = class_register(&rc_class); if (rc) { - printk(KERN_ERR "rc_core: unable to register rc class\n"); + pr_err("rc_core: unable to register rc class\n"); return rc; } -- cgit v1.2.3 From 6037b3ca28f4258d913dbe77248fd77827702ae3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2016 14:21:48 -0200 Subject: [media] tveeprom: print log messages using pr_foo() Unfortunately, the callers of tveeprom don't do the right thing to initialize the device. So, it produces log messages like: [ 267.533010] (null): Hauppauge model 42012, rev C186, serial# 2819348 [ 267.533012] (null): tuner model is Philips FQ1236 MK3 (idx 86, type 43) [ 267.533013] (null): TV standards NTSC(M) (eeprom 0x08) [ 267.533014] (null): audio processor is MSP3445 (idx 12) [ 267.533015] (null): has radio So, replace it to pr_foo(), as it should work fine. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tveeprom.c | 42 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c index e7d0d86f19aa..11976031aff8 100644 --- a/drivers/media/common/tveeprom.c +++ b/drivers/media/common/tveeprom.c @@ -28,6 +28,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -496,12 +498,12 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, len = eeprom_data[i] & 0x07; ++i; } else { - dev_warn(&c->dev, "Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", + pr_warn("Encountered bad packet header [%02x]. Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); return; } - dev_dbg(&c->dev, "Tag [%02x] + %d bytes: %*ph\n", + pr_debug("Tag [%02x] + %d bytes: %*ph\n", eeprom_data[i], len - 1, len, &eeprom_data[i]); /* process by tag */ @@ -642,14 +644,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, /* case 0x12: tag 'InfoBits' */ default: - dev_dbg(&c->dev, "Not sure what to do with tag [%02x]\n", + pr_debug("Not sure what to do with tag [%02x]\n", tag); /* dump the rest of the packet? */ } } if (!done) { - dev_warn(&c->dev, "Ran out of data!\n"); + pr_warn("Ran out of data!\n"); return; } @@ -662,8 +664,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, } if (hasRadioTuner(tuner1) && !tvee->has_radio) { - dev_info(&c->dev, "The eeprom says no radio is present, but the tuner type\n"); - dev_info(&c->dev, "indicates otherwise. I will assume that radio is present.\n"); + pr_info("The eeprom says no radio is present, but the tuner type\n"); + pr_info("indicates otherwise. I will assume that radio is present.\n"); tvee->has_radio = 1; } @@ -698,46 +700,46 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, } } - dev_info(&c->dev, "Hauppauge model %d, rev %s, serial# %u\n", + pr_info("Hauppauge model %d, rev %s, serial# %u\n", tvee->model, tvee->rev_str, tvee->serial_number); if (tvee->has_MAC_address == 1) - dev_info(&c->dev, "MAC address is %pM\n", tvee->MAC_address); - dev_info(&c->dev, "tuner model is %s (idx %d, type %d)\n", + pr_info("MAC address is %pM\n", tvee->MAC_address); + pr_info("tuner model is %s (idx %d, type %d)\n", t_name1, tuner1, tvee->tuner_type); - dev_info(&c->dev, "TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", + pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], t_format1); if (tuner2) - dev_info(&c->dev, "second tuner model is %s (idx %d, type %d)\n", + pr_info("second tuner model is %s (idx %d, type %d)\n", t_name2, tuner2, tvee->tuner2_type); if (t_format2) - dev_info(&c->dev, "TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", + pr_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], t_format2); if (audioic < 0) { - dev_info(&c->dev, "audio processor is unknown (no idx)\n"); + pr_info("audio processor is unknown (no idx)\n"); tvee->audio_processor = TVEEPROM_AUDPROC_OTHER; } else { if (audioic < ARRAY_SIZE(audio_ic)) - dev_info(&c->dev, "audio processor is %s (idx %d)\n", + pr_info("audio processor is %s (idx %d)\n", audio_ic[audioic].name, audioic); else - dev_info(&c->dev, "audio processor is unknown (idx %d)\n", + pr_info("audio processor is unknown (idx %d)\n", audioic); } if (tvee->decoder_processor) - dev_info(&c->dev, "decoder processor is %s (idx %d)\n", + pr_info("decoder processor is %s (idx %d)\n", STRM(decoderIC, tvee->decoder_processor), tvee->decoder_processor); if (tvee->has_ir) - dev_info(&c->dev, "has %sradio, has %sIR receiver, has %sIR transmitter\n", + pr_info("has %sradio, has %sIR receiver, has %sIR transmitter\n", tvee->has_radio ? "" : "no ", (tvee->has_ir & 2) ? "" : "no ", (tvee->has_ir & 4) ? "" : "no "); else - dev_info(&c->dev, "has %sradio\n", + pr_info("has %sradio\n", tvee->has_radio ? "" : "no "); } EXPORT_SYMBOL(tveeprom_hauppauge_analog); @@ -753,12 +755,12 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len) buf = 0; err = i2c_master_send(c, &buf, 1); if (err != 1) { - dev_info(&c->dev, "Huh, no eeprom present (err=%d)?\n", err); + pr_info("Huh, no eeprom present (err=%d)?\n", err); return -1; } err = i2c_master_recv(c, eedata, len); if (err != len) { - dev_warn(&c->dev, "i2c eeprom read error (err=%d)\n", err); + pr_warn("i2c eeprom read error (err=%d)\n", err); return -1; } -- cgit v1.2.3 From 0bebaa5f01bc018cd0246997d2b00f1ed44964a8 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 03:35:57 -0300 Subject: [media] RedRat3: Use kcalloc() in two functions * Multiplications for the size determination of memory allocations indicated that array data structures should be processed. Thus use the corresponding function "kcalloc". This issue was detected by using the Coccinelle software. * Replace the specification of data types by pointer dereferences to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 3b0ed1c3f2d8..67f35200b9eb 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -588,7 +588,7 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) int rc = 0; char *buffer; - buffer = kzalloc(sizeof(char) * (RR3_FW_VERSION_LEN + 1), GFP_KERNEL); + buffer = kcalloc(RR3_FW_VERSION_LEN + 1, sizeof(*buffer), GFP_KERNEL); if (!buffer) { dev_err(rr3->dev, "Memory allocation failure\n"); return; @@ -780,7 +780,9 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, /* rr3 will disable rc detector on transmit */ rr3->transmitting = true; - sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); + sample_lens = kcalloc(RR3_DRIVER_MAXLENS, + sizeof(*sample_lens), + GFP_KERNEL); if (!sample_lens) { ret = -ENOMEM; goto out; -- cgit v1.2.3 From 559f64d4de35c6ff5a89599bc209452e24b4fba4 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 08:20:19 -0300 Subject: [media] RedRat3: Delete six messages for a failed memory allocation The script "checkpatch.pl" pointed information out like the following. WARNING: Possible unnecessary 'out of memory' message Thus remove such a logging statement in five functions. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 67f35200b9eb..5e43766757fd 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -480,10 +480,8 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3) len = sizeof(*tmp); tmp = kzalloc(len, GFP_KERNEL); - if (!tmp) { - dev_warn(rr3->dev, "Memory allocation faillure\n"); + if (!tmp) return timeout; - } pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, @@ -544,10 +542,8 @@ static void redrat3_reset(struct redrat3_dev *rr3) txpipe = usb_sndctrlpipe(udev, 0); val = kmalloc(len, GFP_KERNEL); - if (!val) { - dev_err(dev, "Memory allocation failure\n"); + if (!val) return; - } *val = 0x01; rc = usb_control_msg(udev, rxpipe, RR3_RESET, @@ -589,10 +585,8 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) char *buffer; buffer = kcalloc(RR3_FW_VERSION_LEN + 1, sizeof(*buffer), GFP_KERNEL); - if (!buffer) { - dev_err(rr3->dev, "Memory allocation failure\n"); + if (!buffer) return; - } rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0), RR3_FW_VERSION, @@ -909,10 +903,8 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct); rc = rc_allocate_device(); - if (!rc) { - dev_err(dev, "remote input dev allocation failed\n"); + if (!rc) goto out; - } snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s Infrared Remote Transceiver (%04x:%04x)", prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "", @@ -1001,10 +993,8 @@ static int redrat3_dev_probe(struct usb_interface *intf, /* allocate memory for our device state and initialize it */ rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL); - if (rr3 == NULL) { - dev_err(dev, "Memory allocation failure\n"); + if (!rr3) goto no_endpoints; - } rr3->dev = &intf->dev; @@ -1016,10 +1006,8 @@ static int redrat3_dev_probe(struct usb_interface *intf, rr3->ep_in = ep_in; rr3->bulk_in_buf = usb_alloc_coherent(udev, le16_to_cpu(ep_in->wMaxPacketSize), GFP_KERNEL, &rr3->dma_in); - if (!rr3->bulk_in_buf) { - dev_err(dev, "Read buffer allocation failure\n"); + if (!rr3->bulk_in_buf) goto error; - } pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, -- cgit v1.2.3 From 576df632f24f7db40b7266cada96ed1b76f1255d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 08:23:22 -0300 Subject: [media] RedRat3: Improve another size determination in redrat3_reset() Replace the specification of a data type by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 5e43766757fd..342a85d02887 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -536,7 +536,7 @@ static void redrat3_reset(struct redrat3_dev *rr3) struct device *dev = rr3->dev; int rc, rxpipe, txpipe; u8 *val; - int len = sizeof(u8); + size_t const len = sizeof(*val); rxpipe = usb_rcvctrlpipe(udev, 0); txpipe = usb_sndctrlpipe(udev, 0); -- cgit v1.2.3 From fac59136bc22fd9b3a04ed4f29977da8e045ee6b Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 05:34:29 -0300 Subject: [media] RedRat3: Return directly after a failed kcalloc() in redrat3_transmit_ir() * Return directly after a call of the function "kcalloc" failed at the beginning. * Reorder two calls for the function "kfree" at the end. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 342a85d02887..966f43a7e2c2 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -777,10 +777,8 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, sample_lens = kcalloc(RR3_DRIVER_MAXLENS, sizeof(*sample_lens), GFP_KERNEL); - if (!sample_lens) { - ret = -ENOMEM; - goto out; - } + if (!sample_lens) + return -ENOMEM; irdata = kzalloc(sizeof(*irdata), GFP_KERNEL); if (!irdata) { @@ -848,8 +846,8 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, ret = count; out: - kfree(sample_lens); kfree(irdata); + kfree(sample_lens); rr3->transmitting = false; /* rr3 re-enables rc detector because it was enabled before */ -- cgit v1.2.3 From 7aa20afea649fa1e3cb81bf40c25ddf53cc1328f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 08:21:55 -0300 Subject: [media] RedRat3: Delete an unnecessary variable initialisation in redrat3_get_firmware_rev() The local variable "rc" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 966f43a7e2c2..dc8b88a256f2 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -581,7 +581,7 @@ static void redrat3_reset(struct redrat3_dev *rr3) static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) { - int rc = 0; + int rc; char *buffer; buffer = kcalloc(RR3_FW_VERSION_LEN + 1, sizeof(*buffer), GFP_KERNEL); -- cgit v1.2.3 From 9d45d5fbeb4672648926c8fd2c1f2c08105ee7c3 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 09:17:43 -0300 Subject: [media] RedRat3: Delete an unnecessary variable initialisation in redrat3_init_rc_dev() The local variable "ret" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index dc8b88a256f2..689df034dcfe 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -897,7 +897,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) { struct device *dev = rr3->dev; struct rc_dev *rc; - int ret = -ENODEV; + int ret; u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct); rc = rc_allocate_device(); -- cgit v1.2.3 From 3f81678d8e4918788b17ab007f41b86aea030bdc Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Oct 2016 09:54:46 -0300 Subject: [media] RedRat3: Return directly after a failed rc_allocate_device() in redrat3_init_rc_dev() Return directly after a call of the function "rc_allocate_device" failed at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 689df034dcfe..d3c81619cd87 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -902,7 +902,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) rc = rc_allocate_device(); if (!rc) - goto out; + return NULL; snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s Infrared Remote Transceiver (%04x:%04x)", prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "", -- cgit v1.2.3 From ce3aeaf22c9f6d9dbbad00600b26ddd0263f8cbc Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 14 Oct 2016 02:19:00 -0300 Subject: [media] winbond-cir: Use kmalloc_array() in wbcir_tx() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kmalloc_array". This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/winbond-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index cdcd6e38b295..8c1f9225d358 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -658,7 +658,7 @@ wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count) unsigned i; unsigned long flags; - buf = kmalloc(count * sizeof(*b), GFP_KERNEL); + buf = kmalloc_array(count, sizeof(*b), GFP_KERNEL); if (!buf) return -ENOMEM; -- cgit v1.2.3 From bb16d21cfa874a879b0ae40b8acc1c12f41e6850 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 19 Oct 2016 12:28:45 -0200 Subject: [media] doc-rst: v4l: Add documentation on CSI-2 bus configuration Document the interface between the CSI-2 transmitter and receiver drivers. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/csi2.rst | 61 ++++++++++++++++++++++++++++++++++++++ Documentation/media/media_kapi.rst | 1 + 2 files changed, 62 insertions(+) create mode 100644 Documentation/media/kapi/csi2.rst diff --git a/Documentation/media/kapi/csi2.rst b/Documentation/media/kapi/csi2.rst new file mode 100644 index 000000000000..2004db00b12b --- /dev/null +++ b/Documentation/media/kapi/csi2.rst @@ -0,0 +1,61 @@ +MIPI CSI-2 +========== + +CSI-2 is a data bus intended for transferring images from cameras to +the host SoC. It is defined by the `MIPI alliance`_. + +.. _`MIPI alliance`: http://www.mipi.org/ + +Transmitter drivers +------------------- + +CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to +provide the CSI-2 receiver with information on the CSI-2 bus +configuration. These include the V4L2_CID_LINK_FREQ and +V4L2_CID_PIXEL_RATE controls and +(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These +interface elements must be present on the sub-device represents the +CSI-2 transmitter. + +The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the +frequency (and not the symbol rate) of the link. The +V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel +rate the transmitter uses. The +:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an +ability to start and stop the stream. + +The value of the V4L2_CID_PIXEL_RATE is calculated as follows:: + + pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample + +where + +.. list-table:: variables in pixel rate calculation + :header-rows: 1 + + * - variable or constant + - description + * - link_freq + - The value of the V4L2_CID_LINK_FREQ integer64 menu item. + * - nr_of_lanes + - Number of data lanes used on the CSI-2 link. This can + be obtained from the OF endpoint configuration. + * - 2 + - Two bits are transferred per clock cycle per lane. + * - bits_per_sample + - Number of bits per sample. + +The transmitter drivers must configure the CSI-2 transmitter to *LP-11 +mode* whenever the transmitter is powered on but not active. Some +transmitters do this automatically but some have to be explicitly +programmed to do so. + +Receiver drivers +---------------- + +Before the receiver driver may enable the CSI-2 transmitter by using +the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered +the transmitter up by using the +:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take +place either indirectly by using :c:func:`v4l2_pipeline_pm_use` or +directly. diff --git a/Documentation/media/media_kapi.rst b/Documentation/media/media_kapi.rst index f282ca270369..bc0638956a43 100644 --- a/Documentation/media/media_kapi.rst +++ b/Documentation/media/media_kapi.rst @@ -33,3 +33,4 @@ For more details see the file COPYING in the source distribution of Linux. kapi/rc-core kapi/mc-core kapi/cec-core + kapi/csi2 -- cgit v1.2.3 From 24dc974d1c1d745e38aff94ce37ee3dd3f4febce Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Abbadie Date: Wed, 19 Oct 2016 18:47:12 -0200 Subject: [media] Staging: media: radio-bcm2048: Fix symbolic permissions This replaces the S_* style permissions by numbers for the __ATTR macros Signed-off-by: Jean-Baptiste Abbadie Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 4d9bd02ede47..9fc2c13ce0ff 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2059,67 +2059,67 @@ property_signed_read(fm_rssi, int, "%d") DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0) static struct device_attribute attrs[] = { - __ATTR(power_state, S_IRUGO | S_IWUSR, bcm2048_power_state_read, + __ATTR(power_state, 0644, bcm2048_power_state_read, bcm2048_power_state_write), - __ATTR(mute, S_IRUGO | S_IWUSR, bcm2048_mute_read, + __ATTR(mute, 0644, bcm2048_mute_read, bcm2048_mute_write), - __ATTR(audio_route, S_IRUGO | S_IWUSR, bcm2048_audio_route_read, + __ATTR(audio_route, 0644, bcm2048_audio_route_read, bcm2048_audio_route_write), - __ATTR(dac_output, S_IRUGO | S_IWUSR, bcm2048_dac_output_read, + __ATTR(dac_output, 0644, bcm2048_dac_output_read, bcm2048_dac_output_write), - __ATTR(fm_hi_lo_injection, S_IRUGO | S_IWUSR, + __ATTR(fm_hi_lo_injection, 0644, bcm2048_fm_hi_lo_injection_read, bcm2048_fm_hi_lo_injection_write), - __ATTR(fm_frequency, S_IRUGO | S_IWUSR, bcm2048_fm_frequency_read, + __ATTR(fm_frequency, 0644, bcm2048_fm_frequency_read, bcm2048_fm_frequency_write), - __ATTR(fm_af_frequency, S_IRUGO | S_IWUSR, + __ATTR(fm_af_frequency, 0644, bcm2048_fm_af_frequency_read, bcm2048_fm_af_frequency_write), - __ATTR(fm_deemphasis, S_IRUGO | S_IWUSR, bcm2048_fm_deemphasis_read, + __ATTR(fm_deemphasis, 0644, bcm2048_fm_deemphasis_read, bcm2048_fm_deemphasis_write), - __ATTR(fm_rds_mask, S_IRUGO | S_IWUSR, bcm2048_fm_rds_mask_read, + __ATTR(fm_rds_mask, 0644, bcm2048_fm_rds_mask_read, bcm2048_fm_rds_mask_write), - __ATTR(fm_best_tune_mode, S_IRUGO | S_IWUSR, + __ATTR(fm_best_tune_mode, 0644, bcm2048_fm_best_tune_mode_read, bcm2048_fm_best_tune_mode_write), - __ATTR(fm_search_rssi_threshold, S_IRUGO | S_IWUSR, + __ATTR(fm_search_rssi_threshold, 0644, bcm2048_fm_search_rssi_threshold_read, bcm2048_fm_search_rssi_threshold_write), - __ATTR(fm_search_mode_direction, S_IRUGO | S_IWUSR, + __ATTR(fm_search_mode_direction, 0644, bcm2048_fm_search_mode_direction_read, bcm2048_fm_search_mode_direction_write), - __ATTR(fm_search_tune_mode, S_IRUGO | S_IWUSR, + __ATTR(fm_search_tune_mode, 0644, bcm2048_fm_search_tune_mode_read, bcm2048_fm_search_tune_mode_write), - __ATTR(rds, S_IRUGO | S_IWUSR, bcm2048_rds_read, + __ATTR(rds, 0644, bcm2048_rds_read, bcm2048_rds_write), - __ATTR(rds_b_block_mask, S_IRUGO | S_IWUSR, + __ATTR(rds_b_block_mask, 0644, bcm2048_rds_b_block_mask_read, bcm2048_rds_b_block_mask_write), - __ATTR(rds_b_block_match, S_IRUGO | S_IWUSR, + __ATTR(rds_b_block_match, 0644, bcm2048_rds_b_block_match_read, bcm2048_rds_b_block_match_write), - __ATTR(rds_pi_mask, S_IRUGO | S_IWUSR, bcm2048_rds_pi_mask_read, + __ATTR(rds_pi_mask, 0644, bcm2048_rds_pi_mask_read, bcm2048_rds_pi_mask_write), - __ATTR(rds_pi_match, S_IRUGO | S_IWUSR, bcm2048_rds_pi_match_read, + __ATTR(rds_pi_match, 0644, bcm2048_rds_pi_match_read, bcm2048_rds_pi_match_write), - __ATTR(rds_wline, S_IRUGO | S_IWUSR, bcm2048_rds_wline_read, + __ATTR(rds_wline, 0644, bcm2048_rds_wline_read, bcm2048_rds_wline_write), - __ATTR(rds_pi, S_IRUGO, bcm2048_rds_pi_read, NULL), - __ATTR(rds_rt, S_IRUGO, bcm2048_rds_rt_read, NULL), - __ATTR(rds_ps, S_IRUGO, bcm2048_rds_ps_read, NULL), - __ATTR(fm_rds_flags, S_IRUGO, bcm2048_fm_rds_flags_read, NULL), - __ATTR(region_bottom_frequency, S_IRUGO, + __ATTR(rds_pi, 0444, bcm2048_rds_pi_read, NULL), + __ATTR(rds_rt, 0444, bcm2048_rds_rt_read, NULL), + __ATTR(rds_ps, 0444, bcm2048_rds_ps_read, NULL), + __ATTR(fm_rds_flags, 0444, bcm2048_fm_rds_flags_read, NULL), + __ATTR(region_bottom_frequency, 0444, bcm2048_region_bottom_frequency_read, NULL), - __ATTR(region_top_frequency, S_IRUGO, + __ATTR(region_top_frequency, 0444, bcm2048_region_top_frequency_read, NULL), - __ATTR(fm_carrier_error, S_IRUGO, + __ATTR(fm_carrier_error, 0444, bcm2048_fm_carrier_error_read, NULL), - __ATTR(fm_rssi, S_IRUGO, + __ATTR(fm_rssi, 0444, bcm2048_fm_rssi_read, NULL), - __ATTR(region, S_IRUGO | S_IWUSR, bcm2048_region_read, + __ATTR(region, 0644, bcm2048_region_read, bcm2048_region_write), - __ATTR(rds_data, S_IRUGO, bcm2048_rds_data_read, NULL), + __ATTR(rds_data, 0444, bcm2048_rds_data_read, NULL), }; static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev, -- cgit v1.2.3 From 3194e858c5b84008ead92c0c6ee80f94e1c0606d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Abbadie Date: Wed, 19 Oct 2016 18:47:13 -0200 Subject: [media] Staging: media: radio-bcm2048: Fix indentation Align multiple lines statement with parentheses Signed-off-by: Jean-Baptiste Abbadie Acked-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 9fc2c13ce0ff..e35ceceb6c7b 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -999,7 +999,7 @@ static int bcm2048_set_fm_search_tune_mode(struct bcm2048_device *bdev, timeout = BCM2048_AUTO_SEARCH_TIMEOUT; if (!wait_for_completion_timeout(&bdev->compl, - msecs_to_jiffies(timeout))) + msecs_to_jiffies(timeout))) dev_err(&bdev->client->dev, "IRQ timeout.\n"); if (value) @@ -2204,7 +2204,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, } /* interruptible_sleep_on(&bdev->read_queue); */ if (wait_event_interruptible(bdev->read_queue, - bdev->rds_data_available) < 0) { + bdev->rds_data_available) < 0) { retval = -EINTR; goto done; } -- cgit v1.2.3 From 8be135d052dd88870e1db177a53ac75a4ced04a5 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Abbadie Date: Wed, 19 Oct 2016 18:47:14 -0200 Subject: [media] Staging: media: radio-bcm2048: Remove FSF address from GPL notice Removes the superfluous statement about writing to the FSF in the GPL notice Signed-off-by: Jean-Baptiste Abbadie Acked-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index e35ceceb6c7b..0a9f8589ecfb 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -17,10 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA */ /* -- cgit v1.2.3 From bfc303e7bef819acf2f83a1805d7dc15b5c8eebf Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Fri, 21 Oct 2016 06:55:32 -0200 Subject: [media] c8sectpfe: Remove clk_disable_unprepare hacks Now that CLK_PROC_STFE is defined as a critical clock in DT, we can remove the commented clk_disable_unprepare from the c8sectpfe driver. This means we now have balanced clk*enable/disable calls in the driver, but on STiH407 family the clock in reality will never actually be disabled. This is due to a HW bug where once the IP has been configured and the SLIM core is running, disabling the clock causes a unrecoverable bus lockup. Signed-off-by: Peter Griffin Acked-by: Patrice Chotard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 42b123ff2953..22fd8b91809a 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -885,8 +885,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) return 0; err_clk_disable: - /* TODO uncomment when upstream has taken a reference on this clk */ - /*clk_disable_unprepare(fei->c8sectpfeclk);*/ + clk_disable_unprepare(fei->c8sectpfeclk); return ret; } @@ -921,11 +920,8 @@ static int c8sectpfe_remove(struct platform_device *pdev) if (readl(fei->io + SYS_OTHER_CLKEN)) writel(0, fei->io + SYS_OTHER_CLKEN); - /* TODO uncomment when upstream has taken a reference on this clk */ - /* if (fei->c8sectpfeclk) clk_disable_unprepare(fei->c8sectpfeclk); - */ return 0; } -- cgit v1.2.3 From 5fa88151ecdbfc9f2092cf1add7966c546b95dfa Mon Sep 17 00:00:00 2001 From: CrazyCat Date: Fri, 21 Oct 2016 17:35:40 -0200 Subject: [media] dvb-usb-cxusb: Geniatech T230 - resync TS FIFO after lock This patch fix streaming issue for Geniatech T230/PT360. Signed-off-by: CrazyCat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cxusb.c | 26 ++++++++++++++++++++++++++ drivers/media/usb/dvb-usb/cxusb.h | 5 +++++ 2 files changed, 31 insertions(+) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 243403081fa5..9b8771eb31d4 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -369,6 +369,26 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return 0; } +static int cxusb_read_status(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv; + struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv; + int ret; + + ret = state->fe_read_status(fe, status); + + /* it need resync slave fifo when signal change from unlock to lock.*/ + if ((*status & FE_HAS_LOCK) && (!state->last_lock)) { + mutex_lock(&state->stream_mutex); + cxusb_streaming_ctrl(adap, 1); + mutex_unlock(&state->stream_mutex); + } + + state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; + return ret; +} + static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) { int ep = d->props.generic_bulk_ctrl_endpoint; @@ -1372,6 +1392,12 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) st->i2c_client_tuner = client_tuner; + /* hook fe: need to resync the slave fifo when signal locks. */ + mutex_init(&st->stream_mutex); + st->last_lock = 0; + st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; + return 0; } diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h index 18acda19527a..66429d7f69b5 100644 --- a/drivers/media/usb/dvb-usb/cxusb.h +++ b/drivers/media/usb/dvb-usb/cxusb.h @@ -37,6 +37,11 @@ struct cxusb_state { struct i2c_client *i2c_client_tuner; unsigned char data[MAX_XFER_SIZE]; + + struct mutex stream_mutex; + u8 last_lock; + int (*fe_read_status)(struct dvb_frontend *fe, + enum fe_status *status); }; #endif -- cgit v1.2.3 From 5a91206ff0d0548939f3e85a65fb76b400fb0e89 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 2 Jul 2016 20:27:46 -0300 Subject: [media] saa7134: fix warm Medion 7134 EEPROM read When saa7134 module driving a Medion 7134 card is reloaded reads of this card EEPROM (required for automatic detection of tuner model) will be corrupted due to I2C gate in DVB-T demod being left closed. This sometimes also happens on first saa7134 module load after a warm reboot. Fix this by opening this I2C gate before doing EEPROM read during i2c initialization. Signed-off-by: Maciej S. Szmigiero Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-i2c.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index 2dac48fa1386..dca0592c5f47 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -355,12 +355,43 @@ static struct i2c_client saa7134_client_template = { /* ----------------------------------------------------------- */ +/* On Medion 7134 reading EEPROM needs DVB-T demod i2c gate open */ +static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev) +{ + u8 subaddr = 0x7, dmdregval; + u8 data[2]; + int ret; + struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0, + .buf = &subaddr, .len = 1}, + {.addr = 0x08, + .flags = I2C_M_RD, + .buf = &dmdregval, .len = 1} + }; + struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0, + .buf = data, .len = 2} }; + + ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2); + if ((ret == 2) && (dmdregval & 0x2)) { + pr_debug("%s: DVB-T demod i2c gate was left closed\n", + dev->name); + + data[0] = subaddr; + data[1] = (dmdregval & ~0x2); + if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1) + pr_err("%s: EEPROM i2c gate open failure\n", + dev->name); + } +} + static int saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) { unsigned char buf; int i,err; + if (dev->board == SAA7134_BOARD_MD7134) + saa7134_i2c_eeprom_md7134_gate(dev); + dev->i2c_client.addr = 0xa0 >> 1; buf = 0; if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) { -- cgit v1.2.3 From 5911f629266d577c7697dd3e9797b2d1e947a40b Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Wed, 6 Jul 2016 06:01:22 -0300 Subject: [media] lirc_dev: remove compat_ioctl assignment There is no need to check for CONFIG_COMPAT and consequently assign the compat_ioctl. Signed-off-by: Andi Shyti Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 91f9bb87ce68..809a8671e3d6 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -150,9 +150,6 @@ static const struct file_operations lirc_dev_fops = { .write = lirc_dev_fop_write, .poll = lirc_dev_fop_poll, .unlocked_ioctl = lirc_dev_fop_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = lirc_dev_fop_ioctl, -#endif .open = lirc_dev_fop_open, .release = lirc_dev_fop_close, .llseek = noop_llseek, -- cgit v1.2.3 From c9205e18b41a6ef5ad73e1c4b86a78b2ea3ccb9b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jul 2016 07:18:14 -0300 Subject: [media] blackfin: check devm_pinctrl_get() for errors devm_pinctrl_get() can fail so we should check for that. Fixes: 0a6824bc10de ('[media] v4l2: blackfin: select proper pinctrl state in ppi_set_params if CONFIG_PINCTRL is enabled') Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/ppi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c index cff63e511e6d..b8f3d9fa66e9 100644 --- a/drivers/media/platform/blackfin/ppi.c +++ b/drivers/media/platform/blackfin/ppi.c @@ -214,6 +214,8 @@ static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params) if (params->dlen > 24 || params->dlen <= 0) return -EINVAL; pctrl = devm_pinctrl_get(ppi->dev); + if (IS_ERR(pctrl)) + return PTR_ERR(pctrl); pstate = pinctrl_lookup_state(pctrl, pin_state[(params->dlen + 7) / 8 - 1]); if (pinctrl_select_state(pctrl, pstate)) -- cgit v1.2.3 From b68002db13f57b16b6b9f9841d40b867c298ffe4 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 15 Jul 2016 06:33:06 -0300 Subject: [media] media: platform: ti-vpe: call of_node_put on non-null pointer It should call of_node_put on non-null poiner. Cc: Mauro Carvalho Chehab Signed-off-by: Peter Chen Acked-by: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/cal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index b2d166b2221a..7a058b6e03d0 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1745,13 +1745,13 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) } cleanup_exit: - if (!remote_ep) + if (remote_ep) of_node_put(remote_ep); - if (!sensor_node) + if (sensor_node) of_node_put(sensor_node); - if (!ep_node) + if (ep_node) of_node_put(ep_node); - if (!port) + if (port) of_node_put(port); return ret; -- cgit v1.2.3 From c183d3584b1777be55b4c576385143210dc0dbd5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:06 -0300 Subject: [media] rc-main: clear rc_map.name in ir_free_table() rc_unregister_device() will first call ir_free_table(), and later device_del(); however, the latter causes a call to rc_dev_uevent(), which prints rc_map.name, which at this point has already bee freed. This fixes a use-after-free bug found with KASAN. As reported by Shuah: "I am seeing the following when I do rmmod on au0828 BUG: KASAN: use-after-free in string+0x170/0x1f0 at addr ffff8801bd513000 Read of size 1 by task rmmod/1831 CPU: 1 PID: 1831 Comm: rmmod Tainted: G W 4.9.0-rc5 #5 Hardware name: Hewlett-Packard HP ProBook 6475b/180F, BIOS 68TTU Ver. F.04 08/03/2012 ffff8801aea2f680 ffffffff81b37ad3 ffff8801fa403b80 ffff8801bd513000 ffff8801aea2f6a8 ffffffff8156c301 ffff8801aea2f738 ffff8801bd513000 ffff8801fa403b80 ffff8801aea2f728 ffffffff8156c59a ffff8801aea2f770 Call Trace: dump_stack+0x67/0x94 [] kasan_object_err+0x21/0x70 [] kasan_report_error+0x1fa/0x4d0 [] ? au0828_exit+0x10/0x21 [au0828] [] __asan_report_load1_noabort+0x43/0x50 [] ? string+0x170/0x1f0 [] string+0x170/0x1f0 [] vsnprintf+0x374/0x1c50 [] ? pointer+0xa80/0xa80 [] ? save_stack+0x46/0xd0 [] ? __kmalloc+0x14a/0x2a0 [] ? kobject_get_path+0x9a/0x200 [] ? kobject_uevent_env+0x282/0xca0 [] ? kobject_uevent+0xb/0x10 [] ? device_del+0x434/0x6d0 [] ? rc_unregister_device+0x177/0x240 [rc_core] [] ? au0828_rc_unregister+0x60/0xb0 [au0828] The problem is fixed with this patch on Linux 4.9-rc4" Signed-off-by: Max Kellermann Tested-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index adb10fac63e4..dedaf38c5ff6 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -161,6 +161,7 @@ static void ir_free_table(struct rc_map *rc_map) { rc_map->size = 0; kfree(rc_map->name); + rc_map->name = NULL; kfree(rc_map->scan); rc_map->scan = NULL; } -- cgit v1.2.3 From bd336e63441bcdeeccca6a698087d913a32478c5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:21 -0300 Subject: [media] dvb: make DVB frontend *_ops instances "const" These are immutable. Making them "const" allows the compiler to move them to the "rodata" section. Note that cxd2841er_t_c_ops cannot be made "const", because cxd2841er_attach() modifies it. Ouch! [mchehab@s-opensource.com: fix merge conflicts] Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 2 +- drivers/media/dvb-frontends/af9013.c | 4 ++-- drivers/media/dvb-frontends/af9033.c | 2 +- drivers/media/dvb-frontends/as102_fe.c | 2 +- drivers/media/dvb-frontends/atbm8830.c | 2 +- drivers/media/dvb-frontends/au8522_dig.c | 4 ++-- drivers/media/dvb-frontends/bcm3510.c | 4 ++-- drivers/media/dvb-frontends/cx22700.c | 4 ++-- drivers/media/dvb-frontends/cx24110.c | 4 ++-- drivers/media/dvb-frontends/cx24116.c | 4 ++-- drivers/media/dvb-frontends/cx24117.c | 4 ++-- drivers/media/dvb-frontends/cx24120.c | 4 ++-- drivers/media/dvb-frontends/cx24123.c | 4 ++-- drivers/media/dvb-frontends/cxd2841er.c | 6 +++--- drivers/media/dvb-frontends/dib3000mb.c | 4 ++-- drivers/media/dvb-frontends/dib3000mc.c | 4 ++-- drivers/media/dvb-frontends/dib7000m.c | 4 ++-- drivers/media/dvb-frontends/dib7000p.c | 4 ++-- drivers/media/dvb-frontends/dib9000.c | 4 ++-- drivers/media/dvb-frontends/drx39xyj/drxj.c | 4 ++-- drivers/media/dvb-frontends/drxd_hard.c | 2 +- drivers/media/dvb-frontends/drxk_hard.c | 2 +- drivers/media/dvb-frontends/ds3000.c | 4 ++-- drivers/media/dvb-frontends/dvb_dummy_fe.c | 12 ++++++------ drivers/media/dvb-frontends/ec100.c | 4 ++-- drivers/media/dvb-frontends/gp8psk-fe.c | 4 ++-- drivers/media/dvb-frontends/hd29l2.c | 4 ++-- drivers/media/dvb-frontends/l64781.c | 4 ++-- drivers/media/dvb-frontends/lg2160.c | 4 ++-- drivers/media/dvb-frontends/lgdt3305.c | 8 ++++---- drivers/media/dvb-frontends/lgdt3306a.c | 4 ++-- drivers/media/dvb-frontends/lgdt330x.c | 8 ++++---- drivers/media/dvb-frontends/lgs8gl5.c | 4 ++-- drivers/media/dvb-frontends/lgs8gxx.c | 2 +- drivers/media/dvb-frontends/m88ds3103.c | 4 ++-- drivers/media/dvb-frontends/m88rs2000.c | 2 +- drivers/media/dvb-frontends/mb86a16.c | 2 +- drivers/media/dvb-frontends/mb86a20s.c | 4 ++-- drivers/media/dvb-frontends/mn88472.c | 2 +- drivers/media/dvb-frontends/mt312.c | 2 +- drivers/media/dvb-frontends/mt352.c | 4 ++-- drivers/media/dvb-frontends/nxt200x.c | 4 ++-- drivers/media/dvb-frontends/nxt6000.c | 4 ++-- drivers/media/dvb-frontends/or51132.c | 4 ++-- drivers/media/dvb-frontends/or51211.c | 4 ++-- drivers/media/dvb-frontends/rtl2830.c | 2 +- drivers/media/dvb-frontends/rtl2832.c | 2 +- drivers/media/dvb-frontends/s5h1409.c | 4 ++-- drivers/media/dvb-frontends/s5h1411.c | 4 ++-- drivers/media/dvb-frontends/s5h1420.c | 4 ++-- drivers/media/dvb-frontends/s5h1432.c | 4 ++-- drivers/media/dvb-frontends/s921.c | 4 ++-- drivers/media/dvb-frontends/si2165.c | 2 +- drivers/media/dvb-frontends/si21xx.c | 2 +- drivers/media/dvb-frontends/sp8870.c | 4 ++-- drivers/media/dvb-frontends/sp887x.c | 4 ++-- drivers/media/dvb-frontends/stb0899_drv.c | 2 +- drivers/media/dvb-frontends/stv0288.c | 2 +- drivers/media/dvb-frontends/stv0297.c | 4 ++-- drivers/media/dvb-frontends/stv0299.c | 4 ++-- drivers/media/dvb-frontends/stv0367.c | 4 ++-- drivers/media/dvb-frontends/stv0900_core.c | 2 +- drivers/media/dvb-frontends/stv090x.c | 2 +- drivers/media/dvb-frontends/tda10021.c | 4 ++-- drivers/media/dvb-frontends/tda10023.c | 4 ++-- drivers/media/dvb-frontends/tda10048.c | 4 ++-- drivers/media/dvb-frontends/tda1004x.c | 4 ++-- drivers/media/dvb-frontends/tda10071.c | 4 ++-- drivers/media/dvb-frontends/tda10086.c | 2 +- drivers/media/dvb-frontends/tda8083.c | 4 ++-- drivers/media/dvb-frontends/ves1820.c | 4 ++-- drivers/media/dvb-frontends/ves1x93.c | 4 ++-- drivers/media/dvb-frontends/zl10353.c | 4 ++-- drivers/media/pci/bt8xx/dst.c | 16 ++++++++-------- drivers/media/pci/pt1/va1j5jf8007s.c | 2 +- drivers/media/pci/pt1/va1j5jf8007t.c | 2 +- drivers/media/tuners/tda8290.c | 4 ++-- drivers/media/tuners/tda9887.c | 2 +- drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c | 2 +- drivers/media/usb/dvb-usb/af9005-fe.c | 4 ++-- drivers/media/usb/dvb-usb/cinergyT2-fe.c | 4 ++-- drivers/media/usb/dvb-usb/dtt200u-fe.c | 4 ++-- drivers/media/usb/dvb-usb/friio-fe.c | 4 ++-- drivers/media/usb/dvb-usb/vp702x-fe.c | 4 ++-- drivers/media/usb/dvb-usb/vp7045-fe.c | 4 ++-- drivers/media/usb/ttusb-dec/ttusbdecfe.c | 8 ++++---- 86 files changed, 165 insertions(+), 165 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 9148e14c9d07..affde1426b7a 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1044,7 +1044,7 @@ static void smsdvb_release(struct dvb_frontend *fe) /* do nothing */ } -static struct dvb_frontend_ops smsdvb_fe_ops = { +static const struct dvb_frontend_ops smsdvb_fe_ops = { .info = { .name = "Siano Mobile Digital MDTV Receiver", .frequency_min = 44250000, diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 8bcde336ffd7..c6cb3bbc912a 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -1351,7 +1351,7 @@ static void af9013_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops af9013_ops; +static const struct dvb_frontend_ops af9013_ops; static int af9013_download_firmware(struct af9013_state *state) { @@ -1516,7 +1516,7 @@ err: } EXPORT_SYMBOL(af9013_attach); -static struct dvb_frontend_ops af9013_ops = { +static const struct dvb_frontend_ops af9013_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Afatech AF9013", diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 9a8157a5f49d..f8818028752e 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -1198,7 +1198,7 @@ err: return ret; } -static struct dvb_frontend_ops af9033_ops = { +static const struct dvb_frontend_ops af9033_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Afatech AF9033 (DVB-T)", diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c index 9412fcd1bddb..98d575f2744c 100644 --- a/drivers/media/dvb-frontends/as102_fe.c +++ b/drivers/media/dvb-frontends/as102_fe.c @@ -415,7 +415,7 @@ static void as102_fe_release(struct dvb_frontend *fe) } -static struct dvb_frontend_ops as102_fe_ops = { +static const struct dvb_frontend_ops as102_fe_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Abilis AS102 DVB-T", diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c index 47248b868e38..07ce05578278 100644 --- a/drivers/media/dvb-frontends/atbm8830.c +++ b/drivers/media/dvb-frontends/atbm8830.c @@ -428,7 +428,7 @@ static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0); } -static struct dvb_frontend_ops atbm8830_ops = { +static const struct dvb_frontend_ops atbm8830_ops = { .delsys = { SYS_DTMB }, .info = { .name = "AltoBeam ATBM8830/8831 DMB-TH", diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index e676b9461a59..7ed326e43fc4 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -834,7 +834,7 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, return 0; } -static struct dvb_frontend_ops au8522_ops; +static const struct dvb_frontend_ops au8522_ops; static void au8522_release(struct dvb_frontend *fe) @@ -894,7 +894,7 @@ error: } EXPORT_SYMBOL(au8522_attach); -static struct dvb_frontend_ops au8522_ops = { +static const struct dvb_frontend_ops au8522_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Auvitek AU8522 QAM/8VSB Frontend", diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c index bb698839e477..617c5e29f919 100644 --- a/drivers/media/dvb-frontends/bcm3510.c +++ b/drivers/media/dvb-frontends/bcm3510.c @@ -788,7 +788,7 @@ static int bcm3510_init(struct dvb_frontend* fe) } -static struct dvb_frontend_ops bcm3510_ops; +static const struct dvb_frontend_ops bcm3510_ops; struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, struct i2c_adapter *i2c) @@ -834,7 +834,7 @@ error: } EXPORT_SYMBOL(bcm3510_attach); -static struct dvb_frontend_ops bcm3510_ops = { +static const struct dvb_frontend_ops bcm3510_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Broadcom BCM3510 VSB/QAM frontend", diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c index 5cad925609e0..2b629e23ceeb 100644 --- a/drivers/media/dvb-frontends/cx22700.c +++ b/drivers/media/dvb-frontends/cx22700.c @@ -380,7 +380,7 @@ static void cx22700_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops cx22700_ops; +static const struct dvb_frontend_ops cx22700_ops; struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, struct i2c_adapter* i2c) @@ -408,7 +408,7 @@ error: return NULL; } -static struct dvb_frontend_ops cx22700_ops = { +static const struct dvb_frontend_ops cx22700_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Conexant CX22700 DVB-T", diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 92a08c7bf794..cf1bc99d1f32 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c @@ -592,7 +592,7 @@ static void cx24110_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops cx24110_ops; +static const struct dvb_frontend_ops cx24110_ops; struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, struct i2c_adapter* i2c) @@ -625,7 +625,7 @@ error: return NULL; } -static struct dvb_frontend_ops cx24110_ops = { +static const struct dvb_frontend_ops cx24110_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Conexant CX24110 DVB-S", diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index ae5a7f9f5a72..e105532bfba8 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -1116,7 +1116,7 @@ static void cx24116_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops cx24116_ops; +static const struct dvb_frontend_ops cx24116_ops; struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, struct i2c_adapter *i2c) @@ -1467,7 +1467,7 @@ static int cx24116_get_algo(struct dvb_frontend *fe) return DVBFE_ALGO_HW; } -static struct dvb_frontend_ops cx24116_ops = { +static const struct dvb_frontend_ops cx24116_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Conexant CX24116/CX24118", diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index bc3cd698303f..d37cb7762bd6 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c @@ -1164,7 +1164,7 @@ static void cx24117_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops cx24117_ops; +static const struct dvb_frontend_ops cx24117_ops; struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, struct i2c_adapter *i2c) @@ -1618,7 +1618,7 @@ static int cx24117_get_frontend(struct dvb_frontend *fe, return 0; } -static struct dvb_frontend_ops cx24117_ops = { +static const struct dvb_frontend_ops cx24117_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Conexant CX24117/CX24132", diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 3112a3206d46..7f11dcc94d85 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -267,7 +267,7 @@ out: return ret; } -static struct dvb_frontend_ops cx24120_ops; +static const struct dvb_frontend_ops cx24120_ops; struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, struct i2c_adapter *i2c) @@ -1551,7 +1551,7 @@ static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static struct dvb_frontend_ops cx24120_ops = { +static const struct dvb_frontend_ops cx24120_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Conexant CX24120/CX24118", diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index b1287de98e86..8aed8cc9f93d 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -1049,7 +1049,7 @@ struct i2c_adapter * } EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); -static struct dvb_frontend_ops cx24123_ops; +static const struct dvb_frontend_ops cx24123_ops; struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, struct i2c_adapter *i2c) @@ -1111,7 +1111,7 @@ error: } EXPORT_SYMBOL(cx24123_attach); -static struct dvb_frontend_ops cx24123_ops = { +static const struct dvb_frontend_ops cx24123_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Conexant CX24123/CX24109", diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index 5afb9c508f65..614bfb3740f1 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -3719,7 +3719,7 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe) return 0; } -static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops; +static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops; static struct dvb_frontend_ops cxd2841er_t_c_ops; static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg, @@ -3801,7 +3801,7 @@ struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, } EXPORT_SYMBOL(cxd2841er_attach_t_c); -static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { +static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Sony CXD2841ER DVB-S/S2 demodulator", @@ -3829,7 +3829,7 @@ static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { .tune = cxd2841er_tune_s }; -static struct dvb_frontend_ops cxd2841er_t_c_ops = { +static struct dvb_frontend_ops cxd2841er_t_c_ops = { .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, .info = { .name = "", /* will set in attach function */ diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c index bf9762783be4..068bec104e29 100644 --- a/drivers/media/dvb-frontends/dib3000mb.c +++ b/drivers/media/dvb-frontends/dib3000mb.c @@ -742,7 +742,7 @@ static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_ return 0; } -static struct dvb_frontend_ops dib3000mb_ops; +static const struct dvb_frontend_ops dib3000mb_ops; struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) @@ -782,7 +782,7 @@ error: return NULL; } -static struct dvb_frontend_ops dib3000mb_ops = { +static const struct dvb_frontend_ops dib3000mb_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 3000M-B DVB-T", diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index 0f7793455da7..224283fe100a 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -879,7 +879,7 @@ int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defa } EXPORT_SYMBOL(dib3000mc_i2c_enumeration); -static struct dvb_frontend_ops dib3000mc_ops; +static const struct dvb_frontend_ops dib3000mc_ops; struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) { @@ -912,7 +912,7 @@ error: } EXPORT_SYMBOL(dib3000mc_attach); -static struct dvb_frontend_ops dib3000mc_ops = { +static const struct dvb_frontend_ops dib3000mc_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 3000MC/P", diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c index c9ebb0ff746a..5ce9f93a65c3 100644 --- a/drivers/media/dvb-frontends/dib7000m.c +++ b/drivers/media/dvb-frontends/dib7000m.c @@ -1401,7 +1401,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, EXPORT_SYMBOL(dib7000m_i2c_enumeration); #endif -static struct dvb_frontend_ops dib7000m_ops; +static const struct dvb_frontend_ops dib7000m_ops; struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) { struct dvb_frontend *demod; @@ -1439,7 +1439,7 @@ error: } EXPORT_SYMBOL(dib7000m_attach); -static struct dvb_frontend_ops dib7000m_ops = { +static const struct dvb_frontend_ops dib7000m_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 7000MA/MB/PA/PB/MC", diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 2cee51c08a5a..a27c0001f2d6 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2721,7 +2721,7 @@ static int dib7090_slave_reset(struct dvb_frontend *fe) return 0; } -static struct dvb_frontend_ops dib7000p_ops; +static const struct dvb_frontend_ops dib7000p_ops; static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) { struct dvb_frontend *demod; @@ -2811,7 +2811,7 @@ void *dib7000p_attach(struct dib7000p_ops *ops) } EXPORT_SYMBOL(dib7000p_attach); -static struct dvb_frontend_ops dib7000p_ops = { +static const struct dvb_frontend_ops dib7000p_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 7000PC", diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 3c76ceb6c374..c95fff4f9582 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -2490,7 +2490,7 @@ struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int sla } EXPORT_SYMBOL(dib9000_get_slave_frontend); -static struct dvb_frontend_ops dib9000_ops; +static const struct dvb_frontend_ops dib9000_ops; struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg) { struct dvb_frontend *fe; @@ -2567,7 +2567,7 @@ error: } EXPORT_SYMBOL(dib9000_attach); -static struct dvb_frontend_ops dib9000_ops = { +static const struct dvb_frontend_ops dib9000_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 9000", diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index bd6d2ee0f7c9..f1c3e3b09b65 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -12264,7 +12264,7 @@ static void drx39xxj_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops drx39xxj_ops; +static const struct dvb_frontend_ops drx39xxj_ops; struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) { @@ -12363,7 +12363,7 @@ error: } EXPORT_SYMBOL(drx39xxj_attach); -static struct dvb_frontend_ops drx39xxj_ops = { +static const struct dvb_frontend_ops drx39xxj_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Micronas DRX39xxj family Frontend", diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 445a15c2714f..4143f0326684 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c @@ -2912,7 +2912,7 @@ static void drxd_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops drxd_ops = { +static const struct dvb_frontend_ops drxd_ops = { .delsys = { SYS_DVBT}, .info = { .name = "Micronas DRXD DVB-T", diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index c595adc61c6f..146edf344dd8 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -6737,7 +6737,7 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe, } } -static struct dvb_frontend_ops drxk_ops = { +static const struct dvb_frontend_ops drxk_ops = { /* .delsys will be filled dynamically */ .info = { .name = "DRXK", diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c index 6dc79d4528c2..0b17a45c5640 100644 --- a/drivers/media/dvb-frontends/ds3000.c +++ b/drivers/media/dvb-frontends/ds3000.c @@ -830,7 +830,7 @@ static void ds3000_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops ds3000_ops; +static const struct dvb_frontend_ops ds3000_ops; struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, struct i2c_adapter *i2c) @@ -1104,7 +1104,7 @@ static int ds3000_initfe(struct dvb_frontend *fe) return 0; } -static struct dvb_frontend_ops ds3000_ops = { +static const struct dvb_frontend_ops ds3000_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Montage Technology DS3000", diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c index e5bd8c62ad3a..efc3c31a7635 100644 --- a/drivers/media/dvb-frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c @@ -119,7 +119,7 @@ static void dvb_dummy_fe_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops; +static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops; struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) { @@ -136,7 +136,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) return &state->frontend; } -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; +static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) { @@ -153,7 +153,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) return &state->frontend; } -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; +static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops; struct dvb_frontend *dvb_dummy_fe_qam_attach(void) { @@ -170,7 +170,7 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void) return &state->frontend; } -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { +static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Dummy DVB-T", @@ -201,7 +201,7 @@ static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { .read_ucblocks = dvb_dummy_fe_read_ucblocks, }; -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { +static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "Dummy DVB-C", @@ -230,7 +230,7 @@ static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { .read_ucblocks = dvb_dummy_fe_read_ucblocks, }; -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = { +static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Dummy DVB-S", diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c index c9012e677cd1..d97ce21e26e1 100644 --- a/drivers/media/dvb-frontends/ec100.c +++ b/drivers/media/dvb-frontends/ec100.c @@ -280,7 +280,7 @@ static void ec100_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops ec100_ops; +static const struct dvb_frontend_ops ec100_ops; struct dvb_frontend *ec100_attach(const struct ec100_config *config, struct i2c_adapter *i2c) @@ -315,7 +315,7 @@ error: } EXPORT_SYMBOL(ec100_attach); -static struct dvb_frontend_ops ec100_ops = { +static const struct dvb_frontend_ops ec100_ops = { .delsys = { SYS_DVBT }, .info = { .name = "E3C EC100 DVB-T", diff --git a/drivers/media/dvb-frontends/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c index 93f59bfea092..efe015df7f1d 100644 --- a/drivers/media/dvb-frontends/gp8psk-fe.c +++ b/drivers/media/dvb-frontends/gp8psk-fe.c @@ -323,7 +323,7 @@ static void gp8psk_fe_release(struct dvb_frontend* fe) kfree(st); } -static struct dvb_frontend_ops gp8psk_fe_ops; +static const struct dvb_frontend_ops gp8psk_fe_ops; struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, void *priv, bool is_rev1) @@ -351,7 +351,7 @@ struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, } EXPORT_SYMBOL_GPL(gp8psk_fe_attach); -static struct dvb_frontend_ops gp8psk_fe_ops = { +static const struct dvb_frontend_ops gp8psk_fe_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Genpix DVB-S", diff --git a/drivers/media/dvb-frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c index 1c7eb477e2cd..8b53633cf325 100644 --- a/drivers/media/dvb-frontends/hd29l2.c +++ b/drivers/media/dvb-frontends/hd29l2.c @@ -793,7 +793,7 @@ static void hd29l2_release(struct dvb_frontend *fe) kfree(priv); } -static struct dvb_frontend_ops hd29l2_ops; +static const struct dvb_frontend_ops hd29l2_ops; struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config, struct i2c_adapter *i2c) @@ -828,7 +828,7 @@ err: } EXPORT_SYMBOL(hd29l2_attach); -static struct dvb_frontend_ops hd29l2_ops = { +static const struct dvb_frontend_ops hd29l2_ops = { .delsys = { SYS_DVBT }, .info = { .name = "HDIC HD29L2 DMB-TH", diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c index 2f3d0519e19b..68923c84679a 100644 --- a/drivers/media/dvb-frontends/l64781.c +++ b/drivers/media/dvb-frontends/l64781.c @@ -496,7 +496,7 @@ static void l64781_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops l64781_ops; +static const struct dvb_frontend_ops l64781_ops; struct dvb_frontend* l64781_attach(const struct l64781_config* config, struct i2c_adapter* i2c) @@ -571,7 +571,7 @@ error: return NULL; } -static struct dvb_frontend_ops l64781_ops = { +static const struct dvb_frontend_ops l64781_ops = { .delsys = { SYS_DVBT }, .info = { .name = "LSI L64781 DVB-T", diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c index f51a3a0b3949..3b31e5f20f46 100644 --- a/drivers/media/dvb-frontends/lg2160.c +++ b/drivers/media/dvb-frontends/lg2160.c @@ -1359,7 +1359,7 @@ static void lg216x_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops lg2160_ops = { +static const struct dvb_frontend_ops lg2160_ops = { .delsys = { SYS_ATSCMH }, .info = { .name = "LG Electronics LG2160 ATSC/MH Frontend", @@ -1387,7 +1387,7 @@ static struct dvb_frontend_ops lg2160_ops = { .release = lg216x_release, }; -static struct dvb_frontend_ops lg2161_ops = { +static const struct dvb_frontend_ops lg2161_ops = { .delsys = { SYS_ATSCMH }, .info = { .name = "LG Electronics LG2161 ATSC/MH Frontend", diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c index 4503e8852fd1..9f5d9380bf5f 100644 --- a/drivers/media/dvb-frontends/lgdt3305.c +++ b/drivers/media/dvb-frontends/lgdt3305.c @@ -1103,8 +1103,8 @@ static void lgdt3305_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops lgdt3304_ops; -static struct dvb_frontend_ops lgdt3305_ops; +static const struct dvb_frontend_ops lgdt3304_ops; +static const struct dvb_frontend_ops lgdt3305_ops; struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, struct i2c_adapter *i2c_adap) @@ -1164,7 +1164,7 @@ fail: } EXPORT_SYMBOL(lgdt3305_attach); -static struct dvb_frontend_ops lgdt3304_ops = { +static const struct dvb_frontend_ops lgdt3304_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "LG Electronics LGDT3304 VSB/QAM Frontend", @@ -1187,7 +1187,7 @@ static struct dvb_frontend_ops lgdt3304_ops = { .release = lgdt3305_release, }; -static struct dvb_frontend_ops lgdt3305_ops = { +static const struct dvb_frontend_ops lgdt3305_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "LG Electronics LGDT3305 VSB/QAM Frontend", diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 0ca4e810e9d8..19dca46b1171 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -1767,7 +1767,7 @@ static void lgdt3306a_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops lgdt3306a_ops; +static const struct dvb_frontend_ops lgdt3306a_ops; struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config, struct i2c_adapter *i2c_adap) @@ -2103,7 +2103,7 @@ static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state) -static struct dvb_frontend_ops lgdt3306a_ops = { +static const struct dvb_frontend_ops lgdt3306a_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "LG Electronics LGDT3306A VSB/QAM Frontend", diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c index 8cb6c56d220a..2f4a0316f89c 100644 --- a/drivers/media/dvb-frontends/lgdt330x.c +++ b/drivers/media/dvb-frontends/lgdt330x.c @@ -728,8 +728,8 @@ static void lgdt330x_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops lgdt3302_ops; -static struct dvb_frontend_ops lgdt3303_ops; +static const struct dvb_frontend_ops lgdt3302_ops; +static const struct dvb_frontend_ops lgdt3303_ops; struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, struct i2c_adapter* i2c) @@ -774,7 +774,7 @@ error: return NULL; } -static struct dvb_frontend_ops lgdt3302_ops = { +static const struct dvb_frontend_ops lgdt3302_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name= "LG Electronics LGDT3302 VSB/QAM Frontend", @@ -797,7 +797,7 @@ static struct dvb_frontend_ops lgdt3302_ops = { .release = lgdt330x_release, }; -static struct dvb_frontend_ops lgdt3303_ops = { +static const struct dvb_frontend_ops lgdt3303_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name= "LG Electronics LGDT3303 VSB/QAM Frontend", diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c index fbfd87b5b803..970e42fdbc1b 100644 --- a/drivers/media/dvb-frontends/lgs8gl5.c +++ b/drivers/media/dvb-frontends/lgs8gl5.c @@ -376,7 +376,7 @@ lgs8gl5_release(struct dvb_frontend *fe) } -static struct dvb_frontend_ops lgs8gl5_ops; +static const struct dvb_frontend_ops lgs8gl5_ops; struct dvb_frontend* @@ -412,7 +412,7 @@ error: EXPORT_SYMBOL(lgs8gl5_attach); -static struct dvb_frontend_ops lgs8gl5_ops = { +static const struct dvb_frontend_ops lgs8gl5_ops = { .delsys = { SYS_DTMB }, .info = { .name = "Legend Silicon LGS-8GL5 DMB-TH", diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c index 919daeb96747..6d2e62469d58 100644 --- a/drivers/media/dvb-frontends/lgs8gxx.c +++ b/drivers/media/dvb-frontends/lgs8gxx.c @@ -985,7 +985,7 @@ static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) return lgs8gxx_write_reg(priv, 0x01, 0); } -static struct dvb_frontend_ops lgs8gxx_ops = { +static const struct dvb_frontend_ops lgs8gxx_ops = { .delsys = { SYS_DTMB }, .info = { .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH", diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index e0fe5bc9dbce..50bce68ffd66 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -16,7 +16,7 @@ #include "m88ds3103_priv.h" -static struct dvb_frontend_ops m88ds3103_ops; +static const struct dvb_frontend_ops m88ds3103_ops; /* write single register with mask */ static int m88ds3103_update_bits(struct m88ds3103_dev *dev, @@ -1295,7 +1295,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, } EXPORT_SYMBOL(m88ds3103_attach); -static struct dvb_frontend_ops m88ds3103_ops = { +static const struct dvb_frontend_ops m88ds3103_ops = { .delsys = {SYS_DVBS, SYS_DVBS2}, .info = { .name = "Montage Technology M88DS3103", diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index 3669c906ba01..ce6c21d405ee 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -752,7 +752,7 @@ static void m88rs2000_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops m88rs2000_ops = { +static const struct dvb_frontend_ops m88rs2000_ops = { .delsys = { SYS_DVBS }, .info = { .name = "M88RS2000 DVB-S", diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c index 79bc671e8769..9bb122c39c1b 100644 --- a/drivers/media/dvb-frontends/mb86a16.c +++ b/drivers/media/dvb-frontends/mb86a16.c @@ -1816,7 +1816,7 @@ static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_CUSTOM; } -static struct dvb_frontend_ops mb86a16_ops = { +static const struct dvb_frontend_ops mb86a16_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Fujitsu MB86A16 DVB-S", diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 27f425137ce6..e8ac8c3e2ec0 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -2060,7 +2060,7 @@ static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_HW; } -static struct dvb_frontend_ops mb86a20s_ops; +static const struct dvb_frontend_ops mb86a20s_ops; struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, struct i2c_adapter *i2c) @@ -2108,7 +2108,7 @@ error: } EXPORT_SYMBOL(mb86a20s_attach); -static struct dvb_frontend_ops mb86a20s_ops = { +static const struct dvb_frontend_ops mb86a20s_ops = { .delsys = { SYS_ISDBT }, /* Use dib8000 values per default */ .info = { diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index 18fb2df1e2bd..b6f5f8337cfd 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -411,7 +411,7 @@ err: return ret; } -static struct dvb_frontend_ops mn88472_ops = { +static const struct dvb_frontend_ops mn88472_ops = { .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, .info = { .name = "Panasonic MN88472", diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c index fdee75b1b99a..961b9a2508e0 100644 --- a/drivers/media/dvb-frontends/mt312.c +++ b/drivers/media/dvb-frontends/mt312.c @@ -748,7 +748,7 @@ static void mt312_release(struct dvb_frontend *fe) } #define MT312_SYS_CLK 90000000UL /* 90 MHz */ -static struct dvb_frontend_ops mt312_ops = { +static const struct dvb_frontend_ops mt312_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Zarlink ???? DVB-S", diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c index c0bb6328956b..48ea0408f02a 100644 --- a/drivers/media/dvb-frontends/mt352.c +++ b/drivers/media/dvb-frontends/mt352.c @@ -538,7 +538,7 @@ static void mt352_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops mt352_ops; +static const struct dvb_frontend_ops mt352_ops; struct dvb_frontend* mt352_attach(const struct mt352_config* config, struct i2c_adapter* i2c) @@ -566,7 +566,7 @@ error: return NULL; } -static struct dvb_frontend_ops mt352_ops = { +static const struct dvb_frontend_ops mt352_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Zarlink MT352 DVB-T", diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 7c23f0499f23..2fe40372ca07 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c @@ -1149,7 +1149,7 @@ static void nxt200x_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops nxt200x_ops; +static const struct dvb_frontend_ops nxt200x_ops; struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, struct i2c_adapter* i2c) @@ -1212,7 +1212,7 @@ error: return NULL; } -static struct dvb_frontend_ops nxt200x_ops = { +static const struct dvb_frontend_ops nxt200x_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Nextwave NXT200X VSB/QAM frontend", diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c index 1545d898b125..1ce5ea28489b 100644 --- a/drivers/media/dvb-frontends/nxt6000.c +++ b/drivers/media/dvb-frontends/nxt6000.c @@ -564,7 +564,7 @@ static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) } } -static struct dvb_frontend_ops nxt6000_ops; +static const struct dvb_frontend_ops nxt6000_ops; struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, struct i2c_adapter* i2c) @@ -592,7 +592,7 @@ error: return NULL; } -static struct dvb_frontend_ops nxt6000_ops = { +static const struct dvb_frontend_ops nxt6000_ops = { .delsys = { SYS_DVBT }, .info = { .name = "NxtWave NXT6000 DVB-T", diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c index bacea20822ea..17bdadd7d0e1 100644 --- a/drivers/media/dvb-frontends/or51132.c +++ b/drivers/media/dvb-frontends/or51132.c @@ -559,7 +559,7 @@ static void or51132_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops or51132_ops; +static const struct dvb_frontend_ops or51132_ops; struct dvb_frontend* or51132_attach(const struct or51132_config* config, struct i2c_adapter* i2c) @@ -583,7 +583,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, return &state->frontend; } -static struct dvb_frontend_ops or51132_ops = { +static const struct dvb_frontend_ops or51132_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Oren OR51132 VSB/QAM Frontend", diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c index 839479eab3b3..27eb73aa4f62 100644 --- a/drivers/media/dvb-frontends/or51211.c +++ b/drivers/media/dvb-frontends/or51211.c @@ -507,7 +507,7 @@ static void or51211_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops or51211_ops; +static const struct dvb_frontend_ops or51211_ops; struct dvb_frontend* or51211_attach(const struct or51211_config* config, struct i2c_adapter* i2c) @@ -531,7 +531,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, return &state->frontend; } -static struct dvb_frontend_ops or51211_ops = { +static const struct dvb_frontend_ops or51211_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Oren OR51211 VSB Frontend", diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index 87226056f226..7bbfe11d11ed 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -548,7 +548,7 @@ static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) return 0; } -static struct dvb_frontend_ops rtl2830_ops = { +static const struct dvb_frontend_ops rtl2830_ops = { .delsys = {SYS_DVBT}, .info = { .name = "Realtek RTL2830 (DVB-T)", diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 0ced01f1012e..94bf5b7d6f3f 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -837,7 +837,7 @@ static int rtl2832_deselect(struct i2c_mux_core *muxc, u32 chan_id) return 0; } -static struct dvb_frontend_ops rtl2832_ops = { +static const struct dvb_frontend_ops rtl2832_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Realtek RTL2832 (DVB-T)", diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c index 56c3fb442d6c..f370c6df0a8b 100644 --- a/drivers/media/dvb-frontends/s5h1409.c +++ b/drivers/media/dvb-frontends/s5h1409.c @@ -949,7 +949,7 @@ static void s5h1409_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops s5h1409_ops; +static const struct dvb_frontend_ops s5h1409_ops; struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, struct i2c_adapter *i2c) @@ -995,7 +995,7 @@ error: } EXPORT_SYMBOL(s5h1409_attach); -static struct dvb_frontend_ops s5h1409_ops = { +static const struct dvb_frontend_ops s5h1409_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Samsung S5H1409 QAM/8VSB Frontend", diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c index a861854981b7..f29750a96196 100644 --- a/drivers/media/dvb-frontends/s5h1411.c +++ b/drivers/media/dvb-frontends/s5h1411.c @@ -864,7 +864,7 @@ static void s5h1411_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops s5h1411_ops; +static const struct dvb_frontend_ops s5h1411_ops; struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, struct i2c_adapter *i2c) @@ -914,7 +914,7 @@ error: } EXPORT_SYMBOL(s5h1411_attach); -static struct dvb_frontend_ops s5h1411_ops = { +static const struct dvb_frontend_ops s5h1411_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Samsung S5H1411 QAM/8VSB Frontend", diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index d7d0b7d57ad7..f9a18fe94d88 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -880,7 +880,7 @@ struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) } EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter); -static struct dvb_frontend_ops s5h1420_ops; +static const struct dvb_frontend_ops s5h1420_ops; struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, struct i2c_adapter *i2c) @@ -934,7 +934,7 @@ error: } EXPORT_SYMBOL(s5h1420_attach); -static struct dvb_frontend_ops s5h1420_ops = { +static const struct dvb_frontend_ops s5h1420_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S", diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c index 5de79739cf63..a32fd9bc51a9 100644 --- a/drivers/media/dvb-frontends/s5h1432.c +++ b/drivers/media/dvb-frontends/s5h1432.c @@ -341,7 +341,7 @@ static void s5h1432_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops s5h1432_ops; +static const struct dvb_frontend_ops s5h1432_ops; struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, struct i2c_adapter *i2c) @@ -370,7 +370,7 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, } EXPORT_SYMBOL(s5h1432_attach); -static struct dvb_frontend_ops s5h1432_ops = { +static const struct dvb_frontend_ops s5h1432_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Samsung s5h1432 DVB-T Frontend", diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c index 98cceb149b91..274544a3ae0e 100644 --- a/drivers/media/dvb-frontends/s921.c +++ b/drivers/media/dvb-frontends/s921.c @@ -477,7 +477,7 @@ static void s921_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops s921_ops; +static const struct dvb_frontend_ops s921_ops; struct dvb_frontend *s921_attach(const struct s921_config *config, struct i2c_adapter *i2c) @@ -505,7 +505,7 @@ struct dvb_frontend *s921_attach(const struct s921_config *config, } EXPORT_SYMBOL(s921_attach); -static struct dvb_frontend_ops s921_ops = { +static const struct dvb_frontend_ops s921_ops = { .delsys = { SYS_ISDBT }, /* Use dib8000 values per default */ .info = { diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 78669ea68c61..528b82a5dd46 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -978,7 +978,7 @@ static int si2165_set_frontend(struct dvb_frontend *fe) return 0; } -static struct dvb_frontend_ops si2165_ops = { +static const struct dvb_frontend_ops si2165_ops = { .info = { .name = "Silicon Labs ", /* For DVB-C */ diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c index 32ebfb78bfdd..4e8c3ac4303f 100644 --- a/drivers/media/dvb-frontends/si21xx.c +++ b/drivers/media/dvb-frontends/si21xx.c @@ -866,7 +866,7 @@ static void si21xx_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops si21xx_ops = { +static const struct dvb_frontend_ops si21xx_ops = { .delsys = { SYS_DVBS }, .info = { .name = "SL SI21XX DVB-S", diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c index e87ac30d7fb8..04454cb78467 100644 --- a/drivers/media/dvb-frontends/sp8870.c +++ b/drivers/media/dvb-frontends/sp8870.c @@ -551,7 +551,7 @@ static void sp8870_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops sp8870_ops; +static const struct dvb_frontend_ops sp8870_ops; struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, struct i2c_adapter* i2c) @@ -580,7 +580,7 @@ error: return NULL; } -static struct dvb_frontend_ops sp8870_ops = { +static const struct dvb_frontend_ops sp8870_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Spase SP8870 DVB-T", diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c index f9194b7b7fec..7c511c3cd4ca 100644 --- a/drivers/media/dvb-frontends/sp887x.c +++ b/drivers/media/dvb-frontends/sp887x.c @@ -561,7 +561,7 @@ static void sp887x_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops sp887x_ops; +static const struct dvb_frontend_ops sp887x_ops; struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, struct i2c_adapter* i2c) @@ -590,7 +590,7 @@ error: return NULL; } -static struct dvb_frontend_ops sp887x_ops = { +static const struct dvb_frontend_ops sp887x_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Spase SP887x DVB-T", diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index 8e7cafb8f36a..cc18891f9b45 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -1573,7 +1573,7 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_CUSTOM; } -static struct dvb_frontend_ops stb0899_ops = { +static const struct dvb_frontend_ops stb0899_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STB0899 Multistandard", diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index 12f6a4205e3e..45cbc898ad25 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -535,7 +535,7 @@ static void stv0288_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops stv0288_ops = { +static const struct dvb_frontend_ops stv0288_ops = { .delsys = { SYS_DVBS }, .info = { .name = "ST STV0288 DVB-S", diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c index 73b4d4243b74..db94d4d109f9 100644 --- a/drivers/media/dvb-frontends/stv0297.c +++ b/drivers/media/dvb-frontends/stv0297.c @@ -658,7 +658,7 @@ static void stv0297_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops stv0297_ops; +static const struct dvb_frontend_ops stv0297_ops; struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, struct i2c_adapter *i2c) @@ -690,7 +690,7 @@ error: return NULL; } -static struct dvb_frontend_ops stv0297_ops = { +static const struct dvb_frontend_ops stv0297_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "ST STV0297 DVB-C", diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c index a9b28ceb80d8..b36b21a13201 100644 --- a/drivers/media/dvb-frontends/stv0299.c +++ b/drivers/media/dvb-frontends/stv0299.c @@ -673,7 +673,7 @@ static void stv0299_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops stv0299_ops; +static const struct dvb_frontend_ops stv0299_ops; struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c) @@ -713,7 +713,7 @@ error: return NULL; } -static struct dvb_frontend_ops stv0299_ops = { +static const struct dvb_frontend_ops stv0299_ops = { .delsys = { SYS_DVBS }, .info = { .name = "ST STV0299 DVB-S", diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index abc379aea713..4ac1ce2831ba 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -2272,7 +2272,7 @@ static void stv0367_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops stv0367ter_ops = { +static const struct dvb_frontend_ops stv0367ter_ops = { .delsys = { SYS_DVBT }, .info = { .name = "ST STV0367 DVB-T", @@ -3390,7 +3390,7 @@ static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks) return 0; }; -static struct dvb_frontend_ops stv0367cab_ops = { +static const struct dvb_frontend_ops stv0367cab_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "ST STV0367 DVB-C", diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c index f667005a6661..43a0f69b4b14 100644 --- a/drivers/media/dvb-frontends/stv0900_core.c +++ b/drivers/media/dvb-frontends/stv0900_core.c @@ -1875,7 +1875,7 @@ static int stv0900_get_frontend(struct dvb_frontend *fe, return 0; } -static struct dvb_frontend_ops stv0900_ops = { +static const struct dvb_frontend_ops stv0900_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STV0900 frontend", diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 42d62cc9a357..b586d2a49737 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -4880,7 +4880,7 @@ static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg); } -static struct dvb_frontend_ops stv090x_ops = { +static const struct dvb_frontend_ops stv090x_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STV090x Multistandard", diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c index 4c514e6bffda..32ba8401e743 100644 --- a/drivers/media/dvb-frontends/tda10021.c +++ b/drivers/media/dvb-frontends/tda10021.c @@ -443,7 +443,7 @@ static void tda10021_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops tda10021_ops; +static const struct dvb_frontend_ops tda10021_ops; struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, struct i2c_adapter* i2c, @@ -483,7 +483,7 @@ error: return NULL; } -static struct dvb_frontend_ops tda10021_ops = { +static const struct dvb_frontend_ops tda10021_ops = { .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, .info = { .name = "Philips TDA10021 DVB-C", diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index 0c416be76d65..8028007c68eb 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -514,7 +514,7 @@ static void tda10023_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops tda10023_ops; +static const struct dvb_frontend_ops tda10023_ops; struct dvb_frontend *tda10023_attach(const struct tda10023_config *config, struct i2c_adapter *i2c, @@ -571,7 +571,7 @@ error: return NULL; } -static struct dvb_frontend_ops tda10023_ops = { +static const struct dvb_frontend_ops tda10023_ops = { .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, .info = { .name = "Philips TDA10023 DVB-C", diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c index 7cb23f89a03b..92ab34c3e0be 100644 --- a/drivers/media/dvb-frontends/tda10048.c +++ b/drivers/media/dvb-frontends/tda10048.c @@ -1090,7 +1090,7 @@ static void tda10048_establish_defaults(struct dvb_frontend *fe) } } -static struct dvb_frontend_ops tda10048_ops; +static const struct dvb_frontend_ops tda10048_ops; struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, struct i2c_adapter *i2c) @@ -1152,7 +1152,7 @@ error: } EXPORT_SYMBOL(tda10048_attach); -static struct dvb_frontend_ops tda10048_ops = { +static const struct dvb_frontend_ops tda10048_ops = { .delsys = { SYS_DVBT }, .info = { .name = "NXP TDA10048HN DVB-T", diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c index b89848313fb9..e674508c349c 100644 --- a/drivers/media/dvb-frontends/tda1004x.c +++ b/drivers/media/dvb-frontends/tda1004x.c @@ -1245,7 +1245,7 @@ static void tda1004x_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops tda10045_ops = { +static const struct dvb_frontend_ops tda10045_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Philips TDA10045H DVB-T", @@ -1315,7 +1315,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, return &state->frontend; } -static struct dvb_frontend_ops tda10046_ops = { +static const struct dvb_frontend_ops tda10046_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Philips TDA10046H DVB-T", diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index 37ebeef2bbd0..a59f4fd09df6 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -20,7 +20,7 @@ #include "tda10071_priv.h" -static struct dvb_frontend_ops tda10071_ops; +static const struct dvb_frontend_ops tda10071_ops; /* * XXX: regmap_update_bits() does not fit our needs as it does not support @@ -1102,7 +1102,7 @@ static int tda10071_get_tune_settings(struct dvb_frontend *fe, return 0; } -static struct dvb_frontend_ops tda10071_ops = { +static const struct dvb_frontend_ops tda10071_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "NXP TDA10071", diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c index 31d0acb54fe8..b6d16c05904d 100644 --- a/drivers/media/dvb-frontends/tda10086.c +++ b/drivers/media/dvb-frontends/tda10086.c @@ -706,7 +706,7 @@ static void tda10086_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops tda10086_ops = { +static const struct dvb_frontend_ops tda10086_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Philips TDA10086 DVB-S", diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c index 9072d6463094..aa3200d3c352 100644 --- a/drivers/media/dvb-frontends/tda8083.c +++ b/drivers/media/dvb-frontends/tda8083.c @@ -421,7 +421,7 @@ static void tda8083_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops tda8083_ops; +static const struct dvb_frontend_ops tda8083_ops; struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, struct i2c_adapter* i2c) @@ -449,7 +449,7 @@ error: return NULL; } -static struct dvb_frontend_ops tda8083_ops = { +static const struct dvb_frontend_ops tda8083_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Philips TDA8083 DVB-S", diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c index 24ac54b3b967..178363704bd4 100644 --- a/drivers/media/dvb-frontends/ves1820.c +++ b/drivers/media/dvb-frontends/ves1820.c @@ -369,7 +369,7 @@ static void ves1820_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops ves1820_ops; +static const struct dvb_frontend_ops ves1820_ops; struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, struct i2c_adapter* i2c, @@ -408,7 +408,7 @@ error: return NULL; } -static struct dvb_frontend_ops ves1820_ops = { +static const struct dvb_frontend_ops ves1820_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "VLSI VES1820 DVB-C", diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c index ed113e216e14..d0ee52f66a8e 100644 --- a/drivers/media/dvb-frontends/ves1x93.c +++ b/drivers/media/dvb-frontends/ves1x93.c @@ -454,7 +454,7 @@ static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) } } -static struct dvb_frontend_ops ves1x93_ops; +static const struct dvb_frontend_ops ves1x93_ops; struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, struct i2c_adapter* i2c) @@ -512,7 +512,7 @@ error: return NULL; } -static struct dvb_frontend_ops ves1x93_ops = { +static const struct dvb_frontend_ops ves1x93_ops = { .delsys = { SYS_DVBS }, .info = { .name = "VLSI VES1x93 DVB-S", diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c index 3b08176d7bec..4f3ff3e853ac 100644 --- a/drivers/media/dvb-frontends/zl10353.c +++ b/drivers/media/dvb-frontends/zl10353.c @@ -602,7 +602,7 @@ static void zl10353_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops zl10353_ops; +static const struct dvb_frontend_ops zl10353_ops; struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c) @@ -634,7 +634,7 @@ error: return NULL; } -static struct dvb_frontend_ops zl10353_ops = { +static const struct dvb_frontend_ops zl10353_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Zarlink ZL10353 DVB-T", diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index faea3f06e350..7166d2279465 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c @@ -1696,10 +1696,10 @@ static void bt8xx_dst_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops dst_dvbt_ops; -static struct dvb_frontend_ops dst_dvbs_ops; -static struct dvb_frontend_ops dst_dvbc_ops; -static struct dvb_frontend_ops dst_atsc_ops; +static const struct dvb_frontend_ops dst_dvbt_ops; +static const struct dvb_frontend_ops dst_dvbs_ops; +static const struct dvb_frontend_ops dst_dvbc_ops; +static const struct dvb_frontend_ops dst_atsc_ops; struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) { @@ -1735,7 +1735,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad EXPORT_SYMBOL(dst_attach); -static struct dvb_frontend_ops dst_dvbt_ops = { +static const struct dvb_frontend_ops dst_dvbt_ops = { .delsys = { SYS_DVBT }, .info = { .name = "DST DVB-T", @@ -1764,7 +1764,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { .read_snr = dst_read_snr, }; -static struct dvb_frontend_ops dst_dvbs_ops = { +static const struct dvb_frontend_ops dst_dvbs_ops = { .delsys = { SYS_DVBS }, .info = { .name = "DST DVB-S", @@ -1793,7 +1793,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .set_tone = dst_set_tone, }; -static struct dvb_frontend_ops dst_dvbc_ops = { +static const struct dvb_frontend_ops dst_dvbc_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "DST DVB-C", @@ -1822,7 +1822,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { .read_snr = dst_read_snr, }; -static struct dvb_frontend_ops dst_atsc_ops = { +static const struct dvb_frontend_ops dst_atsc_ops = { .delsys = { SYS_ATSC }, .info = { .name = "DST ATSC", diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c index d0e70dc0e16f..249273b2e0f2 100644 --- a/drivers/media/pci/pt1/va1j5jf8007s.c +++ b/drivers/media/pci/pt1/va1j5jf8007s.c @@ -578,7 +578,7 @@ static void va1j5jf8007s_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops va1j5jf8007s_ops = { +static const struct dvb_frontend_ops va1j5jf8007s_ops = { .delsys = { SYS_ISDBS }, .info = { .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S", diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c index 0268f20b8097..e0766e69a370 100644 --- a/drivers/media/pci/pt1/va1j5jf8007t.c +++ b/drivers/media/pci/pt1/va1j5jf8007t.c @@ -427,7 +427,7 @@ static void va1j5jf8007t_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops va1j5jf8007t_ops = { +static const struct dvb_frontend_ops va1j5jf8007t_ops = { .delsys = { SYS_ISDBT }, .info = { .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T", diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c index 6b75415b75a5..a59c567c55d6 100644 --- a/drivers/media/tuners/tda8290.c +++ b/drivers/media/tuners/tda8290.c @@ -721,7 +721,7 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) return -ENODEV; } -static struct analog_demod_ops tda8290_ops = { +static const struct analog_demod_ops tda8290_ops = { .set_params = tda8290_set_params, .has_signal = tda8290_has_signal, .standby = tda8290_standby, @@ -729,7 +729,7 @@ static struct analog_demod_ops tda8290_ops = { .i2c_gate_ctrl = tda8290_i2c_bridge, }; -static struct analog_demod_ops tda8295_ops = { +static const struct analog_demod_ops tda8295_ops = { .set_params = tda8295_set_params, .has_signal = tda8295_has_signal, .standby = tda8295_standby, diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c index 56be6c29399b..c0e815f8b951 100644 --- a/drivers/media/tuners/tda9887.c +++ b/drivers/media/tuners/tda9887.c @@ -659,7 +659,7 @@ static void tda9887_release(struct dvb_frontend *fe) fe->analog_demod_priv = NULL; } -static struct analog_demod_ops tda9887_ops = { +static const struct analog_demod_ops tda9887_ops = { .info = { .name = "tda9887", }, diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c index 047a32fe43ea..639e156e0c1b 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c @@ -549,7 +549,7 @@ static void mxl111sf_demod_release(struct dvb_frontend *fe) fe->demodulator_priv = NULL; } -static struct dvb_frontend_ops mxl111sf_demod_ops = { +static const struct dvb_frontend_ops mxl111sf_demod_ops = { .delsys = { SYS_DVBT }, .info = { .name = "MaxLinear MxL111SF DVB-T demodulator", diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 09db3d02bd82..9862d3e6b8e8 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -1430,7 +1430,7 @@ static void af9005_fe_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops af9005_fe_ops; +static const struct dvb_frontend_ops af9005_fe_ops; struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) { @@ -1455,7 +1455,7 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) return NULL; } -static struct dvb_frontend_ops af9005_fe_ops = { +static const struct dvb_frontend_ops af9005_fe_ops = { .delsys = { SYS_DVBT }, .info = { .name = "AF9005 USB DVB-T", diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c index 2d29b4174dba..bbb10fab65bc 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c @@ -278,7 +278,7 @@ static void cinergyt2_fe_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops cinergyt2_fe_ops; +static const struct dvb_frontend_ops cinergyt2_fe_ops; struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) { @@ -295,7 +295,7 @@ struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) } -static struct dvb_frontend_ops cinergyt2_fe_ops = { +static const struct dvb_frontend_ops cinergyt2_fe_ops = { .delsys = { SYS_DVBT }, .info = { .name = DRIVER_NAME, diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c index f5c042baa254..00f565fe7cc2 100644 --- a/drivers/media/usb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c @@ -202,7 +202,7 @@ static void dtt200u_fe_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops dtt200u_fe_ops; +static const struct dvb_frontend_ops dtt200u_fe_ops; struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) { @@ -226,7 +226,7 @@ error: return NULL; } -static struct dvb_frontend_ops dtt200u_fe_ops = { +static const struct dvb_frontend_ops dtt200u_fe_ops = { .delsys = { SYS_DVBT }, .info = { .name = "WideView USB DVB-T", diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c index 979f05b4b87c..0251a4e91d47 100644 --- a/drivers/media/usb/dvb-usb/friio-fe.c +++ b/drivers/media/usb/dvb-usb/friio-fe.c @@ -401,7 +401,7 @@ static void jdvbt90502_release(struct dvb_frontend *fe) } -static struct dvb_frontend_ops jdvbt90502_ops; +static const struct dvb_frontend_ops jdvbt90502_ops; struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d) { @@ -432,7 +432,7 @@ error: return NULL; } -static struct dvb_frontend_ops jdvbt90502_ops = { +static const struct dvb_frontend_ops jdvbt90502_ops = { .delsys = { SYS_ISDBT }, .info = { .name = "Comtech JDVBT90502 ISDB-T", diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c index 27398c08c69d..7ff31baa3682 100644 --- a/drivers/media/usb/dvb-usb/vp702x-fe.c +++ b/drivers/media/usb/dvb-usb/vp702x-fe.c @@ -323,7 +323,7 @@ static void vp702x_fe_release(struct dvb_frontend* fe) kfree(st); } -static struct dvb_frontend_ops vp702x_fe_ops; +static const struct dvb_frontend_ops vp702x_fe_ops; struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) { @@ -345,7 +345,7 @@ error: } -static struct dvb_frontend_ops vp702x_fe_ops = { +static const struct dvb_frontend_ops vp702x_fe_ops = { .delsys = { SYS_DVBS }, .info = { .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S", diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c index 7765602ea658..4520ad9c2014 100644 --- a/drivers/media/usb/dvb-usb/vp7045-fe.c +++ b/drivers/media/usb/dvb-usb/vp7045-fe.c @@ -140,7 +140,7 @@ static void vp7045_fe_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops vp7045_fe_ops; +static const struct dvb_frontend_ops vp7045_fe_ops; struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) { @@ -158,7 +158,7 @@ error: } -static struct dvb_frontend_ops vp7045_fe_ops = { +static const struct dvb_frontend_ops vp7045_fe_ops = { .delsys = { SYS_DVBT }, .info = { .name = "Twinhan VP7045/46 USB DVB-T", diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c index 8781335ab92f..2d9444905fdb 100644 --- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c @@ -205,7 +205,7 @@ static void ttusbdecfe_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops ttusbdecfe_dvbt_ops; +static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops; struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config) { @@ -225,7 +225,7 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf return &state->frontend; } -static struct dvb_frontend_ops ttusbdecfe_dvbs_ops; +static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops; struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config) { @@ -247,7 +247,7 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf return &state->frontend; } -static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { +static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { .delsys = { SYS_DVBT }, .info = { .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", @@ -270,7 +270,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { .read_status = ttusbdecfe_dvbt_read_status, }; -static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { +static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { .delsys = { SYS_DVBS }, .info = { .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", -- cgit v1.2.3 From 1f4ed6cd58f36574237926f35bdec50116669909 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:11 -0300 Subject: [media] dvbdev: split dvb_unregister_device() dvb_unregister_device() has a major problem: it combines unregistering with memory disposal. Sometimes, it is necessary to unregister a device, but no memory can be freed yet, because a process still has a (stale) file handle. Therefore, we need to split dvb_unregister_device(). This will allow sanitizing a few callers. With my new design, dvb_unregister_device() appears misnamed, but to reduce patch noise, I'm not renaming it just yet. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 19 ++++++++++++++++++- drivers/media/dvb-core/dvbdev.h | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 0694d1d53c67..38c844667789 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -528,7 +528,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, EXPORT_SYMBOL(dvb_register_device); -void dvb_unregister_device(struct dvb_device *dvbdev) +void dvb_remove_device(struct dvb_device *dvbdev) { if (!dvbdev) return; @@ -542,9 +542,26 @@ void dvb_unregister_device(struct dvb_device *dvbdev) device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); list_del (&dvbdev->list_head); +} +EXPORT_SYMBOL(dvb_remove_device); + + +void dvb_free_device(struct dvb_device *dvbdev) +{ + if (!dvbdev) + return; + kfree (dvbdev->fops); kfree (dvbdev); } +EXPORT_SYMBOL(dvb_free_device); + + +void dvb_unregister_device(struct dvb_device *dvbdev) +{ + dvb_remove_device(dvbdev); + dvb_free_device(dvbdev); +} EXPORT_SYMBOL(dvb_unregister_device); diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 4aff7bd3dea8..576bbd4445b5 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -211,9 +211,32 @@ int dvb_register_device(struct dvb_adapter *adap, int type, int demux_sink_pads); +/** + * dvb_remove_device - Remove a registered DVB device + * + * This does not free memory. To do that, call dvb_free_device(). + * + * @dvbdev: pointer to struct dvb_device + */ +void dvb_remove_device(struct dvb_device *dvbdev); + +/** + * dvb_free_device - Free memory occupied by a DVB device. + * + * Call dvb_unregister_device() before calling this function. + * + * @dvbdev: pointer to struct dvb_device + */ +void dvb_free_device(struct dvb_device *dvbdev); + /** * dvb_unregister_device - Unregisters a DVB device * + * This is a combination of dvb_remove_device() and dvb_free_device(). + * Using this function is usually a mistake, and is often an indicator + * for a use-after-free bug (when a userspace process keeps a file + * handle to a detached device). + * * @dvbdev: pointer to struct dvb_device */ void dvb_unregister_device(struct dvb_device *dvbdev); -- cgit v1.2.3 From 4d5030b69bb4880a760406a6d3d519f02b9351dc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:16 -0300 Subject: [media] dvb-core/en50221: use dvb_remove_device() Commit da677fe14364 ("[media] dvb-core/en50221: use kref to manage struct dvb_ca_private") moved the dvb_unregister_device() call to the kref callback, but that left lots of stale device state visible to userspace (e.g. in sysfs). By using dvb_remove_device() and dvb_free_device() instead of dvb_unregister_device(), we can avoid that. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 262a492e7c08..fd893141211c 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -171,7 +171,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca) { unsigned int i; - dvb_unregister_device(ca->dvbdev); + dvb_free_device(ca->dvbdev); for (i = 0; i < ca->slot_count; i++) vfree(ca->slot_info[i].rx_buffer.data); @@ -1807,6 +1807,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) for (i = 0; i < ca->slot_count; i++) { dvb_ca_en50221_slot_shutdown(ca, i); } + dvb_remove_device(ca->dvbdev); dvb_ca_private_put(ca); pubca->private = NULL; } -- cgit v1.2.3 From 22a613e89825ea7a3984a968463cc6d425bd8856 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:26 -0300 Subject: [media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations Most release callback functions are identical: free the "tuner_priv" and clear it. Let's eliminate some bloat by providing this simple implementation in the dvb_frontend library. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 9 +++++++++ drivers/media/dvb-core/dvb_frontend.h | 7 +++++++ drivers/media/dvb-frontends/dib0070.c | 9 +-------- drivers/media/dvb-frontends/dib0090.c | 11 ++--------- drivers/media/dvb-frontends/dvb-pll.c | 9 +-------- drivers/media/dvb-frontends/itd1000.c | 9 +-------- drivers/media/dvb-frontends/ix2505v.c | 12 +----------- drivers/media/dvb-frontends/stb6000.c | 9 +-------- drivers/media/dvb-frontends/stb6100.c | 14 +------------- drivers/media/dvb-frontends/stv6110.c | 9 +-------- drivers/media/dvb-frontends/stv6110x.c | 12 +----------- drivers/media/dvb-frontends/tda18271c2dd.c | 10 +--------- drivers/media/dvb-frontends/tda665x.c | 11 +---------- drivers/media/dvb-frontends/tda8261.c | 11 +---------- drivers/media/dvb-frontends/tda826x.c | 9 +-------- drivers/media/dvb-frontends/tua6100.c | 9 +-------- drivers/media/dvb-frontends/zl10036.c | 12 +----------- drivers/media/tuners/fc0011.c | 10 +--------- drivers/media/tuners/fc0012.c | 9 +-------- drivers/media/tuners/fc0013.c | 9 +-------- drivers/media/tuners/mc44s803.c | 12 +----------- drivers/media/tuners/mt2060.c | 9 +-------- drivers/media/tuners/mt20xx.c | 12 ++---------- drivers/media/tuners/mt2266.c | 9 +-------- drivers/media/tuners/qt1010.c | 9 +-------- drivers/media/tuners/tda18218.c | 9 +-------- drivers/media/tuners/tda827x.c | 11 ++--------- drivers/media/tuners/tea5761.c | 10 +--------- drivers/media/tuners/tea5767.c | 10 +--------- 29 files changed, 46 insertions(+), 245 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index cdb7048874c5..7c4a50b0b963 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -174,6 +174,15 @@ static bool has_get_frontend(struct dvb_frontend *fe) return fe->ops.get_frontend != NULL; } +int +dvb_tuner_simple_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} +EXPORT_SYMBOL(dvb_tuner_simple_release); + /* * Due to DVBv3 API calls, a delivery system should be mapped into one of * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC), diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index fb6e84811504..6b675a833520 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -266,6 +266,13 @@ struct dvb_tuner_ops { int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); }; +/** + * A common default implementation for dvb_tuner_ops.release. All it + * does is kfree() the tuner_priv and assign NULL to it. + */ +int +dvb_tuner_simple_release(struct dvb_frontend *fe); + /** * struct analog_demod_info - Information struct for analog TV part of the demod * diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c index 016ad09a8754..d9f1bc2f778c 100644 --- a/drivers/media/dvb-frontends/dib0070.c +++ b/drivers/media/dvb-frontends/dib0070.c @@ -722,13 +722,6 @@ static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int dib0070_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static const struct dvb_tuner_ops dib0070_ops = { .info = { .name = "DiBcom DiB0070", @@ -736,7 +729,7 @@ static const struct dvb_tuner_ops dib0070_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dib0070_release, + .release = dvb_tuner_simple_release, .init = dib0070_wakeup, .sleep = dib0070_sleep, diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 16200582f089..7b4bee5c8e34 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -2526,13 +2526,6 @@ static int dib0090_tune(struct dvb_frontend *fe) return ret; } -static int dib0090_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; @@ -2594,7 +2587,7 @@ static const struct dvb_tuner_ops dib0090_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dib0090_release, + .release = dvb_tuner_simple_release, .init = dib0090_wakeup, .sleep = dib0090_sleep, @@ -2609,7 +2602,7 @@ static const struct dvb_tuner_ops dib0090_fw_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dib0090_release, + .release = dvb_tuner_simple_release, .init = NULL, .sleep = NULL, diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index b6d199196b83..56832d6f47ae 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -606,13 +606,6 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, return (div * desc->entries[i].stepsize) - desc->iffreq; } -static int dvb_pll_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int dvb_pll_sleep(struct dvb_frontend *fe) { struct dvb_pll_priv *priv = fe->tuner_priv; @@ -745,7 +738,7 @@ static int dvb_pll_init(struct dvb_frontend *fe) } static const struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_pll_release, + .release = dvb_tuner_simple_release, .sleep = dvb_pll_sleep, .init = dvb_pll_init, .set_params = dvb_pll_set_params, diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c index cadcae4cff89..d09f718f8119 100644 --- a/drivers/media/dvb-frontends/itd1000.c +++ b/drivers/media/dvb-frontends/itd1000.c @@ -348,13 +348,6 @@ static int itd1000_sleep(struct dvb_frontend *fe) return 0; } -static int itd1000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static const struct dvb_tuner_ops itd1000_tuner_ops = { .info = { .name = "Integrant ITD1000", @@ -363,7 +356,7 @@ static const struct dvb_tuner_ops itd1000_tuner_ops = { .frequency_step = 125, /* kHz for QPSK frontends */ }, - .release = itd1000_release, + .release = dvb_tuner_simple_release, .init = itd1000_init, .sleep = itd1000_sleep, diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c index 2826bbb36b73..7742a7a8cdbb 100644 --- a/drivers/media/dvb-frontends/ix2505v.c +++ b/drivers/media/dvb-frontends/ix2505v.c @@ -94,16 +94,6 @@ static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count) return 0; } -static int ix2505v_release(struct dvb_frontend *fe) -{ - struct ix2505v_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - /** * Data write format of the Sharp IX2505V B0017 * @@ -264,7 +254,7 @@ static const struct dvb_tuner_ops ix2505v_tuner_ops = { .frequency_min = 950000, .frequency_max = 2175000 }, - .release = ix2505v_release, + .release = dvb_tuner_simple_release, .set_params = ix2505v_set_params, .get_frequency = ix2505v_get_frequency, }; diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c index 73347d51f340..5252d485439e 100644 --- a/drivers/media/dvb-frontends/stb6000.c +++ b/drivers/media/dvb-frontends/stb6000.c @@ -41,13 +41,6 @@ struct stb6000_priv { u32 frequency; }; -static int stb6000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int stb6000_sleep(struct dvb_frontend *fe) { struct stb6000_priv *priv = fe->tuner_priv; @@ -192,7 +185,7 @@ static const struct dvb_tuner_ops stb6000_tuner_ops = { .frequency_min = 950000, .frequency_max = 2150000 }, - .release = stb6000_release, + .release = dvb_tuner_simple_release, .sleep = stb6000_sleep, .set_params = stb6000_set_params, .get_frequency = stb6000_get_frequency, diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c index 5add1182c3ca..befd26bdfa0f 100644 --- a/drivers/media/dvb-frontends/stb6100.c +++ b/drivers/media/dvb-frontends/stb6100.c @@ -61,8 +61,6 @@ struct stb6100_lkup { u8 reg; }; -static int stb6100_release(struct dvb_frontend *fe); - static const struct stb6100_lkup lkup[] = { { 0, 950000, 0x0a }, { 950000, 1000000, 0x0a }, @@ -536,7 +534,7 @@ static const struct dvb_tuner_ops stb6100_ops = { .set_params = stb6100_set_params, .get_frequency = stb6100_get_frequency, .get_bandwidth = stb6100_get_bandwidth, - .release = stb6100_release + .release = dvb_tuner_simple_release }; struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, @@ -560,16 +558,6 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, return fe; } -static int stb6100_release(struct dvb_frontend *fe) -{ - struct stb6100_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - EXPORT_SYMBOL(stb6100_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index 66a5a7f2295c..d9a88adc4c10 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c @@ -59,13 +59,6 @@ static s32 abssub(s32 a, s32 b) return b - a; }; -static int stv6110_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[], int start, int len) { @@ -390,7 +383,7 @@ static const struct dvb_tuner_ops stv6110_tuner_ops = { .frequency_step = 1000, }, .init = stv6110_init, - .release = stv6110_release, + .release = dvb_tuner_simple_release, .sleep = stv6110_sleep, .set_params = stv6110_set_params, .get_frequency = stv6110_get_frequency, diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index c611ad210b5c..70d5641453c2 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c @@ -335,16 +335,6 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) } -static int stv6110x_release(struct dvb_frontend *fe) -{ - struct stv6110x_state *stv6110x = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(stv6110x); - - return 0; -} - static const struct dvb_tuner_ops stv6110x_ops = { .info = { .name = "STV6110(A) Silicon Tuner", @@ -352,7 +342,7 @@ static const struct dvb_tuner_ops stv6110x_ops = { .frequency_max = 2150000, .frequency_step = 0, }, - .release = stv6110x_release + .release = dvb_tuner_simple_release, }; static const struct stv6110x_devctl stv6110x_ctl = { diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c index bc247f9b553a..a324f30f7224 100644 --- a/drivers/media/dvb-frontends/tda18271c2dd.c +++ b/drivers/media/dvb-frontends/tda18271c2dd.c @@ -1126,14 +1126,6 @@ static int init(struct dvb_frontend *fe) return 0; } -static int release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - - static int set_params(struct dvb_frontend *fe) { struct tda_state *state = fe->tuner_priv; @@ -1227,7 +1219,7 @@ static const struct dvb_tuner_ops tuner_ops = { .init = init, .sleep = sleep, .set_params = set_params, - .release = release, + .release = dvb_tuner_simple_release, .get_if_frequency = get_if_frequency, .get_bandwidth = get_bandwidth, }; diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c index 7ca965987f40..39a1eb23ad04 100644 --- a/drivers/media/dvb-frontends/tda665x.c +++ b/drivers/media/dvb-frontends/tda665x.c @@ -197,20 +197,11 @@ static int tda665x_set_params(struct dvb_frontend *fe) return 0; } -static int tda665x_release(struct dvb_frontend *fe) -{ - struct tda665x_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - static const struct dvb_tuner_ops tda665x_ops = { .get_status = tda665x_get_status, .set_params = tda665x_set_params, .get_frequency = tda665x_get_frequency, - .release = tda665x_release + .release = dvb_tuner_simple_release, }; struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c index e0df93191b9e..65f729ff27a9 100644 --- a/drivers/media/dvb-frontends/tda8261.c +++ b/drivers/media/dvb-frontends/tda8261.c @@ -152,15 +152,6 @@ static int tda8261_set_params(struct dvb_frontend *fe) return 0; } -static int tda8261_release(struct dvb_frontend *fe) -{ - struct tda8261_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - static const struct dvb_tuner_ops tda8261_ops = { .info = { @@ -173,7 +164,7 @@ static const struct dvb_tuner_ops tda8261_ops = { .set_params = tda8261_set_params, .get_frequency = tda8261_get_frequency, .get_status = tda8261_get_status, - .release = tda8261_release + .release = dvb_tuner_simple_release, }; struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c index 2ec671df1441..bf8946c2c04a 100644 --- a/drivers/media/dvb-frontends/tda826x.c +++ b/drivers/media/dvb-frontends/tda826x.c @@ -41,13 +41,6 @@ struct tda826x_priv { u32 frequency; }; -static int tda826x_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int tda826x_sleep(struct dvb_frontend *fe) { struct tda826x_priv *priv = fe->tuner_priv; @@ -135,7 +128,7 @@ static const struct dvb_tuner_ops tda826x_tuner_ops = { .frequency_min = 950000, .frequency_max = 2175000 }, - .release = tda826x_release, + .release = dvb_tuner_simple_release, .sleep = tda826x_sleep, .set_params = tda826x_set_params, .get_frequency = tda826x_get_frequency, diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c index 6da12b9e55eb..9e9a8ad7f37c 100644 --- a/drivers/media/dvb-frontends/tua6100.c +++ b/drivers/media/dvb-frontends/tua6100.c @@ -42,13 +42,6 @@ struct tua6100_priv { u32 frequency; }; -static int tua6100_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int tua6100_sleep(struct dvb_frontend *fe) { struct tua6100_priv *priv = fe->tuner_priv; @@ -164,7 +157,7 @@ static const struct dvb_tuner_ops tua6100_tuner_ops = { .frequency_max = 2150000, .frequency_step = 1000, }, - .release = tua6100_release, + .release = dvb_tuner_simple_release, .sleep = tua6100_sleep, .set_params = tua6100_set_params, .get_frequency = tua6100_get_frequency, diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c index df5d0fe24687..0116557c0f10 100644 --- a/drivers/media/dvb-frontends/zl10036.c +++ b/drivers/media/dvb-frontends/zl10036.c @@ -134,16 +134,6 @@ static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count) return 0; } -static int zl10036_release(struct dvb_frontend *fe) -{ - struct zl10036_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - static int zl10036_sleep(struct dvb_frontend *fe) { struct zl10036_state *state = fe->tuner_priv; @@ -453,7 +443,7 @@ static const struct dvb_tuner_ops zl10036_tuner_ops = { .frequency_max = 2175000 }, .init = zl10036_init, - .release = zl10036_release, + .release = dvb_tuner_simple_release, .sleep = zl10036_sleep, .set_params = zl10036_set_params, .get_frequency = zl10036_get_frequency, diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c index 2dda8d993c14..5e9e2e694f98 100644 --- a/drivers/media/tuners/fc0011.c +++ b/drivers/media/tuners/fc0011.c @@ -112,14 +112,6 @@ static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val) return 0; } -static int fc0011_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - - return 0; -} - static int fc0011_init(struct dvb_frontend *fe) { struct fc0011_priv *priv = fe->tuner_priv; @@ -483,7 +475,7 @@ static const struct dvb_tuner_ops fc0011_tuner_ops = { .frequency_max = 1000000000, }, - .release = fc0011_release, + .release = dvb_tuner_simple_release, .init = fc0011_init, .set_params = fc0011_set_params, diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index d74e92056810..7faff84e5ea8 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c @@ -55,13 +55,6 @@ static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val) return 0; } -static int fc0012_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int fc0012_init(struct dvb_frontend *fe) { struct fc0012_priv *priv = fe->tuner_priv; @@ -427,7 +420,7 @@ static const struct dvb_tuner_ops fc0012_tuner_ops = { .frequency_step = 0, }, - .release = fc0012_release, + .release = dvb_tuner_simple_release, .init = fc0012_init, diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index 522690d97b42..b068b9702cf7 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -52,13 +52,6 @@ static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val) return 0; } -static int fc0013_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int fc0013_init(struct dvb_frontend *fe) { struct fc0013_priv *priv = fe->tuner_priv; @@ -586,7 +579,7 @@ static const struct dvb_tuner_ops fc0013_tuner_ops = { .frequency_step = 0, }, - .release = fc0013_release, + .release = dvb_tuner_simple_release, .init = fc0013_init, .sleep = fc0013_sleep, diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c index d5681669d3cd..86542cbd73fb 100644 --- a/drivers/media/tuners/mc44s803.c +++ b/drivers/media/tuners/mc44s803.c @@ -80,16 +80,6 @@ static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val) return 0; } -static int mc44s803_release(struct dvb_frontend *fe) -{ - struct mc44s803_priv *priv = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(priv); - - return 0; -} - static int mc44s803_init(struct dvb_frontend *fe) { struct mc44s803_priv *priv = fe->tuner_priv; @@ -312,7 +302,7 @@ static const struct dvb_tuner_ops mc44s803_tuner_ops = { .frequency_step = 100000, }, - .release = mc44s803_release, + .release = dvb_tuner_simple_release, .init = mc44s803_init, .set_params = mc44s803_set_params, .get_frequency = mc44s803_get_frequency, diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c index b87b2549d58d..14e7b64360cb 100644 --- a/drivers/media/tuners/mt2060.c +++ b/drivers/media/tuners/mt2060.c @@ -332,13 +332,6 @@ static int mt2060_sleep(struct dvb_frontend *fe) return ret; } -static int mt2060_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static const struct dvb_tuner_ops mt2060_tuner_ops = { .info = { .name = "Microtune MT2060", @@ -347,7 +340,7 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = { .frequency_step = 50000, }, - .release = mt2060_release, + .release = dvb_tuner_simple_release, .init = mt2060_init, .sleep = mt2060_sleep, diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c index 29dadd171b31..4237d8f15919 100644 --- a/drivers/media/tuners/mt20xx.c +++ b/drivers/media/tuners/mt20xx.c @@ -49,14 +49,6 @@ struct microtune_priv { u32 frequency; }; -static int microtune_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - - return 0; -} - static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct microtune_priv *priv = fe->tuner_priv; @@ -365,7 +357,7 @@ static int mt2032_set_params(struct dvb_frontend *fe, static const struct dvb_tuner_ops mt2032_tuner_ops = { .set_analog_params = mt2032_set_params, - .release = microtune_release, + .release = dvb_tuner_simple_release, .get_frequency = microtune_get_frequency, }; @@ -560,7 +552,7 @@ static int mt2050_set_params(struct dvb_frontend *fe, static const struct dvb_tuner_ops mt2050_tuner_ops = { .set_analog_params = mt2050_set_params, - .release = microtune_release, + .release = dvb_tuner_simple_release, .get_frequency = microtune_get_frequency, }; diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c index bca4d75e42d4..35ea5e7975ac 100644 --- a/drivers/media/tuners/mt2266.c +++ b/drivers/media/tuners/mt2266.c @@ -296,13 +296,6 @@ static int mt2266_sleep(struct dvb_frontend *fe) return 0; } -static int mt2266_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static const struct dvb_tuner_ops mt2266_tuner_ops = { .info = { .name = "Microtune MT2266", @@ -310,7 +303,7 @@ static const struct dvb_tuner_ops mt2266_tuner_ops = { .frequency_max = 862000000, .frequency_step = 50000, }, - .release = mt2266_release, + .release = dvb_tuner_simple_release, .init = mt2266_init, .sleep = mt2266_sleep, .set_params = mt2266_set_params, diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c index ae8cbece6d2b..5a1662aeeb87 100644 --- a/drivers/media/tuners/qt1010.c +++ b/drivers/media/tuners/qt1010.c @@ -377,13 +377,6 @@ static int qt1010_init(struct dvb_frontend *fe) return qt1010_set_params(fe); } -static int qt1010_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct qt1010_priv *priv = fe->tuner_priv; @@ -405,7 +398,7 @@ static const struct dvb_tuner_ops qt1010_tuner_ops = { .frequency_step = QT1010_STEP, }, - .release = qt1010_release, + .release = dvb_tuner_simple_release, .init = qt1010_init, /* TODO: implement sleep */ diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c index 9300e9361e3b..4d2916fb9953 100644 --- a/drivers/media/tuners/tda18218.c +++ b/drivers/media/tuners/tda18218.c @@ -265,13 +265,6 @@ static int tda18218_init(struct dvb_frontend *fe) return ret; } -static int tda18218_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static const struct dvb_tuner_ops tda18218_tuner_ops = { .info = { .name = "NXP TDA18218", @@ -281,7 +274,7 @@ static const struct dvb_tuner_ops tda18218_tuner_ops = { .frequency_step = 1000, }, - .release = tda18218_release, + .release = dvb_tuner_simple_release, .init = tda18218_init, .sleep = tda18218_sleep, diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c index 5050ce9be423..4befb81f0c1a 100644 --- a/drivers/media/tuners/tda827x.c +++ b/drivers/media/tuners/tda827x.c @@ -767,13 +767,6 @@ static void tda827xa_agcf(struct dvb_frontend *fe) /* ------------------------------------------------------------------ */ -static int tda827x_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tda827x_priv *priv = fe->tuner_priv; @@ -825,7 +818,7 @@ static const struct dvb_tuner_ops tda827xo_tuner_ops = { .frequency_max = 860000000, .frequency_step = 250000 }, - .release = tda827x_release, + .release = dvb_tuner_simple_release, .init = tda827x_initial_init, .sleep = tda827x_initial_sleep, .set_params = tda827xo_set_params, @@ -841,7 +834,7 @@ static const struct dvb_tuner_ops tda827xa_tuner_ops = { .frequency_max = 906000000, .frequency_step = 62500 }, - .release = tda827x_release, + .release = dvb_tuner_simple_release, .init = tda827x_init, .sleep = tda827xa_sleep, .set_params = tda827xa_set_params, diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c index 12347aa95de3..82f25621d995 100644 --- a/drivers/media/tuners/tea5761.c +++ b/drivers/media/tuners/tea5761.c @@ -284,14 +284,6 @@ int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) return 0; } -static int tea5761_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - - return 0; -} - static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tea5761_priv *priv = fe->tuner_priv; @@ -305,7 +297,7 @@ static const struct dvb_tuner_ops tea5761_tuner_ops = { }, .set_analog_params = set_radio_freq, .sleep = set_radio_sleep, - .release = tea5761_release, + .release = dvb_tuner_simple_release, .get_frequency = tea5761_get_frequency, .get_status = tea5761_get_status, .get_rf_strength = tea5761_get_rf_strength, diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c index d62a6d6b1f42..a33c97de8b8a 100644 --- a/drivers/media/tuners/tea5767.c +++ b/drivers/media/tuners/tea5767.c @@ -401,14 +401,6 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) return 0; } -static int tea5767_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - - return 0; -} - static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tea5767_priv *priv = fe->tuner_priv; @@ -434,7 +426,7 @@ static const struct dvb_tuner_ops tea5767_tuner_ops = { .set_analog_params = set_radio_freq, .set_config = tea5767_set_config, .sleep = tea5767_standby, - .release = tea5767_release, + .release = dvb_tuner_simple_release, .get_frequency = tea5767_get_frequency, .get_status = tea5767_get_status, .get_rf_strength = tea5767_get_rf_strength, -- cgit v1.2.3 From 194ced7a5a99b303daf0bca6d0a1697731265602 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:31 -0300 Subject: [media] dvb_frontend: tuner_ops.release returns void It is not clear what this return value means. All implemenations return 0, and the one caller ignores the value. Let's remove this useless return value completely. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 3 +-- drivers/media/dvb-core/dvb_frontend.h | 4 ++-- drivers/media/dvb-frontends/ascot2e.c | 3 +-- drivers/media/dvb-frontends/cx24113.c | 3 +-- drivers/media/dvb-frontends/helene.c | 3 +-- drivers/media/dvb-frontends/horus3a.c | 3 +-- drivers/media/dvb-frontends/ts2020.c | 3 +-- drivers/media/dvb-frontends/zl10039.c | 3 +-- drivers/media/tuners/max2165.c | 4 +--- drivers/media/tuners/mt2063.c | 4 +--- drivers/media/tuners/mt2131.c | 3 +-- drivers/media/tuners/mxl5005s.c | 3 +-- drivers/media/tuners/mxl5007t.c | 4 +--- drivers/media/tuners/r820t.c | 4 +--- drivers/media/tuners/tda18271-fe.c | 4 +--- drivers/media/tuners/tuner-simple.c | 4 +--- drivers/media/tuners/tuner-xc2028.c | 4 +--- drivers/media/tuners/xc4000.c | 4 +--- drivers/media/tuners/xc5000.c | 4 +--- drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c | 3 +-- 20 files changed, 21 insertions(+), 49 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 7c4a50b0b963..023a7e4e6168 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -174,12 +174,11 @@ static bool has_get_frontend(struct dvb_frontend *fe) return fe->ops.get_frontend != NULL; } -int +void dvb_tuner_simple_release(struct dvb_frontend *fe) { kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } EXPORT_SYMBOL(dvb_tuner_simple_release); diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 6b675a833520..5bfb16bf188f 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -225,7 +225,7 @@ struct dvb_tuner_ops { struct dvb_tuner_info info; - int (*release)(struct dvb_frontend *fe); + void (*release)(struct dvb_frontend *fe); int (*init)(struct dvb_frontend *fe); int (*sleep)(struct dvb_frontend *fe); int (*suspend)(struct dvb_frontend *fe); @@ -270,7 +270,7 @@ struct dvb_tuner_ops { * A common default implementation for dvb_tuner_ops.release. All it * does is kfree() the tuner_priv and assign NULL to it. */ -int +void dvb_tuner_simple_release(struct dvb_frontend *fe); /** diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c index ad304eed656d..0ee0df53b91b 100644 --- a/drivers/media/dvb-frontends/ascot2e.c +++ b/drivers/media/dvb-frontends/ascot2e.c @@ -254,14 +254,13 @@ static int ascot2e_init(struct dvb_frontend *fe) return ascot2e_leave_power_save(priv); } -static int ascot2e_release(struct dvb_frontend *fe) +static void ascot2e_release(struct dvb_frontend *fe) { struct ascot2e_priv *priv = fe->tuner_priv; dev_dbg(&priv->i2c->dev, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } static int ascot2e_sleep(struct dvb_frontend *fe) diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c index 3812ef8cac08..db44ebb7c561 100644 --- a/drivers/media/dvb-frontends/cx24113.c +++ b/drivers/media/dvb-frontends/cx24113.c @@ -527,13 +527,12 @@ static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int cx24113_release(struct dvb_frontend *fe) +static void cx24113_release(struct dvb_frontend *fe) { struct cx24113_state *state = fe->tuner_priv; dprintk("\n"); fe->tuner_priv = NULL; kfree(state); - return 0; } static const struct dvb_tuner_ops cx24113_tuner_ops = { diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index dc43c5f6d0ea..ef35c2b30ea3 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c @@ -434,14 +434,13 @@ static int helene_init(struct dvb_frontend *fe) return helene_leave_power_save(priv); } -static int helene_release(struct dvb_frontend *fe) +static void helene_release(struct dvb_frontend *fe) { struct helene_priv *priv = fe->tuner_priv; dev_dbg(&priv->i2c->dev, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } static int helene_sleep(struct dvb_frontend *fe) diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c index 0c089b5986a1..94bb4f7a2298 100644 --- a/drivers/media/dvb-frontends/horus3a.c +++ b/drivers/media/dvb-frontends/horus3a.c @@ -151,14 +151,13 @@ static int horus3a_init(struct dvb_frontend *fe) return 0; } -static int horus3a_release(struct dvb_frontend *fe) +static void horus3a_release(struct dvb_frontend *fe) { struct horus3a_priv *priv = fe->tuner_priv; dev_dbg(&priv->i2c->dev, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } static int horus3a_sleep(struct dvb_frontend *fe) diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index a9f6bbea6df3..931e5c98da8a 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -56,7 +56,7 @@ struct ts2020_reg_val { static void ts2020_stat_work(struct work_struct *work); -static int ts2020_release(struct dvb_frontend *fe) +static void ts2020_release(struct dvb_frontend *fe) { struct ts2020_priv *priv = fe->tuner_priv; struct i2c_client *client = priv->client; @@ -64,7 +64,6 @@ static int ts2020_release(struct dvb_frontend *fe) dev_dbg(&client->dev, "\n"); i2c_unregister_device(client); - return 0; } static int ts2020_sleep(struct dvb_frontend *fe) diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c index d6ded11fee49..60a2954f8ff8 100644 --- a/drivers/media/dvb-frontends/zl10039.c +++ b/drivers/media/dvb-frontends/zl10039.c @@ -244,14 +244,13 @@ error: return ret; } -static int zl10039_release(struct dvb_frontend *fe) +static void zl10039_release(struct dvb_frontend *fe) { struct zl10039_state *state = fe->tuner_priv; dprintk("%s\n", __func__); kfree(state); fe->tuner_priv = NULL; - return 0; } static const struct dvb_tuner_ops zl10039_ops = { diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c index 353b178becf6..c3f10925b0d4 100644 --- a/drivers/media/tuners/max2165.c +++ b/drivers/media/tuners/max2165.c @@ -370,15 +370,13 @@ static int max2165_init(struct dvb_frontend *fe) return 0; } -static int max2165_release(struct dvb_frontend *fe) +static void max2165_release(struct dvb_frontend *fe) { struct max2165_priv *priv = fe->tuner_priv; dprintk("%s()\n", __func__); kfree(priv); fe->tuner_priv = NULL; - - return 0; } static const struct dvb_tuner_ops max2165_tuner_ops = { diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c index dfec23743afe..8b39d8dc97a0 100644 --- a/drivers/media/tuners/mt2063.c +++ b/drivers/media/tuners/mt2063.c @@ -2019,7 +2019,7 @@ static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status) return 0; } -static int mt2063_release(struct dvb_frontend *fe) +static void mt2063_release(struct dvb_frontend *fe) { struct mt2063_state *state = fe->tuner_priv; @@ -2027,8 +2027,6 @@ static int mt2063_release(struct dvb_frontend *fe) fe->tuner_priv = NULL; kfree(state); - - return 0; } static int mt2063_set_analog_params(struct dvb_frontend *fe, diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c index 6e2cdd2b6175..e7790e4afcfe 100644 --- a/drivers/media/tuners/mt2131.c +++ b/drivers/media/tuners/mt2131.c @@ -230,12 +230,11 @@ static int mt2131_init(struct dvb_frontend *fe) return ret; } -static int mt2131_release(struct dvb_frontend *fe) +static void mt2131_release(struct dvb_frontend *fe) { dprintk(1, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } static const struct dvb_tuner_ops mt2131_tuner_ops = { diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c index 92a3be4fde87..353744fee053 100644 --- a/drivers/media/tuners/mxl5005s.c +++ b/drivers/media/tuners/mxl5005s.c @@ -4063,12 +4063,11 @@ static int mxl5005s_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int mxl5005s_release(struct dvb_frontend *fe) +static void mxl5005s_release(struct dvb_frontend *fe) { dprintk(1, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } static const struct dvb_tuner_ops mxl5005s_tuner_ops = { diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c index 42569c6811e6..b16dfa5e85fb 100644 --- a/drivers/media/tuners/mxl5007t.c +++ b/drivers/media/tuners/mxl5007t.c @@ -776,7 +776,7 @@ static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int mxl5007t_release(struct dvb_frontend *fe) +static void mxl5007t_release(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; @@ -788,8 +788,6 @@ static int mxl5007t_release(struct dvb_frontend *fe) mutex_unlock(&mxl5007t_list_mutex); fe->tuner_priv = NULL; - - return 0; } /* ------------------------------------------------------------------------- */ diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index 08dca40356d2..ba80376a3b86 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c @@ -2286,7 +2286,7 @@ static int r820t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int r820t_release(struct dvb_frontend *fe) +static void r820t_release(struct dvb_frontend *fe) { struct r820t_priv *priv = fe->tuner_priv; @@ -2300,8 +2300,6 @@ static int r820t_release(struct dvb_frontend *fe) mutex_unlock(&r820t_list_mutex); fe->tuner_priv = NULL; - - return 0; } static const struct dvb_tuner_ops r820t_tuner_ops = { diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c index a4730610c0c6..b4e5fa2ff5e5 100644 --- a/drivers/media/tuners/tda18271-fe.c +++ b/drivers/media/tuners/tda18271-fe.c @@ -1048,7 +1048,7 @@ fail: return ret; } -static int tda18271_release(struct dvb_frontend *fe) +static void tda18271_release(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; @@ -1060,8 +1060,6 @@ static int tda18271_release(struct dvb_frontend *fe) mutex_unlock(&tda18271_list_mutex); fe->tuner_priv = NULL; - - return 0; } static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency) diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c index 315f45cd0778..3339b13dd3f5 100644 --- a/drivers/media/tuners/tuner-simple.c +++ b/drivers/media/tuners/tuner-simple.c @@ -1001,7 +1001,7 @@ static int simple_sleep(struct dvb_frontend *fe) return 0; } -static int simple_release(struct dvb_frontend *fe) +static void simple_release(struct dvb_frontend *fe) { struct tuner_simple_priv *priv = fe->tuner_priv; @@ -1013,8 +1013,6 @@ static int simple_release(struct dvb_frontend *fe) mutex_unlock(&tuner_simple_list_mutex); fe->tuner_priv = NULL; - - return 0; } static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency) diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index e07c5fb59cc6..1a9665404ada 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1321,7 +1321,7 @@ static int xc2028_sleep(struct dvb_frontend *fe) return rc; } -static int xc2028_dvb_release(struct dvb_frontend *fe) +static void xc2028_dvb_release(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; @@ -1342,8 +1342,6 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) mutex_unlock(&xc2028_list_mutex); fe->tuner_priv = NULL; - - return 0; } static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c index ac98dea985c8..03eef9b87a24 100644 --- a/drivers/media/tuners/xc4000.c +++ b/drivers/media/tuners/xc4000.c @@ -1618,7 +1618,7 @@ static int xc4000_init(struct dvb_frontend *fe) return 0; } -static int xc4000_release(struct dvb_frontend *fe) +static void xc4000_release(struct dvb_frontend *fe) { struct xc4000_priv *priv = fe->tuner_priv; @@ -1632,8 +1632,6 @@ static int xc4000_release(struct dvb_frontend *fe) mutex_unlock(&xc4000_list_mutex); fe->tuner_priv = NULL; - - return 0; } static const struct dvb_tuner_ops xc4000_tuner_ops = { diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index e6e5e90d8d95..796e7638b3b2 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -1326,7 +1326,7 @@ static int xc5000_init(struct dvb_frontend *fe) return 0; } -static int xc5000_release(struct dvb_frontend *fe) +static void xc5000_release(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; @@ -1346,8 +1346,6 @@ static int xc5000_release(struct dvb_frontend *fe) mutex_unlock(&xc5000_list_mutex); fe->tuner_priv = NULL; - - return 0; } static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg) diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c index f141dcc55cc9..f84bef6034dc 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c @@ -455,13 +455,12 @@ static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe, return 0; } -static int mxl111sf_tuner_release(struct dvb_frontend *fe) +static void mxl111sf_tuner_release(struct dvb_frontend *fe) { struct mxl111sf_tuner_state *state = fe->tuner_priv; mxl_dbg("()"); kfree(state); fe->tuner_priv = NULL; - return 0; } /* ------------------------------------------------------------------------- */ -- cgit v1.2.3 From 967d8e8f4caca396e6c4c8a8cf18765aa16cfdaf Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:36 -0300 Subject: [media] dvb_frontend: merge the two dvb_frontend_detach() versions This code duplication is confusing and error prone. Let's merge them by moving the release/dvb_detach call into one function with one Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 42 ++++++++++------------------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 023a7e4e6168..2465b0d7f43c 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2740,40 +2740,22 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) } EXPORT_SYMBOL(dvb_unregister_frontend); -#ifdef CONFIG_MEDIA_ATTACH -void dvb_frontend_detach(struct dvb_frontend* fe) +static void dvb_frontend_invoke_release(struct dvb_frontend *fe, + void (*release)(struct dvb_frontend *fe)) { - void *ptr; - - if (fe->ops.release_sec) { - fe->ops.release_sec(fe); - dvb_detach(fe->ops.release_sec); - } - if (fe->ops.tuner_ops.release) { - fe->ops.tuner_ops.release(fe); - dvb_detach(fe->ops.tuner_ops.release); - } - if (fe->ops.analog_ops.release) { - fe->ops.analog_ops.release(fe); - dvb_detach(fe->ops.analog_ops.release); - } - ptr = (void*)fe->ops.release; - if (ptr) { - fe->ops.release(fe); - dvb_detach(ptr); + if (release) { + release(fe); +#ifdef CONFIG_MEDIA_ATTACH + dvb_detach(release); +#endif } } -#else + void dvb_frontend_detach(struct dvb_frontend* fe) { - if (fe->ops.release_sec) - fe->ops.release_sec(fe); - if (fe->ops.tuner_ops.release) - fe->ops.tuner_ops.release(fe); - if (fe->ops.analog_ops.release) - fe->ops.analog_ops.release(fe); - if (fe->ops.release) - fe->ops.release(fe); + dvb_frontend_invoke_release(fe, fe->ops.release_sec); + dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release); + dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release); + dvb_frontend_invoke_release(fe, fe->ops.release); } -#endif EXPORT_SYMBOL(dvb_frontend_detach); -- cgit v1.2.3 From d812b3caea394a6c60e8d6a4ad46b941690435e3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:41 -0300 Subject: [media] dvb_frontend: add "detach" callback Prepare for making "release" asynchronous (via kref). Some operations may need to be run synchronously in dvb_frontend_detach(), and that's why we need a "detach" callback. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 1 + drivers/media/dvb-core/dvb_frontend.h | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2465b0d7f43c..667c5e7aaa3e 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2756,6 +2756,7 @@ void dvb_frontend_detach(struct dvb_frontend* fe) dvb_frontend_invoke_release(fe, fe->ops.release_sec); dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release); dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release); + dvb_frontend_invoke_release(fe, fe->ops.detach); dvb_frontend_invoke_release(fe, fe->ops.release); } EXPORT_SYMBOL(dvb_frontend_detach); diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 5bfb16bf188f..d5355718f365 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -330,7 +330,11 @@ struct dtv_frontend_properties; * * @info: embedded struct dvb_tuner_info with tuner properties * @delsys: Delivery systems supported by the frontend - * @release: callback function called when frontend is dettached. + * @detach: callback function called when frontend is detached. + * drivers should clean up, but not yet free the struct + * dvb_frontend allocation. + * @release: callback function called when frontend is ready to be + * freed. * drivers should free any allocated memory. * @release_sec: callback function requesting that the Satelite Equipment * Control (SEC) driver to release and free any memory @@ -415,6 +419,7 @@ struct dvb_frontend_ops { u8 delsys[MAX_DELSYS]; + void (*detach)(struct dvb_frontend *fe); void (*release)(struct dvb_frontend* fe); void (*release_sec)(struct dvb_frontend* fe); -- cgit v1.2.3 From f686c14364ade79a373ef65c0fecfc2953ca8da5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:46 -0300 Subject: [media] stb0899: move code to "detach" callback Ensure that STB0899_POSTPROC_GPIO_POWER is set synchronously. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stb0899_drv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index cc18891f9b45..02347598277a 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -601,13 +601,19 @@ static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) return 0; } -static void stb0899_release(struct dvb_frontend *fe) +static void stb0899_detach(struct dvb_frontend *fe) { struct stb0899_state *state = fe->demodulator_priv; - dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend"); /* post process event */ stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); +} + +static void stb0899_release(struct dvb_frontend *fe) +{ + struct stb0899_state *state = fe->demodulator_priv; + + dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend"); kfree(state); } @@ -1590,6 +1596,7 @@ static const struct dvb_frontend_ops stb0899_ops = { FE_CAN_QPSK }, + .detach = stb0899_detach, .release = stb0899_release, .init = stb0899_init, .sleep = stb0899_sleep, -- cgit v1.2.3 From 1f862a68df2449bc7b1cf78dce616891697b4bdf Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:32:51 -0300 Subject: [media] dvb_frontend: move kref to struct dvb_frontend This commit amends my old commit fe35637b0a9f ("[media] dvb_frontend: eliminate blocking wait in dvb_unregister_frontend()"), which added kref to struct dvb_frontend_private. It turned out that there are several use-after-free bugs left, which affect the struct dvb_frontend. Protecting it with kref also protects struct dvb_frontend_private, so we can simply move it. This is how the use-after-free looks like in KASAN: BUG: KASAN: use-after-free in string+0x60/0xb1 at addr ffff880033bd9fc0 Read of size 1 by task kworker/0:2/617 CPU: 0 PID: 617 Comm: kworker/0:2 Not tainted 4.8.0-rc1-hosting+ #60 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event 0000000000000000 ffff880033757218 ffffffff81394e50 ffff880033bd9fd0 ffff880035c03b00 ffff880033757240 ffffffff811f271d ffff880033bd9fc0 1ffff1000677b3f8 ffffed000677b3f8 ffff8800337572b8 ffffffff811f2afe Call Trace: [...] [] vsnprintf+0x39d/0x7e9 [] add_uevent_var+0x10f/0x1dc [] rc_dev_uevent+0x55/0x6f [] dev_uevent+0x2e1/0x316 [] kobject_uevent_env+0x27e/0x701 [] kobject_uevent+0xb/0xd [] device_del+0x322/0x383 [] rc_unregister_device+0x98/0xc3 [] dvb_usb_remote_exit+0x7a/0x90 [] dvb_usb_exit+0x1d/0xe5 [] dvb_usb_device_exit+0x69/0x7d [] pctv452e_usb_disconnect+0x7b/0x80 [...] Object at ffff880033bd9fc0, in cache kmalloc-16 size: 16 Allocated: [...] Freed: PID = 617 [...] [] kfree+0xd9/0x166 [] ir_free_table+0x2f/0x51 [] rc_unregister_device+0x4d/0xc3 [] dvb_usb_remote_exit+0x7a/0x90 [] dvb_usb_exit+0x1d/0xe5 [] dvb_usb_device_exit+0x69/0x7d [] pctv452e_usb_disconnect+0x7b/0x80 Another one: BUG: KASAN: use-after-free in do_sys_poll+0x336/0x6b8 at addr ffff88003563fcc0 Read of size 8 by task tuner on fronte/1042 CPU: 1 PID: 1042 Comm: tuner on fronte Tainted: G B 4.8.0-rc1-hosting+ #60 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 0000000000000000 ffff88003353f910 ffffffff81394e50 ffff88003563fd80 ffff880035c03200 ffff88003353f938 ffffffff811f271d ffff88003563fc80 1ffff10006ac7f98 ffffed0006ac7f98 ffff88003353f9b0 ffffffff811f2afe Call Trace: [...] [] do_sys_poll+0x336/0x6b8 [...] [] SyS_poll+0xa9/0x194 [...] Object at ffff88003563fc80, in cache kmalloc-256 size: 256 Allocated: [...] Freed: PID = 617 [...] [] kfree+0xd9/0x166 [] dvb_unregister_device+0xd6/0xe5 [] dvb_unregister_frontend+0x4b/0x66 [] dvb_usb_adapter_frontend_exit+0x69/0xac [] dvb_usb_exit+0x43/0xe5 [] dvb_usb_device_exit+0x69/0x7d [] pctv452e_usb_disconnect+0x7b/0x80 Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 46 +++++++++++++++++++++++------------ drivers/media/dvb-core/dvb_frontend.h | 1 + 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 667c5e7aaa3e..87f1346e1fec 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -104,8 +104,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to seconds on open( static DEFINE_MUTEX(frontend_mutex); struct dvb_frontend_private { - struct kref refcount; - /* thread/frontend values */ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters_out; @@ -143,21 +141,30 @@ struct dvb_frontend_private { #endif }; -static void dvb_frontend_private_free(struct kref *ref) +static void dvb_frontend_invoke_release(struct dvb_frontend *fe, + void (*release)(struct dvb_frontend *fe)); + +static void dvb_frontend_free(struct kref *ref) { - struct dvb_frontend_private *fepriv = - container_of(ref, struct dvb_frontend_private, refcount); + struct dvb_frontend *fe = + container_of(ref, struct dvb_frontend, refcount); + struct dvb_frontend_private *fepriv = fe->frontend_priv; + + dvb_free_device(fepriv->dvbdev); + + dvb_frontend_invoke_release(fe, fe->ops.release); + kfree(fepriv); } -static void dvb_frontend_private_put(struct dvb_frontend_private *fepriv) +static void dvb_frontend_put(struct dvb_frontend *fe) { - kref_put(&fepriv->refcount, dvb_frontend_private_free); + kref_put(&fe->refcount, dvb_frontend_free); } -static void dvb_frontend_private_get(struct dvb_frontend_private *fepriv) +static void dvb_frontend_get(struct dvb_frontend *fe) { - kref_get(&fepriv->refcount); + kref_get(&fe->refcount); } static void dvb_frontend_wakeup(struct dvb_frontend *fe); @@ -2555,7 +2562,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) fepriv->events.eventr = fepriv->events.eventw = 0; } - dvb_frontend_private_get(fepriv); + dvb_frontend_get(fe); if (adapter->mfe_shared) mutex_unlock (&adapter->mfe_lock); @@ -2605,7 +2612,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) fe->ops.ts_bus_ctrl(fe, 0); } - dvb_frontend_private_put(fepriv); + dvb_frontend_put(fe); return ret; } @@ -2695,7 +2702,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb, } fepriv = fe->frontend_priv; - kref_init(&fepriv->refcount); + kref_init(&fe->refcount); + + /* + * After initialization, there need to be two references: one + * for dvb_unregister_frontend(), and another one for + * dvb_frontend_detach(). + */ + dvb_frontend_get(fe); sema_init(&fepriv->sem, 1); init_waitqueue_head (&fepriv->wait_queue); @@ -2730,12 +2744,12 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) dev_dbg(fe->dvb->device, "%s:\n", __func__); mutex_lock(&frontend_mutex); - dvb_frontend_stop (fe); - dvb_unregister_device (fepriv->dvbdev); + dvb_frontend_stop(fe); + dvb_remove_device(fepriv->dvbdev); /* fe is invalid now */ mutex_unlock(&frontend_mutex); - dvb_frontend_private_put(fepriv); + dvb_frontend_put(fe); return 0; } EXPORT_SYMBOL(dvb_unregister_frontend); @@ -2757,6 +2771,6 @@ void dvb_frontend_detach(struct dvb_frontend* fe) dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release); dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release); dvb_frontend_invoke_release(fe, fe->ops.detach); - dvb_frontend_invoke_release(fe, fe->ops.release); + dvb_frontend_put(fe); } EXPORT_SYMBOL(dvb_frontend_detach); diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index d5355718f365..f21b255c61de 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -667,6 +667,7 @@ struct dtv_frontend_properties { */ struct dvb_frontend { + struct kref refcount; struct dvb_frontend_ops ops; struct dvb_adapter *dvb; void *demodulator_priv; -- cgit v1.2.3 From 6753743e11540b7fc54d03771458e2bd91ba411b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 23:32:57 +0200 Subject: [media] media-entity: clear media_gobj.mdev in _destroy() media_gobj_destroy() may be called twice on one instance - once by media_device_unregister() and again by dvb_media_device_free(). The function media_remove_intf_links() establishes and documents the convention that mdev==NULL means that the object is not registered, but nobody ever NULLs this variable. So this patch really implements this behavior, and adds another mdev==NULL check to media_gobj_destroy() to protect against double removal. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index c68239e60487..f9f723f5e4f0 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -205,10 +205,16 @@ void media_gobj_destroy(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj); + /* Do nothing if the object is not linked. */ + if (gobj->mdev == NULL) + return; + gobj->mdev->topology_version++; /* Remove the object from mdev list */ list_del(&gobj->list); + + gobj->mdev = NULL; } int media_entity_pads_init(struct media_entity *entity, u16 num_pads, -- cgit v1.2.3 From e7cd17a29d72868aa5cfbbd4de7c54a28ed30ff0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Aug 2016 18:33:03 -0300 Subject: [media] drivers/media/media-device: fix double free bug in _unregister() While removing all interfaces in media_device_unregister(), all media_interface pointers are freed. This is illegal and results in double kfree() if any media_interface is still linked at this point; maybe because a userspace process still has a file handle. Once the process closes the file handle, dvb_media_device_free() gets called, which frees the dvb_device.intf_devnode again. This patch removes the unnecessary kfree() call, and documents who's responsible for really freeing it. Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 2783531f9fc0..219ab5fc8b4c 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -801,9 +801,13 @@ void media_device_unregister(struct media_device *mdev) /* Remove all interfaces from the media device */ list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces, graph_obj.list) { + /* + * Unlink the interface, but don't free it here; the + * module which created it is responsible for freeing + * it + */ __media_remove_intf_links(intf); media_gobj_destroy(&intf->graph_obj); - kfree(intf); } mutex_unlock(&mdev->graph_mutex); -- cgit v1.2.3 From b24ccccaee5e6a73f461b1ca7bbb55d3dfc24a2d Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 Oct 2016 17:23:37 -0200 Subject: [media] media: rc: nuvoton: eliminate member pdev from struct nvt_dev Member pdev of struct nvt_dev is needed only to access &pdev->dev. We can get rid of this it by using rdev->dev.parent instead (both point to the same struct device). Setting rdev->dev.parent can be removed from the probe function as this is done by devm_rc_allocate_device now. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 27 ++++++++++++++------------- drivers/media/rc/nuvoton-cir.h | 1 - 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 3df3bd9aab7e..0705d51e4238 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -48,6 +48,11 @@ static const struct nvt_chip nvt_chips[] = { { "NCT6779D", NVT_6779D }, }; +static inline struct device *nvt_get_dev(const struct nvt_dev *nvt) +{ + return nvt->rdev->dev.parent; +} + static inline bool is_w83667hg(struct nvt_dev *nvt) { return nvt->chip_ver == NVT_W83667HG; @@ -385,6 +390,7 @@ static inline const char *nvt_find_chip(struct nvt_dev *nvt, int id) /* detect hardware features */ static int nvt_hw_detect(struct nvt_dev *nvt) { + struct device *dev = nvt_get_dev(nvt); const char *chip_name; int chip_id; @@ -405,8 +411,7 @@ static int nvt_hw_detect(struct nvt_dev *nvt) chip_id = nvt->chip_major << 8 | nvt->chip_minor; if (chip_id == NVT_INVALID) { - dev_err(&nvt->pdev->dev, - "No device found on either EFM port\n"); + dev_err(dev, "No device found on either EFM port\n"); return -ENODEV; } @@ -414,12 +419,11 @@ static int nvt_hw_detect(struct nvt_dev *nvt) /* warn, but still let the driver load, if we don't know this chip */ if (!chip_name) - dev_warn(&nvt->pdev->dev, + dev_warn(dev, "unknown chip, id: 0x%02x 0x%02x, it may not work...", nvt->chip_major, nvt->chip_minor); else - dev_info(&nvt->pdev->dev, - "found %s or compatible: chip id: 0x%02x 0x%02x", + dev_info(dev, "found %s or compatible: chip id: 0x%02x 0x%02x", chip_name, nvt->chip_major, nvt->chip_minor); return 0; @@ -616,7 +620,7 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) duration *= SAMPLE_PERIOD; if (!count || !duration) { - dev_notice(&nvt->pdev->dev, + dev_notice(nvt_get_dev(nvt), "Unable to determine carrier! (c:%u, d:%u)", count, duration); return 0; @@ -781,7 +785,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt) { - dev_warn(&nvt->pdev->dev, "RX FIFO overrun detected, flushing data!"); + dev_warn(nvt_get_dev(nvt), "RX FIFO overrun detected, flushing data!"); nvt->pkts = 0; nvt_clear_cir_fifo(nvt); @@ -1009,9 +1013,10 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) return -ENOMEM; /* input device for IR remote (and tx) */ - rdev = devm_rc_allocate_device(&pdev->dev); - if (!rdev) + nvt->rdev = devm_rc_allocate_device(&pdev->dev); + if (!nvt->rdev) return -ENOMEM; + rdev = nvt->rdev; /* activate pnp device */ ret = pnp_activate_dev(pdev); @@ -1050,7 +1055,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) spin_lock_init(&nvt->tx.lock); pnp_set_drvdata(pdev, nvt); - nvt->pdev = pdev; init_waitqueue_head(&nvt->tx.queue); @@ -1085,7 +1089,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2; rdev->input_id.product = nvt->chip_major; rdev->input_id.version = nvt->chip_minor; - rdev->dev.parent = &pdev->dev; rdev->driver_name = NVT_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; rdev->timeout = MS_TO_NS(100); @@ -1097,8 +1100,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* tx bits */ rdev->tx_resolution = XYZ; #endif - nvt->rdev = rdev; - ret = devm_rc_register_device(&pdev->dev, rdev); if (ret) return ret; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index acf735fc7170..77102a9b7d7b 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -78,7 +78,6 @@ struct nvt_chip { }; struct nvt_dev { - struct pnp_dev *pdev; struct rc_dev *rdev; spinlock_t nvt_lock; -- cgit v1.2.3 From f7ceec4fa0f40a1e21b738fa5a4997f99f62d1d1 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 Oct 2016 17:23:45 -0200 Subject: [media] media: rc: nuvoton: eliminate nvt->tx.lock Using a separate spinlock to protect access to substruct tx of struct nvt_dev doesn't provide any actual benefit. We can use spinlock nvt_lock to protect all access to struct nvt_dev and get rid of nvt->tx.lock. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 35 +++++++++-------------------------- drivers/media/rc/nuvoton-cir.h | 1 - 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 0705d51e4238..356f39953942 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -688,7 +688,7 @@ static int nvt_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned n) u8 iren; int ret; - spin_lock_irqsave(&nvt->tx.lock, flags); + spin_lock_irqsave(&nvt->nvt_lock, flags); ret = min((unsigned)(TX_BUF_LEN / sizeof(unsigned)), n); nvt->tx.buf_count = (ret * sizeof(unsigned)); @@ -712,13 +712,13 @@ static int nvt_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned n) for (i = 0; i < 9; i++) nvt_cir_reg_write(nvt, 0x01, CIR_STXFIFO); - spin_unlock_irqrestore(&nvt->tx.lock, flags); + spin_unlock_irqrestore(&nvt->nvt_lock, flags); wait_event(nvt->tx.queue, nvt->tx.tx_state == ST_TX_REQUEST); - spin_lock_irqsave(&nvt->tx.lock, flags); + spin_lock_irqsave(&nvt->nvt_lock, flags); nvt->tx.tx_state = ST_TX_NONE; - spin_unlock_irqrestore(&nvt->tx.lock, flags); + spin_unlock_irqrestore(&nvt->nvt_lock, flags); /* restore enabled interrupts to prior state */ nvt_cir_reg_write(nvt, iren, CIR_IREN); @@ -832,14 +832,7 @@ static void nvt_cir_log_irqs(u8 status, u8 iren) static bool nvt_cir_tx_inactive(struct nvt_dev *nvt) { - unsigned long flags; - u8 tx_state; - - spin_lock_irqsave(&nvt->tx.lock, flags); - tx_state = nvt->tx.tx_state; - spin_unlock_irqrestore(&nvt->tx.lock, flags); - - return tx_state == ST_TX_NONE; + return nvt->tx.tx_state == ST_TX_NONE; } /* interrupt service routine for incoming and outgoing CIR data */ @@ -902,8 +895,6 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) nvt_get_rx_ir_data(nvt); } - spin_unlock_irqrestore(&nvt->nvt_lock, flags); - if (status & CIR_IRSTS_TE) nvt_clear_tx_fifo(nvt); @@ -911,8 +902,6 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) unsigned int pos, count; u8 tmp; - spin_lock_irqsave(&nvt->tx.lock, flags); - pos = nvt->tx.cur_buf_num; count = nvt->tx.buf_count; @@ -925,20 +914,17 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) tmp = nvt_cir_reg_read(nvt, CIR_IREN); nvt_cir_reg_write(nvt, tmp & ~CIR_IREN_TTR, CIR_IREN); } - - spin_unlock_irqrestore(&nvt->tx.lock, flags); - } if (status & CIR_IRSTS_TFU) { - spin_lock_irqsave(&nvt->tx.lock, flags); if (nvt->tx.tx_state == ST_TX_REPLY) { nvt->tx.tx_state = ST_TX_REQUEST; wake_up(&nvt->tx.queue); } - spin_unlock_irqrestore(&nvt->tx.lock, flags); } + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + nvt_dbg_verbose("%s done", __func__); return IRQ_HANDLED; } @@ -1052,7 +1038,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) nvt->cr_efdr = CR_EFDR; spin_lock_init(&nvt->nvt_lock); - spin_lock_init(&nvt->tx.lock); pnp_set_drvdata(pdev, nvt); @@ -1152,12 +1137,10 @@ static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) nvt_dbg("%s called", __func__); - spin_lock_irqsave(&nvt->tx.lock, flags); - nvt->tx.tx_state = ST_TX_NONE; - spin_unlock_irqrestore(&nvt->tx.lock, flags); - spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->tx.tx_state = ST_TX_NONE; + /* disable all CIR interrupts */ nvt_cir_reg_write(nvt, 0, CIR_IREN); diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 77102a9b7d7b..a8569b66c214 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -87,7 +87,6 @@ struct nvt_dev { unsigned int pkts; struct { - spinlock_t lock; u8 buf[TX_BUF_LEN]; unsigned int buf_count; unsigned int cur_buf_num; -- cgit v1.2.3 From 73d4576d8ff4e418175c9b6e3059561ee0e46210 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 Oct 2016 17:23:49 -0200 Subject: [media] media: rc: nuvoton: rename spinlock nvt_lock Spinlock nvt_lock is a member of struct nvt_dev and there's no need to prefix it with nvt_. So remove this prefix. [mchehab@s-opensource.org: change the prefix also at the open function, as the patch removing it were not applied (yet?)] Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 44 +++++++++++++++++++++--------------------- drivers/media/rc/nuvoton-cir.h | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 356f39953942..c335de4ca4b5 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -187,7 +187,7 @@ static ssize_t wakeup_data_show(struct device *dev, ssize_t buf_len = 0; int i; - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT); fifo_len = min(fifo_len, WAKEUP_MAX_SIZE); @@ -204,7 +204,7 @@ static ssize_t wakeup_data_show(struct device *dev, } buf_len += snprintf(buf + buf_len, PAGE_SIZE - buf_len, "\n"); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); return buf_len; } @@ -248,7 +248,7 @@ static ssize_t wakeup_data_store(struct device *dev, /* hardcode the tolerance to 10% */ tolerance = DIV_ROUND_UP(count, 10); - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); nvt_clear_cir_wake_fifo(nvt); nvt_cir_wake_reg_write(nvt, count, CIR_WAKE_FIFO_CMP_DEEP); @@ -265,7 +265,7 @@ static ssize_t wakeup_data_store(struct device *dev, nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); ret = len; out: @@ -590,7 +590,7 @@ static void nvt_enable_wake(struct nvt_dev *nvt) nvt_efm_disable(nvt); - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | @@ -599,11 +599,11 @@ static void nvt_enable_wake(struct nvt_dev *nvt) nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); } #if 0 /* Currently unused */ -/* rx carrier detect only works in learning mode, must be called w/nvt_lock */ +/* rx carrier detect only works in learning mode, must be called w/lock */ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) { u32 count, carrier, duration = 0; @@ -688,7 +688,7 @@ static int nvt_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned n) u8 iren; int ret; - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); ret = min((unsigned)(TX_BUF_LEN / sizeof(unsigned)), n); nvt->tx.buf_count = (ret * sizeof(unsigned)); @@ -712,13 +712,13 @@ static int nvt_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned n) for (i = 0; i < 9; i++) nvt_cir_reg_write(nvt, 0x01, CIR_STXFIFO); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); wait_event(nvt->tx.queue, nvt->tx.tx_state == ST_TX_REQUEST); - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); nvt->tx.tx_state = ST_TX_NONE; - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); /* restore enabled interrupts to prior state */ nvt_cir_reg_write(nvt, iren, CIR_IREN); @@ -844,7 +844,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) nvt_dbg_verbose("%s firing", __func__); - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); /* * Get IR Status register contents. Write 1 to ack/clear @@ -866,7 +866,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) * logical device is being disabled. */ if (status == 0xff && iren == 0xff) { - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); nvt_dbg_verbose("Spurious interrupt detected"); return IRQ_HANDLED; } @@ -875,7 +875,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) * status bit whether the related interrupt source is enabled */ if (!(status & iren)) { - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__); return IRQ_NONE; } @@ -923,7 +923,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) } } - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); nvt_dbg_verbose("%s done", __func__); return IRQ_HANDLED; @@ -933,7 +933,7 @@ static void nvt_disable_cir(struct nvt_dev *nvt) { unsigned long flags; - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); /* disable CIR interrupts */ nvt_cir_reg_write(nvt, 0, CIR_IREN); @@ -948,7 +948,7 @@ static void nvt_disable_cir(struct nvt_dev *nvt) nvt_clear_cir_fifo(nvt); nvt_clear_tx_fifo(nvt); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); /* disable the CIR logical device */ nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR); @@ -959,7 +959,7 @@ static int nvt_open(struct rc_dev *dev) struct nvt_dev *nvt = dev->priv; unsigned long flags; - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); /* set function enable flags */ nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN | @@ -972,7 +972,7 @@ static int nvt_open(struct rc_dev *dev) /* enable interrupts */ nvt_set_cir_iren(nvt); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); /* enable the CIR logical device */ nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR); @@ -1037,7 +1037,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) nvt->cr_efir = CR_EFIR; nvt->cr_efdr = CR_EFDR; - spin_lock_init(&nvt->nvt_lock); + spin_lock_init(&nvt->lock); pnp_set_drvdata(pdev, nvt); @@ -1137,14 +1137,14 @@ static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) nvt_dbg("%s called", __func__); - spin_lock_irqsave(&nvt->nvt_lock, flags); + spin_lock_irqsave(&nvt->lock, flags); nvt->tx.tx_state = ST_TX_NONE; /* disable all CIR interrupts */ nvt_cir_reg_write(nvt, 0, CIR_IREN); - spin_unlock_irqrestore(&nvt->nvt_lock, flags); + spin_unlock_irqrestore(&nvt->lock, flags); /* disable cir logical dev */ nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR); diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index a8569b66c214..c41c5765e1d2 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -80,7 +80,7 @@ struct nvt_chip { struct nvt_dev { struct rc_dev *rdev; - spinlock_t nvt_lock; + spinlock_t lock; /* for rx */ u8 buf[RX_BUF_LEN]; -- cgit v1.2.3 From c044170fcfca3783f7dd8eb69ff8b06d66fad5d8 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 Oct 2016 17:23:52 -0200 Subject: [media] media: rc: nuvoton: replace usage of spin_lock_irqsave in ISR Kernel takes care that interrupts from one source are serialized. So there's no need to use spinlock_irq_save. Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index c335de4ca4b5..4b78c891eb77 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -840,11 +840,10 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) { struct nvt_dev *nvt = data; u8 status, iren; - unsigned long flags; nvt_dbg_verbose("%s firing", __func__); - spin_lock_irqsave(&nvt->lock, flags); + spin_lock(&nvt->lock); /* * Get IR Status register contents. Write 1 to ack/clear @@ -866,7 +865,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) * logical device is being disabled. */ if (status == 0xff && iren == 0xff) { - spin_unlock_irqrestore(&nvt->lock, flags); + spin_unlock(&nvt->lock); nvt_dbg_verbose("Spurious interrupt detected"); return IRQ_HANDLED; } @@ -875,7 +874,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) * status bit whether the related interrupt source is enabled */ if (!(status & iren)) { - spin_unlock_irqrestore(&nvt->lock, flags); + spin_unlock(&nvt->lock); nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__); return IRQ_NONE; } @@ -923,7 +922,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) } } - spin_unlock_irqrestore(&nvt->lock, flags); + spin_unlock(&nvt->lock); nvt_dbg_verbose("%s done", __func__); return IRQ_HANDLED; -- cgit v1.2.3 From a4afb3ed430af793702c32ff2e68613263291e81 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 18 Nov 2016 17:47:41 -0200 Subject: [media] Kconfig: fix breakages when DVB_CORE is not selected On some weird randconfigs, it is possible to select DVB drivers, without having the DVB_CORE: CONFIG_DVB_AU8522=m CONFIG_DVB_AU8522_V4L=m CONFIG_DVB_TUNER_DIB0090=m This was never supposed to work, but changeset 22a613e89825 ("[media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations") caused it to be exposed: drivers/built-in.o: In function `fc0011_attach': (.text+0x1598fb): undefined reference to `dvb_tuner_simple_release' drivers/built-in.o:(.rodata+0x55e58): undefined reference to `dvb_tuner_simple_release' drivers/built-in.o:(.rodata+0x57398): undefined reference to `dvb_tuner_simple_release' Fixes: 22a613e89825 ("[media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations") Reported-by: kbuild test robot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 2 +- drivers/media/dvb-frontends/Kconfig | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index bc643cbf813e..3512316e7a46 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -115,7 +115,7 @@ config MEDIA_CONTROLLER config MEDIA_CONTROLLER_DVB bool "Enable Media controller for DVB (EXPERIMENTAL)" - depends on MEDIA_CONTROLLER + depends on MEDIA_CONTROLLER && DVB_CORE ---help--- Enable the media controller API support for DVB. diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index b71b747ee0ba..c841fa1770be 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -642,7 +642,7 @@ config DVB_S5H1409 to support this frontend. config DVB_AU8522 - depends on I2C + depends on DVB_CORE && I2C tristate config DVB_AU8522_DTV @@ -656,7 +656,7 @@ config DVB_AU8522_DTV config DVB_AU8522_V4L tristate "Auvitek AU8522 based ATV demod" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L2 && DVB_CORE && I2C select DVB_AU8522 default m if !MEDIA_SUBDRV_AUTOSELECT help @@ -722,7 +722,7 @@ config DVB_PLL config DVB_TUNER_DIB0070 tristate "DiBcom DiB0070 silicon base-band tuner" - depends on I2C + depends on DVB_CORE && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help A driver for the silicon baseband tuner DiB0070 from DiBcom. @@ -731,7 +731,7 @@ config DVB_TUNER_DIB0070 config DVB_TUNER_DIB0090 tristate "DiBcom DiB0090 silicon base-band tuner" - depends on I2C + depends on DVB_CORE && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help A driver for the silicon baseband tuner DiB0090 from DiBcom. @@ -879,5 +879,6 @@ comment "Tools to develop new frontends" config DVB_DUMMY_FE tristate "Dummy frontend driver" + depends on DVB_CORE default n endmenu -- cgit v1.2.3 From f2709c206d8a3e11729e68d80c57e7470bbe8e5e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 18 Nov 2016 20:30:51 -0200 Subject: Revert "[media] dvb_frontend: merge duplicate dvb_tuner_ops.release implementations" While this patch sounded a good idea, unfortunately, it causes bad dependencies, as drivers that would otherwise work without the DVB core will now break: ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tea5767.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tea5761.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tda827x.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/tda18218.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/qt1010.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mt2266.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mt20xx.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mt2060.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/mc44s803.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/fc0013.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/fc0012.ko] undefined! ERROR: "dvb_tuner_simple_release" [drivers/media/tuners/fc0011.ko] undefined! So, we have to revert it. Note: as the argument for the release ops changed from "int" to "void", we needed to change it at the revert patch, to avoid compilation issues like: drivers/media/tuners/tea5767.c:437:23: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .release = tea5767_release, ^~~~~~~~~~~~~~~ This reverts commit 22a613e89825ea7a3984a968463cc6d425bd8856. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 8 -------- drivers/media/dvb-core/dvb_frontend.h | 7 ------- drivers/media/dvb-frontends/dib0070.c | 8 +++++++- drivers/media/dvb-frontends/dib0090.c | 10 ++++++++-- drivers/media/dvb-frontends/dvb-pll.c | 8 +++++++- drivers/media/dvb-frontends/itd1000.c | 8 +++++++- drivers/media/dvb-frontends/ix2505v.c | 11 ++++++++++- drivers/media/dvb-frontends/stb6000.c | 8 +++++++- drivers/media/dvb-frontends/stb6100.c | 12 +++++++++++- drivers/media/dvb-frontends/stv6110.c | 8 +++++++- drivers/media/dvb-frontends/stv6110x.c | 10 +++++++++- drivers/media/dvb-frontends/tda18271c2dd.c | 9 ++++++++- drivers/media/dvb-frontends/tda665x.c | 10 +++++++++- drivers/media/dvb-frontends/tda8261.c | 10 +++++++++- drivers/media/dvb-frontends/tda826x.c | 8 +++++++- drivers/media/dvb-frontends/tua6100.c | 8 +++++++- drivers/media/dvb-frontends/zl10036.c | 10 +++++++++- drivers/media/tuners/fc0011.c | 8 +++++++- drivers/media/tuners/fc0012.c | 8 +++++++- drivers/media/tuners/fc0013.c | 8 +++++++- drivers/media/tuners/mc44s803.c | 10 +++++++++- drivers/media/tuners/mt2060.c | 8 +++++++- drivers/media/tuners/mt20xx.c | 10 ++++++++-- drivers/media/tuners/mt2266.c | 8 +++++++- drivers/media/tuners/qt1010.c | 8 +++++++- drivers/media/tuners/tda18218.c | 8 +++++++- drivers/media/tuners/tda827x.c | 10 ++++++++-- drivers/media/tuners/tea5761.c | 8 +++++++- drivers/media/tuners/tea5767.c | 8 +++++++- 29 files changed, 210 insertions(+), 45 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 87f1346e1fec..db74cb74d271 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -181,14 +181,6 @@ static bool has_get_frontend(struct dvb_frontend *fe) return fe->ops.get_frontend != NULL; } -void -dvb_tuner_simple_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; -} -EXPORT_SYMBOL(dvb_tuner_simple_release); - /* * Due to DVBv3 API calls, a delivery system should be mapped into one of * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC), diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index f21b255c61de..482912d3b77a 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -266,13 +266,6 @@ struct dvb_tuner_ops { int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); }; -/** - * A common default implementation for dvb_tuner_ops.release. All it - * does is kfree() the tuner_priv and assign NULL to it. - */ -void -dvb_tuner_simple_release(struct dvb_frontend *fe); - /** * struct analog_demod_info - Information struct for analog TV part of the demod * diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c index d9f1bc2f778c..befc8172159d 100644 --- a/drivers/media/dvb-frontends/dib0070.c +++ b/drivers/media/dvb-frontends/dib0070.c @@ -722,6 +722,12 @@ static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } +static void dib0070_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static const struct dvb_tuner_ops dib0070_ops = { .info = { .name = "DiBcom DiB0070", @@ -729,7 +735,7 @@ static const struct dvb_tuner_ops dib0070_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dvb_tuner_simple_release, + .release = dib0070_release, .init = dib0070_wakeup, .sleep = dib0070_sleep, diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 7b4bee5c8e34..fd3b33296b15 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -2526,6 +2526,12 @@ static int dib0090_tune(struct dvb_frontend *fe) return ret; } +static void dib0090_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; @@ -2587,7 +2593,7 @@ static const struct dvb_tuner_ops dib0090_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dvb_tuner_simple_release, + .release = dib0090_release, .init = dib0090_wakeup, .sleep = dib0090_sleep, @@ -2602,7 +2608,7 @@ static const struct dvb_tuner_ops dib0090_fw_ops = { .frequency_max = 860000000, .frequency_step = 1000, }, - .release = dvb_tuner_simple_release, + .release = dib0090_release, .init = NULL, .sleep = NULL, diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 56832d6f47ae..ef976eb23344 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -606,6 +606,12 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, return (div * desc->entries[i].stepsize) - desc->iffreq; } +static void dvb_pll_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int dvb_pll_sleep(struct dvb_frontend *fe) { struct dvb_pll_priv *priv = fe->tuner_priv; @@ -738,7 +744,7 @@ static int dvb_pll_init(struct dvb_frontend *fe) } static const struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_tuner_simple_release, + .release = dvb_pll_release, .sleep = dvb_pll_sleep, .init = dvb_pll_init, .set_params = dvb_pll_set_params, diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c index d09f718f8119..475525134327 100644 --- a/drivers/media/dvb-frontends/itd1000.c +++ b/drivers/media/dvb-frontends/itd1000.c @@ -348,6 +348,12 @@ static int itd1000_sleep(struct dvb_frontend *fe) return 0; } +static void itd1000_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static const struct dvb_tuner_ops itd1000_tuner_ops = { .info = { .name = "Integrant ITD1000", @@ -356,7 +362,7 @@ static const struct dvb_tuner_ops itd1000_tuner_ops = { .frequency_step = 125, /* kHz for QPSK frontends */ }, - .release = dvb_tuner_simple_release, + .release = itd1000_release, .init = itd1000_init, .sleep = itd1000_sleep, diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c index 7742a7a8cdbb..ca371680a69f 100644 --- a/drivers/media/dvb-frontends/ix2505v.c +++ b/drivers/media/dvb-frontends/ix2505v.c @@ -94,6 +94,15 @@ static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count) return 0; } +static void ix2505v_release(struct dvb_frontend *fe) +{ + struct ix2505v_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); + +} + /** * Data write format of the Sharp IX2505V B0017 * @@ -254,7 +263,7 @@ static const struct dvb_tuner_ops ix2505v_tuner_ops = { .frequency_min = 950000, .frequency_max = 2175000 }, - .release = dvb_tuner_simple_release, + .release = ix2505v_release, .set_params = ix2505v_set_params, .get_frequency = ix2505v_get_frequency, }; diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c index 5252d485439e..69c03892f2da 100644 --- a/drivers/media/dvb-frontends/stb6000.c +++ b/drivers/media/dvb-frontends/stb6000.c @@ -41,6 +41,12 @@ struct stb6000_priv { u32 frequency; }; +static void stb6000_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int stb6000_sleep(struct dvb_frontend *fe) { struct stb6000_priv *priv = fe->tuner_priv; @@ -185,7 +191,7 @@ static const struct dvb_tuner_ops stb6000_tuner_ops = { .frequency_min = 950000, .frequency_max = 2150000 }, - .release = dvb_tuner_simple_release, + .release = stb6000_release, .sleep = stb6000_sleep, .set_params = stb6000_set_params, .get_frequency = stb6000_get_frequency, diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c index befd26bdfa0f..17a955d0031b 100644 --- a/drivers/media/dvb-frontends/stb6100.c +++ b/drivers/media/dvb-frontends/stb6100.c @@ -61,6 +61,8 @@ struct stb6100_lkup { u8 reg; }; +static void stb6100_release(struct dvb_frontend *fe); + static const struct stb6100_lkup lkup[] = { { 0, 950000, 0x0a }, { 950000, 1000000, 0x0a }, @@ -534,7 +536,7 @@ static const struct dvb_tuner_ops stb6100_ops = { .set_params = stb6100_set_params, .get_frequency = stb6100_get_frequency, .get_bandwidth = stb6100_get_bandwidth, - .release = dvb_tuner_simple_release + .release = stb6100_release }; struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, @@ -558,6 +560,14 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, return fe; } +static void stb6100_release(struct dvb_frontend *fe) +{ + struct stb6100_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); +} + EXPORT_SYMBOL(stb6100_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index d9a88adc4c10..6a72d0be2ec5 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c @@ -59,6 +59,12 @@ static s32 abssub(s32 a, s32 b) return b - a; }; +static void stv6110_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[], int start, int len) { @@ -383,7 +389,7 @@ static const struct dvb_tuner_ops stv6110_tuner_ops = { .frequency_step = 1000, }, .init = stv6110_init, - .release = dvb_tuner_simple_release, + .release = stv6110_release, .sleep = stv6110_sleep, .set_params = stv6110_set_params, .get_frequency = stv6110_get_frequency, diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index 70d5641453c2..66eba38f1014 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c @@ -335,6 +335,14 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) } +static void stv6110x_release(struct dvb_frontend *fe) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(stv6110x); +} + static const struct dvb_tuner_ops stv6110x_ops = { .info = { .name = "STV6110(A) Silicon Tuner", @@ -342,7 +350,7 @@ static const struct dvb_tuner_ops stv6110x_ops = { .frequency_max = 2150000, .frequency_step = 0, }, - .release = dvb_tuner_simple_release, + .release = stv6110x_release }; static const struct stv6110x_devctl stv6110x_ctl = { diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c index a324f30f7224..6859fa5d5a85 100644 --- a/drivers/media/dvb-frontends/tda18271c2dd.c +++ b/drivers/media/dvb-frontends/tda18271c2dd.c @@ -1126,6 +1126,13 @@ static int init(struct dvb_frontend *fe) return 0; } +static void release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + + static int set_params(struct dvb_frontend *fe) { struct tda_state *state = fe->tuner_priv; @@ -1219,7 +1226,7 @@ static const struct dvb_tuner_ops tuner_ops = { .init = init, .sleep = sleep, .set_params = set_params, - .release = dvb_tuner_simple_release, + .release = release, .get_if_frequency = get_if_frequency, .get_bandwidth = get_bandwidth, }; diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c index 39a1eb23ad04..a63dec44295b 100644 --- a/drivers/media/dvb-frontends/tda665x.c +++ b/drivers/media/dvb-frontends/tda665x.c @@ -197,11 +197,19 @@ static int tda665x_set_params(struct dvb_frontend *fe) return 0; } +static void tda665x_release(struct dvb_frontend *fe) +{ + struct tda665x_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); +} + static const struct dvb_tuner_ops tda665x_ops = { .get_status = tda665x_get_status, .set_params = tda665x_set_params, .get_frequency = tda665x_get_frequency, - .release = dvb_tuner_simple_release, + .release = tda665x_release }; struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c index 65f729ff27a9..4eb294f330bc 100644 --- a/drivers/media/dvb-frontends/tda8261.c +++ b/drivers/media/dvb-frontends/tda8261.c @@ -152,6 +152,14 @@ static int tda8261_set_params(struct dvb_frontend *fe) return 0; } +static void tda8261_release(struct dvb_frontend *fe) +{ + struct tda8261_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); +} + static const struct dvb_tuner_ops tda8261_ops = { .info = { @@ -164,7 +172,7 @@ static const struct dvb_tuner_ops tda8261_ops = { .set_params = tda8261_set_params, .get_frequency = tda8261_get_frequency, .get_status = tda8261_get_status, - .release = dvb_tuner_simple_release, + .release = tda8261_release }; struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c index bf8946c2c04a..da427b4c2aaa 100644 --- a/drivers/media/dvb-frontends/tda826x.c +++ b/drivers/media/dvb-frontends/tda826x.c @@ -41,6 +41,12 @@ struct tda826x_priv { u32 frequency; }; +static void tda826x_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int tda826x_sleep(struct dvb_frontend *fe) { struct tda826x_priv *priv = fe->tuner_priv; @@ -128,7 +134,7 @@ static const struct dvb_tuner_ops tda826x_tuner_ops = { .frequency_min = 950000, .frequency_max = 2175000 }, - .release = dvb_tuner_simple_release, + .release = tda826x_release, .sleep = tda826x_sleep, .set_params = tda826x_set_params, .get_frequency = tda826x_get_frequency, diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c index 9e9a8ad7f37c..05ee16d29851 100644 --- a/drivers/media/dvb-frontends/tua6100.c +++ b/drivers/media/dvb-frontends/tua6100.c @@ -42,6 +42,12 @@ struct tua6100_priv { u32 frequency; }; +static void tua6100_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int tua6100_sleep(struct dvb_frontend *fe) { struct tua6100_priv *priv = fe->tuner_priv; @@ -157,7 +163,7 @@ static const struct dvb_tuner_ops tua6100_tuner_ops = { .frequency_max = 2150000, .frequency_step = 1000, }, - .release = dvb_tuner_simple_release, + .release = tua6100_release, .sleep = tua6100_sleep, .set_params = tua6100_set_params, .get_frequency = tua6100_get_frequency, diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c index 0116557c0f10..a6d020fe9b8b 100644 --- a/drivers/media/dvb-frontends/zl10036.c +++ b/drivers/media/dvb-frontends/zl10036.c @@ -134,6 +134,14 @@ static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count) return 0; } +static void zl10036_release(struct dvb_frontend *fe) +{ + struct zl10036_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); +} + static int zl10036_sleep(struct dvb_frontend *fe) { struct zl10036_state *state = fe->tuner_priv; @@ -443,7 +451,7 @@ static const struct dvb_tuner_ops zl10036_tuner_ops = { .frequency_max = 2175000 }, .init = zl10036_init, - .release = dvb_tuner_simple_release, + .release = zl10036_release, .sleep = zl10036_sleep, .set_params = zl10036_set_params, .get_frequency = zl10036_get_frequency, diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c index 5e9e2e694f98..00489a9df4e4 100644 --- a/drivers/media/tuners/fc0011.c +++ b/drivers/media/tuners/fc0011.c @@ -112,6 +112,12 @@ static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val) return 0; } +static void fc0011_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int fc0011_init(struct dvb_frontend *fe) { struct fc0011_priv *priv = fe->tuner_priv; @@ -475,7 +481,7 @@ static const struct dvb_tuner_ops fc0011_tuner_ops = { .frequency_max = 1000000000, }, - .release = dvb_tuner_simple_release, + .release = fc0011_release, .init = fc0011_init, .set_params = fc0011_set_params, diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index 7faff84e5ea8..30508f44e5f9 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c @@ -55,6 +55,12 @@ static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val) return 0; } +static void fc0012_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int fc0012_init(struct dvb_frontend *fe) { struct fc0012_priv *priv = fe->tuner_priv; @@ -420,7 +426,7 @@ static const struct dvb_tuner_ops fc0012_tuner_ops = { .frequency_step = 0, }, - .release = dvb_tuner_simple_release, + .release = fc0012_release, .init = fc0012_init, diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index b068b9702cf7..f7cf0e9e7c99 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -52,6 +52,12 @@ static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val) return 0; } +static void fc0013_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int fc0013_init(struct dvb_frontend *fe) { struct fc0013_priv *priv = fe->tuner_priv; @@ -579,7 +585,7 @@ static const struct dvb_tuner_ops fc0013_tuner_ops = { .frequency_step = 0, }, - .release = dvb_tuner_simple_release, + .release = fc0013_release, .init = fc0013_init, .sleep = fc0013_sleep, diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c index 86542cbd73fb..aba580b4ac2c 100644 --- a/drivers/media/tuners/mc44s803.c +++ b/drivers/media/tuners/mc44s803.c @@ -80,6 +80,14 @@ static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val) return 0; } +static void mc44s803_release(struct dvb_frontend *fe) +{ + struct mc44s803_priv *priv = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(priv); +} + static int mc44s803_init(struct dvb_frontend *fe) { struct mc44s803_priv *priv = fe->tuner_priv; @@ -302,7 +310,7 @@ static const struct dvb_tuner_ops mc44s803_tuner_ops = { .frequency_step = 100000, }, - .release = dvb_tuner_simple_release, + .release = mc44s803_release, .init = mc44s803_init, .set_params = mc44s803_set_params, .get_frequency = mc44s803_get_frequency, diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c index 14e7b64360cb..94077ea78dde 100644 --- a/drivers/media/tuners/mt2060.c +++ b/drivers/media/tuners/mt2060.c @@ -332,6 +332,12 @@ static int mt2060_sleep(struct dvb_frontend *fe) return ret; } +static void mt2060_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static const struct dvb_tuner_ops mt2060_tuner_ops = { .info = { .name = "Microtune MT2060", @@ -340,7 +346,7 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = { .frequency_step = 50000, }, - .release = dvb_tuner_simple_release, + .release = mt2060_release, .init = mt2060_init, .sleep = mt2060_sleep, diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c index 4237d8f15919..129bf8e1aff8 100644 --- a/drivers/media/tuners/mt20xx.c +++ b/drivers/media/tuners/mt20xx.c @@ -49,6 +49,12 @@ struct microtune_priv { u32 frequency; }; +static void microtune_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct microtune_priv *priv = fe->tuner_priv; @@ -357,7 +363,7 @@ static int mt2032_set_params(struct dvb_frontend *fe, static const struct dvb_tuner_ops mt2032_tuner_ops = { .set_analog_params = mt2032_set_params, - .release = dvb_tuner_simple_release, + .release = microtune_release, .get_frequency = microtune_get_frequency, }; @@ -552,7 +558,7 @@ static int mt2050_set_params(struct dvb_frontend *fe, static const struct dvb_tuner_ops mt2050_tuner_ops = { .set_analog_params = mt2050_set_params, - .release = dvb_tuner_simple_release, + .release = microtune_release, .get_frequency = microtune_get_frequency, }; diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c index 35ea5e7975ac..88edcc031e3c 100644 --- a/drivers/media/tuners/mt2266.c +++ b/drivers/media/tuners/mt2266.c @@ -296,6 +296,12 @@ static int mt2266_sleep(struct dvb_frontend *fe) return 0; } +static void mt2266_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static const struct dvb_tuner_ops mt2266_tuner_ops = { .info = { .name = "Microtune MT2266", @@ -303,7 +309,7 @@ static const struct dvb_tuner_ops mt2266_tuner_ops = { .frequency_max = 862000000, .frequency_step = 50000, }, - .release = dvb_tuner_simple_release, + .release = mt2266_release, .init = mt2266_init, .sleep = mt2266_sleep, .set_params = mt2266_set_params, diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c index 5a1662aeeb87..a2c6cd1c3923 100644 --- a/drivers/media/tuners/qt1010.c +++ b/drivers/media/tuners/qt1010.c @@ -377,6 +377,12 @@ static int qt1010_init(struct dvb_frontend *fe) return qt1010_set_params(fe); } +static void qt1010_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct qt1010_priv *priv = fe->tuner_priv; @@ -398,7 +404,7 @@ static const struct dvb_tuner_ops qt1010_tuner_ops = { .frequency_step = QT1010_STEP, }, - .release = dvb_tuner_simple_release, + .release = qt1010_release, .init = qt1010_init, /* TODO: implement sleep */ diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c index 4d2916fb9953..8357a3c08a70 100644 --- a/drivers/media/tuners/tda18218.c +++ b/drivers/media/tuners/tda18218.c @@ -265,6 +265,12 @@ static int tda18218_init(struct dvb_frontend *fe) return ret; } +static void tda18218_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static const struct dvb_tuner_ops tda18218_tuner_ops = { .info = { .name = "NXP TDA18218", @@ -274,7 +280,7 @@ static const struct dvb_tuner_ops tda18218_tuner_ops = { .frequency_step = 1000, }, - .release = dvb_tuner_simple_release, + .release = tda18218_release, .init = tda18218_init, .sleep = tda18218_sleep, diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c index 4befb81f0c1a..2137eadf30f1 100644 --- a/drivers/media/tuners/tda827x.c +++ b/drivers/media/tuners/tda827x.c @@ -767,6 +767,12 @@ static void tda827xa_agcf(struct dvb_frontend *fe) /* ------------------------------------------------------------------ */ +static void tda827x_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tda827x_priv *priv = fe->tuner_priv; @@ -818,7 +824,7 @@ static const struct dvb_tuner_ops tda827xo_tuner_ops = { .frequency_max = 860000000, .frequency_step = 250000 }, - .release = dvb_tuner_simple_release, + .release = tda827x_release, .init = tda827x_initial_init, .sleep = tda827x_initial_sleep, .set_params = tda827xo_set_params, @@ -834,7 +840,7 @@ static const struct dvb_tuner_ops tda827xa_tuner_ops = { .frequency_max = 906000000, .frequency_step = 62500 }, - .release = dvb_tuner_simple_release, + .release = tda827x_release, .init = tda827x_init, .sleep = tda827xa_sleep, .set_params = tda827xa_set_params, diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c index 82f25621d995..a9b1bb134409 100644 --- a/drivers/media/tuners/tea5761.c +++ b/drivers/media/tuners/tea5761.c @@ -284,6 +284,12 @@ int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) return 0; } +static void tea5761_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tea5761_priv *priv = fe->tuner_priv; @@ -297,7 +303,7 @@ static const struct dvb_tuner_ops tea5761_tuner_ops = { }, .set_analog_params = set_radio_freq, .sleep = set_radio_sleep, - .release = dvb_tuner_simple_release, + .release = tea5761_release, .get_frequency = tea5761_get_frequency, .get_status = tea5761_get_status, .get_rf_strength = tea5761_get_rf_strength, diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c index a33c97de8b8a..525b7ab90c80 100644 --- a/drivers/media/tuners/tea5767.c +++ b/drivers/media/tuners/tea5767.c @@ -401,6 +401,12 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) return 0; } +static void tea5767_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tea5767_priv *priv = fe->tuner_priv; @@ -426,7 +432,7 @@ static const struct dvb_tuner_ops tea5767_tuner_ops = { .set_analog_params = set_radio_freq, .set_config = tea5767_set_config, .sleep = tea5767_standby, - .release = dvb_tuner_simple_release, + .release = tea5767_release, .get_frequency = tea5767_get_frequency, .get_status = tea5767_get_status, .get_rf_strength = tea5767_get_rf_strength, -- cgit v1.2.3 From 33e423c40ccf6eedbb5dc6e687524f9133368601 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 26 Oct 2016 07:43:43 -0200 Subject: [media] media: mtk-mdp: mark PM functions as __maybe_unused MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A previous patch tried to fix a build error, but introduced another warning: drivers/media/platform/mtk-mdp/mtk_mdp_core.c:71:13: error: ‘mtk_mdp_clock_off’ defined but not used [-Werror=unused-function] drivers/media/platform/mtk-mdp/mtk_mdp_core.c:62:13: error: ‘mtk_mdp_clock_on’ defined but not used [-Werror=unused-function] This marks all the PM functions as __maybe_unused and removes the #ifdef around them, as that will always do the right thing. Fixes: 1b06fcf56aa6 ("[media] media: mtk-mdp: fix build error") Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 51f2b50e406f..9e4eb7dcc424 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -234,8 +234,7 @@ static int mtk_mdp_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int mtk_mdp_pm_suspend(struct device *dev) +static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev) { struct mtk_mdp_dev *mdp = dev_get_drvdata(dev); @@ -244,7 +243,7 @@ static int mtk_mdp_pm_suspend(struct device *dev) return 0; } -static int mtk_mdp_pm_resume(struct device *dev) +static int __maybe_unused mtk_mdp_pm_resume(struct device *dev) { struct mtk_mdp_dev *mdp = dev_get_drvdata(dev); @@ -252,10 +251,8 @@ static int mtk_mdp_pm_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM */ -#ifdef CONFIG_PM_SLEEP -static int mtk_mdp_suspend(struct device *dev) +static int __maybe_unused mtk_mdp_suspend(struct device *dev) { if (pm_runtime_suspended(dev)) return 0; @@ -263,14 +260,13 @@ static int mtk_mdp_suspend(struct device *dev) return mtk_mdp_pm_suspend(dev); } -static int mtk_mdp_resume(struct device *dev) +static int __maybe_unused mtk_mdp_resume(struct device *dev) { if (pm_runtime_suspended(dev)) return 0; return mtk_mdp_pm_resume(dev); } -#endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops mtk_mdp_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(mtk_mdp_suspend, mtk_mdp_resume) -- cgit v1.2.3 From 1f5ecaf985c46889278f51fcb7bc143f60f4eb14 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 29 Oct 2016 23:36:24 -0200 Subject: [media] dibusb: fix possible memory leak in dibusb_rc_query() 'buf' is malloced in dibusb_rc_query() and should be freed before leaving from the error handling cases, otherwise it will cause memory leak. Fixes: ff1c123545d7 ("[media] dibusb: handle error code on RC query") Signed-off-by: Wei Yongjun Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dibusb-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c index de3ee2547479..8207e6900656 100644 --- a/drivers/media/usb/dvb-usb/dibusb-common.c +++ b/drivers/media/usb/dvb-usb/dibusb-common.c @@ -382,9 +382,9 @@ int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) if (buf[0] != 0) deb_info("key: %*ph\n", 5, buf); +ret: kfree(buf); -ret: return ret; } EXPORT_SYMBOL(dibusb_rc_query); -- cgit v1.2.3 From 21098562a41ce24af1e105dc96179260ebcc980c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 29 Oct 2016 23:53:10 -0200 Subject: [media] c8sectpfe: fix error return code in c8sectpfe_probe() Fix to return error code -ENODEV from the error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Acked-by: Patrice Chotard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 22fd8b91809a..7652ce2ec1dc 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -813,6 +813,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) i2c_bus = of_parse_phandle(child, "i2c-bus", 0); if (!i2c_bus) { dev_err(&pdev->dev, "No i2c-bus found\n"); + ret = -ENODEV; goto err_clk_disable; } tsin->i2c_adapter = @@ -820,6 +821,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) if (!tsin->i2c_adapter) { dev_err(&pdev->dev, "No i2c adapter found\n"); of_node_put(i2c_bus); + ret = -ENODEV; goto err_clk_disable; } of_node_put(i2c_bus); -- cgit v1.2.3 From 6932234fbe746223abf730cc89508492244fa64c Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:19 -0200 Subject: [media] winbond-cir: use name without space for pnp driver Rename the pnp driver in sysfs from /sys/bus/pnp/drivers/Winbond CIR to /sys/bus/pnp/drivers/winbond-cir Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/winbond-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 8c1f9225d358..78491ed48d92 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1185,7 +1185,7 @@ static const struct pnp_device_id wbcir_ids[] = { MODULE_DEVICE_TABLE(pnp, wbcir_ids); static struct pnp_driver wbcir_driver = { - .name = WBCIR_NAME, + .name = DRVNAME, .id_table = wbcir_ids, .probe = wbcir_probe, .remove = wbcir_remove, -- cgit v1.2.3 From da500033df2b7b532aa04c462ffdc203b9eabde4 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:20 -0200 Subject: [media] redrat3: don't include vendor/product id in name No need to duplicate these in the rc name. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index d3c81619cd87..236b686bffd6 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -904,9 +904,9 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) if (!rc) return NULL; - snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s Infrared Remote Transceiver (%04x:%04x)", - prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "", - le16_to_cpu(rr3->udev->descriptor.idVendor), prod); + snprintf(rr3->name, sizeof(rr3->name), + "RedRat3%s Infrared Remote Transceiver", + prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : ""); usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys)); -- cgit v1.2.3 From d6aca6ea281d88ce1816fd6f5a57889c6ea9392b Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:21 -0200 Subject: [media] redrat3: remove dead code and pointless messages Cleanup the error logic, removing checks for things that should be always initialized when the routines are called, and remove some bogus messages. [mchehab@s-opensource.com: fix some merge conflicts] Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 236b686bffd6..09e34a73d663 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -363,11 +363,6 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) unsigned int i, sig_size, single_len, offset, val; u32 mod_freq; - if (!rr3) { - pr_err("%s called with no context!\n", __func__); - return; - } - dev = rr3->dev; mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); @@ -693,19 +688,9 @@ out: /* callback function from USB when async USB request has completed */ static void redrat3_handle_async(struct urb *urb) { - struct redrat3_dev *rr3; + struct redrat3_dev *rr3 = urb->context; int ret; - if (!urb) - return; - - rr3 = urb->context; - if (!rr3) { - pr_err("%s called with invalid context!\n", __func__); - usb_unlink_urb(urb); - return; - } - switch (urb->status) { case 0: ret = redrat3_get_ir_data(rr3, urb->actual_length); @@ -1069,8 +1054,6 @@ error: redrat3_delete(rr3, rr3->udev); no_endpoints: - dev_err(dev, "%s: retval = %x", __func__, retval); - return retval; } @@ -1079,9 +1062,6 @@ static void redrat3_dev_disconnect(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); struct redrat3_dev *rr3 = usb_get_intfdata(intf); - if (!rr3) - return; - usb_set_intfdata(intf, NULL); rc_unregister_device(rr3->rc); led_classdev_unregister(&rr3->led); -- cgit v1.2.3 From 8a21ec9bb3ecea54ebbd8576460ec8ba2096a29e Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:22 -0200 Subject: [media] redrat3: fix error paths in probe If redrat3_delete() is called, ensure ep_in and udev members are set up so we don't dereference null in the error path. Also ensure that rc dev device exists before we enable the receiver and that the led urb exists before we create the led device. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 49 ++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 09e34a73d663..af562217a205 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -980,17 +980,19 @@ static int redrat3_dev_probe(struct usb_interface *intf, goto no_endpoints; rr3->dev = &intf->dev; + rr3->ep_in = ep_in; + rr3->ep_out = ep_out; + rr3->udev = udev; /* set up bulk-in endpoint */ rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rr3->read_urb) - goto error; + goto redrat_free; - rr3->ep_in = ep_in; rr3->bulk_in_buf = usb_alloc_coherent(udev, le16_to_cpu(ep_in->wMaxPacketSize), GFP_KERNEL, &rr3->dma_in); if (!rr3->bulk_in_buf) - goto error; + goto redrat_free; pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, @@ -998,34 +1000,16 @@ static int redrat3_dev_probe(struct usb_interface *intf, rr3->read_urb->transfer_dma = rr3->dma_in; rr3->read_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - rr3->ep_out = ep_out; - rr3->udev = udev; - redrat3_reset(rr3); redrat3_get_firmware_rev(rr3); - /* might be all we need to do? */ - retval = redrat3_enable_detector(rr3); - if (retval < 0) - goto error; - /* default.. will get overridden by any sends with a freq defined */ rr3->carrier = 38000; - /* led control */ - rr3->led.name = "redrat3:red:feedback"; - rr3->led.default_trigger = "rc-feedback"; - rr3->led.brightness_set = redrat3_brightness_set; - retval = led_classdev_register(&intf->dev, &rr3->led); - if (retval) - goto error; - atomic_set(&rr3->flash, 0); rr3->flash_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rr3->flash_urb) { - retval = -ENOMEM; - goto led_free_error; - } + if (!rr3->flash_urb) + goto redrat_free; /* setup packet is 'c0 b9 0000 0000 0001' */ rr3->flash_control.bRequestType = 0xc0; @@ -1037,20 +1021,33 @@ static int redrat3_dev_probe(struct usb_interface *intf, &rr3->flash_in_buf, sizeof(rr3->flash_in_buf), redrat3_led_complete, rr3); + /* led control */ + rr3->led.name = "redrat3:red:feedback"; + rr3->led.default_trigger = "rc-feedback"; + rr3->led.brightness_set = redrat3_brightness_set; + retval = led_classdev_register(&intf->dev, &rr3->led); + if (retval) + goto redrat_free; + rr3->rc = redrat3_init_rc_dev(rr3); if (!rr3->rc) { retval = -ENOMEM; - goto led_free_error; + goto led_free; } + /* might be all we need to do? */ + retval = redrat3_enable_detector(rr3); + if (retval < 0) + goto led_free; + /* we can register the device now, as it is ready */ usb_set_intfdata(intf, rr3); return 0; -led_free_error: +led_free: led_classdev_unregister(&rr3->led); -error: +redrat_free: redrat3_delete(rr3, rr3->udev); no_endpoints: -- cgit v1.2.3 From c49fcdde38cba120005d6b86bcbbfacca51309f6 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 19:13:11 -0200 Subject: [media] redrat3: enable carrier reports using wideband receiver The wideband receiver is a little awkward on the redrat3. Data arrives on a different endpoint, and the learning command must be reissued every time data is learned. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 186 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 140 insertions(+), 46 deletions(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index af562217a205..33fa1951733c 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -81,6 +81,8 @@ #define RR3_RC_DET_ENABLE 0xbb /* Stop capture with the RC receiver */ #define RR3_RC_DET_DISABLE 0xbc +/* Start capture with the wideband receiver */ +#define RR3_MODSIG_CAPTURE 0xb2 /* Return the status of RC detector capture */ #define RR3_RC_DET_STATUS 0xbd /* Reset redrat */ @@ -105,8 +107,10 @@ #define RR3_CLK_PER_COUNT 12 /* (RR3_CLK / RR3_CLK_PER_COUNT) */ #define RR3_CLK_CONV_FACTOR 2000000 -/* USB bulk-in IR data endpoint address */ -#define RR3_BULK_IN_EP_ADDR 0x82 +/* USB bulk-in wideband IR data endpoint address */ +#define RR3_WIDE_IN_EP_ADDR 0x81 +/* USB bulk-in narrowband IR data endpoint address */ +#define RR3_NARROW_IN_EP_ADDR 0x82 /* Size of the fixed-length portion of the signal */ #define RR3_DRIVER_MAXLENS 128 @@ -207,15 +211,22 @@ struct redrat3_dev { struct urb *flash_urb; u8 flash_in_buf; + /* learning */ + bool wideband; + struct usb_ctrlrequest learn_control; + struct urb *learn_urb; + u8 learn_buf; + /* save off the usb device pointer */ struct usb_device *udev; /* the receive endpoint */ - struct usb_endpoint_descriptor *ep_in; + struct usb_endpoint_descriptor *ep_narrow; /* the buffer to receive data */ void *bulk_in_buf; /* urb used to read ir data */ - struct urb *read_urb; + struct urb *narrow_urb; + struct urb *wide_urb; /* the send endpoint */ struct usb_endpoint_descriptor *ep_out; @@ -236,23 +247,6 @@ struct redrat3_dev { char phys[64]; }; -/* - * redrat3_issue_async - * - * Issues an async read to the ir data in port.. - * sets the callback to be redrat3_handle_async - */ -static void redrat3_issue_async(struct redrat3_dev *rr3) -{ - int res; - - res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); - if (res) - dev_dbg(rr3->dev, - "%s: receive request FAILED! (res %d, len %d)\n", - __func__, res, rr3->read_urb->transfer_buffer_length); -} - static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code) { if (!rr3->transmitting && (code != 0x40)) @@ -367,6 +361,14 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); dev_dbg(dev, "Got mod_freq of %u\n", mod_freq); + if (mod_freq && rr3->wideband) { + DEFINE_IR_RAW_EVENT(ev); + + ev.carrier_report = 1; + ev.carrier = mod_freq; + + ir_raw_event_store(rr3->rc, &ev); + } /* process each rr3 encoded byte into an int */ sig_size = be16_to_cpu(rr3->irdata.sig_size); @@ -449,19 +451,31 @@ static int redrat3_enable_detector(struct redrat3_dev *rr3) return -EIO; } - redrat3_issue_async(rr3); + ret = usb_submit_urb(rr3->narrow_urb, GFP_KERNEL); + if (ret) { + dev_err(rr3->dev, "narrow band urb failed: %d", ret); + return ret; + } - return 0; + ret = usb_submit_urb(rr3->wide_urb, GFP_KERNEL); + if (ret) + dev_err(rr3->dev, "wide band urb failed: %d", ret); + + return ret; } static inline void redrat3_delete(struct redrat3_dev *rr3, struct usb_device *udev) { - usb_kill_urb(rr3->read_urb); + usb_kill_urb(rr3->narrow_urb); + usb_kill_urb(rr3->wide_urb); usb_kill_urb(rr3->flash_urb); - usb_free_urb(rr3->read_urb); + usb_kill_urb(rr3->learn_urb); + usb_free_urb(rr3->narrow_urb); + usb_free_urb(rr3->wide_urb); usb_free_urb(rr3->flash_urb); - usb_free_coherent(udev, le16_to_cpu(rr3->ep_in->wMaxPacketSize), + usb_free_urb(rr3->learn_urb); + usb_free_coherent(udev, le16_to_cpu(rr3->ep_narrow->wMaxPacketSize), rr3->bulk_in_buf, rr3->dma_in); kfree(rr3); @@ -694,9 +708,19 @@ static void redrat3_handle_async(struct urb *urb) switch (urb->status) { case 0: ret = redrat3_get_ir_data(rr3, urb->actual_length); + if (!ret && rr3->wideband && !rr3->learn_urb->hcpriv) { + ret = usb_submit_urb(rr3->learn_urb, GFP_ATOMIC); + if (ret) + dev_err(rr3->dev, "Failed to submit learning urb: %d", + ret); + } + if (!ret) { /* no error, prepare to read more */ - redrat3_issue_async(rr3); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + dev_err(rr3->dev, "Failed to resubmit urb: %d", + ret); } break; @@ -856,6 +880,42 @@ static void redrat3_brightness_set(struct led_classdev *led_dev, enum } } +static int redrat3_wideband_receiver(struct rc_dev *rcdev, int enable) +{ + struct redrat3_dev *rr3 = rcdev->priv; + int ret = 0; + + rr3->wideband = enable != 0; + + if (enable) { + ret = usb_submit_urb(rr3->learn_urb, GFP_KERNEL); + if (ret) + dev_err(rr3->dev, "Failed to submit learning urb: %d", + ret); + } + + return ret; +} + +static void redrat3_learn_complete(struct urb *urb) +{ + struct redrat3_dev *rr3 = urb->context; + + switch (urb->status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + usb_unlink_urb(urb); + return; + case -EPIPE: + default: + dev_err(rr3->dev, "Error: learn urb status = %d", urb->status); + break; + } +} + static void redrat3_led_complete(struct urb *urb) { struct redrat3_dev *rr3 = urb->context; @@ -908,6 +968,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) rc->s_timeout = redrat3_set_timeout; rc->tx_ir = redrat3_transmit_ir; rc->s_tx_carrier = redrat3_set_tx_carrier; + rc->s_carrier_report = redrat3_wideband_receiver; rc->driver_name = DRIVER_NAME; rc->rx_resolution = US_TO_NS(2); rc->map_name = RC_MAP_HAUPPAUGE; @@ -933,7 +994,8 @@ static int redrat3_dev_probe(struct usb_interface *intf, struct usb_host_interface *uhi; struct redrat3_dev *rr3; struct usb_endpoint_descriptor *ep; - struct usb_endpoint_descriptor *ep_in = NULL; + struct usb_endpoint_descriptor *ep_narrow = NULL; + struct usb_endpoint_descriptor *ep_wide = NULL; struct usb_endpoint_descriptor *ep_out = NULL; u8 addr, attrs; int pipe, i; @@ -947,15 +1009,16 @@ static int redrat3_dev_probe(struct usb_interface *intf, addr = ep->bEndpointAddress; attrs = ep->bmAttributes; - if ((ep_in == NULL) && - ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && + if (((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && ((attrs & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { dev_dbg(dev, "found bulk-in endpoint at 0x%02x\n", ep->bEndpointAddress); - /* data comes in on 0x82, 0x81 is for other data... */ - if (ep->bEndpointAddress == RR3_BULK_IN_EP_ADDR) - ep_in = ep; + /* data comes in on 0x82, 0x81 is for learning */ + if (ep->bEndpointAddress == RR3_NARROW_IN_EP_ADDR) + ep_narrow = ep; + if (ep->bEndpointAddress == RR3_WIDE_IN_EP_ADDR) + ep_wide = ep; } if ((ep_out == NULL) && @@ -968,8 +1031,8 @@ static int redrat3_dev_probe(struct usb_interface *intf, } } - if (!ep_in || !ep_out) { - dev_err(dev, "Couldn't find both in and out endpoints\n"); + if (!ep_narrow || !ep_out || !ep_wide) { + dev_err(dev, "Couldn't find all endpoints\n"); retval = -ENODEV; goto no_endpoints; } @@ -980,25 +1043,38 @@ static int redrat3_dev_probe(struct usb_interface *intf, goto no_endpoints; rr3->dev = &intf->dev; - rr3->ep_in = ep_in; + rr3->ep_narrow = ep_narrow; rr3->ep_out = ep_out; rr3->udev = udev; /* set up bulk-in endpoint */ - rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rr3->read_urb) + rr3->narrow_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rr3->narrow_urb) + goto redrat_free; + + rr3->wide_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rr3->wide_urb) goto redrat_free; rr3->bulk_in_buf = usb_alloc_coherent(udev, - le16_to_cpu(ep_in->wMaxPacketSize), GFP_KERNEL, &rr3->dma_in); + le16_to_cpu(ep_narrow->wMaxPacketSize), + GFP_KERNEL, &rr3->dma_in); if (!rr3->bulk_in_buf) goto redrat_free; - pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); - usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, - le16_to_cpu(ep_in->wMaxPacketSize), redrat3_handle_async, rr3); - rr3->read_urb->transfer_dma = rr3->dma_in; - rr3->read_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + pipe = usb_rcvbulkpipe(udev, ep_narrow->bEndpointAddress); + usb_fill_bulk_urb(rr3->narrow_urb, udev, pipe, rr3->bulk_in_buf, + le16_to_cpu(ep_narrow->wMaxPacketSize), + redrat3_handle_async, rr3); + rr3->narrow_urb->transfer_dma = rr3->dma_in; + rr3->narrow_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + pipe = usb_rcvbulkpipe(udev, ep_wide->bEndpointAddress); + usb_fill_bulk_urb(rr3->wide_urb, udev, pipe, rr3->bulk_in_buf, + le16_to_cpu(ep_narrow->wMaxPacketSize), + redrat3_handle_async, rr3); + rr3->wide_urb->transfer_dma = rr3->dma_in; + rr3->wide_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; redrat3_reset(rr3); redrat3_get_firmware_rev(rr3); @@ -1011,6 +1087,21 @@ static int redrat3_dev_probe(struct usb_interface *intf, if (!rr3->flash_urb) goto redrat_free; + /* learn urb */ + rr3->learn_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rr3->learn_urb) + goto redrat_free; + + /* setup packet is 'c0 b2 0000 0000 0001' */ + rr3->learn_control.bRequestType = 0xc0; + rr3->learn_control.bRequest = RR3_MODSIG_CAPTURE; + rr3->learn_control.wLength = cpu_to_le16(1); + + usb_fill_control_urb(rr3->learn_urb, udev, usb_rcvctrlpipe(udev, 0), + (unsigned char *)&rr3->learn_control, + &rr3->learn_buf, sizeof(rr3->learn_buf), + redrat3_learn_complete, rr3); + /* setup packet is 'c0 b9 0000 0000 0001' */ rr3->flash_control.bRequestType = 0xc0; rr3->flash_control.bRequest = RR3_BLINK_LED; @@ -1070,7 +1161,8 @@ static int redrat3_dev_suspend(struct usb_interface *intf, pm_message_t message) struct redrat3_dev *rr3 = usb_get_intfdata(intf); led_classdev_suspend(&rr3->led); - usb_kill_urb(rr3->read_urb); + usb_kill_urb(rr3->narrow_urb); + usb_kill_urb(rr3->wide_urb); usb_kill_urb(rr3->flash_urb); return 0; } @@ -1079,7 +1171,9 @@ static int redrat3_dev_resume(struct usb_interface *intf) { struct redrat3_dev *rr3 = usb_get_intfdata(intf); - if (usb_submit_urb(rr3->read_urb, GFP_ATOMIC)) + if (usb_submit_urb(rr3->narrow_urb, GFP_ATOMIC)) + return -EIO; + if (usb_submit_urb(rr3->wide_urb, GFP_ATOMIC)) return -EIO; led_classdev_resume(&rr3->led); return 0; -- cgit v1.2.3 From a48c4bbdff4f6fe10f9e853b01c8591d734a4e84 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:24 -0200 Subject: [media] redrat3: increase set size for lengths to maximum In learning mode, you can get much longer messages which can run out of lengths. The usb message will slightly larger. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 33fa1951733c..2784f5dae398 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -113,7 +113,7 @@ #define RR3_NARROW_IN_EP_ADDR 0x82 /* Size of the fixed-length portion of the signal */ -#define RR3_DRIVER_MAXLENS 128 +#define RR3_DRIVER_MAXLENS 255 #define RR3_MAX_SIG_SIZE 512 #define RR3_TIME_UNIT 50 #define RR3_END_OF_SIGNAL 0x7f -- cgit v1.2.3 From 12accdcb92ca997ffc3bf1e76887fb991d5ac773 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:25 -0200 Subject: [media] lirc: might sleep error in lirc_dev_fop_read [ 101.457944] ------------[ cut here ]------------ [ 101.457954] WARNING: CPU: 3 PID: 1819 at kernel/sched/core.c:7708 __might_sleep+0x7e/0x80 [ 101.457960] do not call blocking ops when !TASK_RUNNING; state=1 set at [] lirc_dev_fop_read+0x292/0x4e0 [lirc_dev] Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 809a8671e3d6..bb2f47a21d68 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -681,7 +681,6 @@ ssize_t lirc_dev_fop_read(struct file *file, * between while condition checking and scheduling) */ add_wait_queue(&ir->buf->wait_poll, &wait); - set_current_state(TASK_INTERRUPTIBLE); /* * while we didn't provide 'length' bytes, device is opened in blocking @@ -706,13 +705,13 @@ ssize_t lirc_dev_fop_read(struct file *file, } mutex_unlock(&ir->irctl_lock); - schedule(); set_current_state(TASK_INTERRUPTIBLE); + schedule(); + set_current_state(TASK_RUNNING); if (mutex_lock_interruptible(&ir->irctl_lock)) { ret = -ERESTARTSYS; remove_wait_queue(&ir->buf->wait_poll, &wait); - set_current_state(TASK_RUNNING); goto out_unlocked; } @@ -732,7 +731,6 @@ ssize_t lirc_dev_fop_read(struct file *file, } remove_wait_queue(&ir->buf->wait_poll, &wait); - set_current_state(TASK_RUNNING); out_locked: mutex_unlock(&ir->irctl_lock); -- cgit v1.2.3 From afbb110172b93e44a3fd1b5afb3a71f7f9da4406 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:26 -0200 Subject: [media] lirc: prevent use-after free If you unplug an lirc device while reading from it, you will get an use after free as the cdev is freed while still in use. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index bb2f47a21d68..7215891da248 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -161,15 +161,15 @@ static int lirc_cdev_add(struct irctl *ir) struct lirc_driver *d = &ir->d; struct cdev *cdev; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = cdev_alloc(); if (!cdev) goto err_out; if (d->fops) { - cdev_init(cdev, d->fops); + cdev->ops = d->fops; cdev->owner = d->owner; } else { - cdev_init(cdev, &lirc_dev_fops); + cdev->ops = &lirc_dev_fops; cdev->owner = THIS_MODULE; } retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); @@ -187,7 +187,7 @@ static int lirc_cdev_add(struct irctl *ir) return 0; err_out: - kfree(cdev); + cdev_del(cdev); return retval; } @@ -417,7 +417,6 @@ int lirc_unregister_driver(int minor) } else { lirc_irctl_cleanup(ir); cdev_del(cdev); - kfree(cdev); kfree(ir); irctls[minor] = NULL; } @@ -518,7 +517,6 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) lirc_irctl_cleanup(ir); cdev_del(cdev); irctls[ir->d.minor] = NULL; - kfree(cdev); kfree(ir); } -- cgit v1.2.3 From c77d17c0985a70fa3cd2ecde1e4f4be0dd5e9e12 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 31 Oct 2016 15:52:27 -0200 Subject: [media] lirc: use-after free while reading from device and unplugging Many lirc drivers have their own receive buffers which are freed on unplug (e.g. ir_lirc_unregister). This means that ir->buf->wait_poll will be freed directly after unplug so do not remove yourself from the wait queue. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 7215891da248..d3039efb4e7c 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -715,7 +715,7 @@ ssize_t lirc_dev_fop_read(struct file *file, if (!ir->attached) { ret = -ENODEV; - break; + goto out_locked; } } else { lirc_buffer_read(ir->buf, buf); -- cgit v1.2.3 From 8c1d254f2de803fc7d74269e8ded79047284c275 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 3 Nov 2016 07:38:01 -0200 Subject: [media] dvb-usb: remove another redundant #include Kernel source files need not include explicitly because the top Makefile forces to include it with: -include $(srctree)/include/linux/kconfig.h Remove another reduntdant include, that managed to sneak by commit 97139d4a6f26 ("treewide: remove redundant #include "). Signed-off-by: Paul Bolle Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dibusb-mc-common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/dibusb-mc-common.c b/drivers/media/usb/dvb-usb/dibusb-mc-common.c index d66f56cc46a5..c989cac9343d 100644 --- a/drivers/media/usb/dvb-usb/dibusb-mc-common.c +++ b/drivers/media/usb/dvb-usb/dibusb-mc-common.c @@ -9,7 +9,6 @@ * see Documentation/dvb/README.dvb-usb for more information */ -#include #include "dibusb.h" /* 3000MC/P stuff */ -- cgit v1.2.3 From e04e581093d74249f27411ed95878b648b222e53 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 11 Nov 2016 11:40:20 -0200 Subject: [media] atmel-isc: fix error return code in atmel_isc_probe() Fix to return error code -ENODEV from the error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index 8e25d3f56438..fa68fe912c95 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -1424,6 +1424,7 @@ static int atmel_isc_probe(struct platform_device *pdev) if (list_empty(&isc->subdev_entities)) { dev_err(dev, "no subdev found\n"); + ret = -ENODEV; goto unregister_v4l2_device; } -- cgit v1.2.3 From db9ee88bb22e237a532fa4c8fda0975f8f045246 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 11 Nov 2016 22:23:56 -0200 Subject: [media] vivid: fix HDMI VSDB block in the EDID The maximum 'Max TMDS Rate' in the HDMI VSDB block is 340 MHz, not 600. Higher rates are advertised in the HDMI Forum VSDB block. So lower the Max TMDS rate in the HDMI VSDB block that the vivid driver uses to 300 MHz, which is typical of most HDMI 1.4b devices. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 5464fefbaab9..b8ef836766df 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -183,7 +183,7 @@ static const u8 vivid_hdmi_edid[256] = { 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, - 0x0c, 0x00, 0x10, 0x00, 0x00, 0x78, 0x21, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, @@ -194,7 +194,7 @@ static const u8 vivid_hdmi_edid[256] = { 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, }; static int vidioc_querycap(struct file *file, void *priv, -- cgit v1.2.3 From 4c0c596adfca795af12e8e61625fd95b50e8f8f3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 12 Nov 2016 15:26:48 -0200 Subject: [media] zoran: fix spelling mistake in dprintk message Trivial fix to spelling mistake "unnsupported" to "unsupported" in debug message. Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/zoran/zoran_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index d6b631add216..2170e174c335 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -1488,7 +1488,7 @@ zoran_set_input (struct zoran *zr, if (input < 0 || input >= zr->card.inputs) { dprintk(1, KERN_ERR - "%s: %s - unnsupported input %d\n", + "%s: %s - unsupported input %d\n", ZR_DEVNAME(zr), __func__, input); return -EINVAL; } -- cgit v1.2.3 From 7febb418a32a2caaef57bca91df41c658406670d Mon Sep 17 00:00:00 2001 From: Minghsiu Tsai Date: Mon, 14 Nov 2016 23:34:34 -0200 Subject: [media] mtk-mdp: allocate video_device dynamically It can fix known problems with embedded video_device structs. Signed-off-by: Minghsiu Tsai Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_core.h | 2 +- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 33 ++++++++++++++++----------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h index 848569d4ab90..ad1cff306efd 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h @@ -167,7 +167,7 @@ struct mtk_mdp_dev { struct mtk_mdp_comp *comp[MTK_MDP_COMP_ID_MAX]; struct v4l2_m2m_dev *m2m_dev; struct list_head ctx_list; - struct video_device vdev; + struct video_device *vdev; struct v4l2_device v4l2_dev; struct workqueue_struct *job_wq; struct platform_device *vpu_dev; diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index 9a747e7321cc..13afe48b9dc5 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -1236,16 +1236,22 @@ int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp) int ret; mdp->variant = &mtk_mdp_default_variant; - mdp->vdev.device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; - mdp->vdev.fops = &mtk_mdp_m2m_fops; - mdp->vdev.ioctl_ops = &mtk_mdp_m2m_ioctl_ops; - mdp->vdev.release = video_device_release_empty; - mdp->vdev.lock = &mdp->lock; - mdp->vdev.vfl_dir = VFL_DIR_M2M; - mdp->vdev.v4l2_dev = &mdp->v4l2_dev; - snprintf(mdp->vdev.name, sizeof(mdp->vdev.name), "%s:m2m", + mdp->vdev = video_device_alloc(); + if (!mdp->vdev) { + dev_err(dev, "failed to allocate video device\n"); + ret = -ENOMEM; + goto err_video_alloc; + } + mdp->vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; + mdp->vdev->fops = &mtk_mdp_m2m_fops; + mdp->vdev->ioctl_ops = &mtk_mdp_m2m_ioctl_ops; + mdp->vdev->release = video_device_release; + mdp->vdev->lock = &mdp->lock; + mdp->vdev->vfl_dir = VFL_DIR_M2M; + mdp->vdev->v4l2_dev = &mdp->v4l2_dev; + snprintf(mdp->vdev->name, sizeof(mdp->vdev->name), "%s:m2m", MTK_MDP_MODULE_NAME); - video_set_drvdata(&mdp->vdev, mdp); + video_set_drvdata(mdp->vdev, mdp); mdp->m2m_dev = v4l2_m2m_init(&mtk_mdp_m2m_ops); if (IS_ERR(mdp->m2m_dev)) { @@ -1254,26 +1260,27 @@ int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp) goto err_m2m_init; } - ret = video_register_device(&mdp->vdev, VFL_TYPE_GRABBER, 2); + ret = video_register_device(mdp->vdev, VFL_TYPE_GRABBER, 2); if (ret) { dev_err(dev, "failed to register video device\n"); goto err_vdev_register; } v4l2_info(&mdp->v4l2_dev, "driver registered as /dev/video%d", - mdp->vdev.num); + mdp->vdev->num); return 0; err_vdev_register: v4l2_m2m_release(mdp->m2m_dev); err_m2m_init: - video_device_release(&mdp->vdev); + video_device_release(mdp->vdev); +err_video_alloc: return ret; } void mtk_mdp_unregister_m2m_device(struct mtk_mdp_dev *mdp) { - video_device_release(&mdp->vdev); + video_unregister_device(mdp->vdev); v4l2_m2m_release(mdp->m2m_dev); } -- cgit v1.2.3 From 3f98da9636029486b86eb63f0b57b91dcbd880b0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Nov 2016 13:15:45 -0200 Subject: [media] cec: ignore messages that we initiated Some CEC adapters will receive messages that they initiated. Add a check that will ignore such messages. Most hardware behaves correctly in this respect, but I have seen adapters that don't, so just filter this out in the framework. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index d9c6f2c1c6fa..0ea4efb3de66 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -869,6 +869,21 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) return; + /* + * Some CEC adapters will receive the messages that they transmitted. + * This test filters out those messages by checking if we are the + * initiator, and just returning in that case. + * + * Note that this won't work if this is an Unregistered device. + * + * It is bad practice if the hardware receives the message that it + * transmitted and luckily most CEC adapters behave correctly in this + * respect. + */ + if (msg_init != CEC_LOG_ADDR_UNREGISTERED && + cec_has_log_addr(adap, msg_init)) + return; + msg->rx_ts = ktime_get_ns(); msg->rx_status = CEC_RX_STATUS_OK; msg->sequence = msg->reply = msg->timeout = 0; -- cgit v1.2.3 From b66db53f8d85f6e8ce1b2b827d3fb3b0f0bf64c6 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 21 Nov 2016 19:55:51 -0200 Subject: [media] lirc_serial: port to rc-core Tested with a homebrew serial ir. Remove last remmants of the nslu2 which could not be enabled, and fix checkpatch warnings. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_serial.c | 677 +++++++++++++------------------ 1 file changed, 274 insertions(+), 403 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index b798b311d32c..05a8a47aecef 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -9,6 +9,7 @@ * Copyright (C) 1998 Ben Pfaff * Copyright (C) 1999 Christoph Bartelmus * Copyright (C) 2007 Andrei Tanas (suspend/resume support) + * Copyright (C) 2016 Sean Young (port to rc-core) * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -18,18 +19,13 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ /* * Steve's changes to improve transmission fidelity: * - for systems with the rdtsc instruction and the clock counter, a * send_pule that times the pulses directly using the counter. - * This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is + * This means that the IR_SERIAL_TRANSMITTER_LATENCY fudge is * not needed. Measurement shows very stable waveform, even where * PCI activity slows the access to the UART, which trips up other * versions. @@ -52,56 +48,34 @@ #include #include -#include -#include -#include #include -#include #include #include -#include -#include #include -#include -#include #include -#include #include -#include -#include -#include -#include #include +#include -/* From Intel IXP42X Developer's Manual (#252480-005): */ -/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ -#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ -#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ - -#include -#include - -#define LIRC_DRIVER_NAME "lirc_serial" - -struct lirc_serial { +struct serial_ir_hw { int signal_pin; int signal_pin_change; u8 on; u8 off; + unsigned set_send_carrier:1; + unsigned set_duty_cycle:1; long (*send_pulse)(unsigned long length); void (*send_space)(long length); - int features; spinlock_t lock; }; -#define LIRC_HOMEBREW 0 -#define LIRC_IRDEO 1 -#define LIRC_IRDEO_REMOTE 2 -#define LIRC_ANIMAX 3 -#define LIRC_IGOR 4 -#define LIRC_NSLU2 5 +#define IR_HOMEBREW 0 +#define IR_IRDEO 1 +#define IR_IRDEO_REMOTE 2 +#define IR_ANIMAX 3 +#define IR_IGOR 4 -/*** module parameters ***/ +/* module parameters */ static int type; static int io; static int irq; @@ -114,107 +88,89 @@ static bool txsense; /* 0 = active high, 1 = active low */ /* forward declarations */ static long send_pulse_irdeo(unsigned long length); -static long send_pulse_homebrew(unsigned long length); static void send_space_irdeo(long length); +#ifdef CONFIG_IR_SERIAL_TRANSMITTER +static long send_pulse_homebrew(unsigned long length); static void send_space_homebrew(long length); +#endif -static struct lirc_serial hardware[] = { - [LIRC_HOMEBREW] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_HOMEBREW].lock), - .signal_pin = UART_MSR_DCD, +static struct serial_ir_hw hardware[] = { + [IR_HOMEBREW] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_HOMEBREW].lock), + .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), .off = (UART_MCR_RTS | UART_MCR_OUT2), +#ifdef CONFIG_IR_SERIAL_TRANSMITTER .send_pulse = send_pulse_homebrew, .send_space = send_space_homebrew, -#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER - .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | - LIRC_CAN_SET_SEND_CARRIER | - LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) -#else - .features = LIRC_CAN_REC_MODE2 + .set_send_carrier = true, + .set_duty_cycle = true, #endif }, - [LIRC_IRDEO] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO].lock), - .signal_pin = UART_MSR_DSR, + [IR_IRDEO] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO].lock), + .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = UART_MCR_OUT2, .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .send_pulse = send_pulse_irdeo, - .send_space = send_space_irdeo, - .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | - LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) + .send_pulse = send_pulse_irdeo, + .send_space = send_space_irdeo, + .set_duty_cycle = true, }, - [LIRC_IRDEO_REMOTE] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO_REMOTE].lock), - .signal_pin = UART_MSR_DSR, + [IR_IRDEO_REMOTE] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO_REMOTE].lock), + .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .send_pulse = send_pulse_irdeo, - .send_space = send_space_irdeo, - .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | - LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) + .send_pulse = send_pulse_irdeo, + .send_space = send_space_irdeo, + .set_duty_cycle = true, }, - [LIRC_ANIMAX] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_ANIMAX].lock), - .signal_pin = UART_MSR_DCD, + [IR_ANIMAX] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_ANIMAX].lock), + .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = 0, .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), .send_pulse = NULL, .send_space = NULL, - .features = LIRC_CAN_REC_MODE2 }, - [LIRC_IGOR] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IGOR].lock), - .signal_pin = UART_MSR_DSR, + [IR_IGOR] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IGOR].lock), + .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), .off = (UART_MCR_RTS | UART_MCR_OUT2), +#ifdef CONFIG_IR_SERIAL_TRANSMITTER .send_pulse = send_pulse_homebrew, .send_space = send_space_homebrew, -#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER - .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | - LIRC_CAN_SET_SEND_CARRIER | - LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) -#else - .features = LIRC_CAN_REC_MODE2 + .set_send_carrier = true, + .set_duty_cycle = true, #endif }, }; #define RS_ISR_PASS_LIMIT 256 -/* - * A long pulse code from a remote might take up to 300 bytes. The - * daemon should read the bytes as soon as they are generated, so take - * the number of keys you think you can push before the daemon runs - * and multiply by 300. The driver will warn you if you overrun this - * buffer. If you have a slow computer or non-busmastering IDE disks, - * maybe you will need to increase this. - */ - -/* This MUST be a power of two! It has to be larger than 1 as well. */ - -#define RBUF_LEN 256 +struct serial_ir { + ktime_t lastkt; + struct rc_dev *rcdev; + struct platform_device *pdev; -static ktime_t lastkt; + unsigned int freq; + unsigned int duty_cycle; -static struct lirc_buffer rbuf; - -static unsigned int freq = 38000; -static unsigned int duty_cycle = 50; + unsigned long period; + unsigned long pulse_width, space_width; +}; -/* Initialized in init_timing_params() */ -static unsigned long period; -static unsigned long pulse_width; -static unsigned long space_width; +static struct serial_ir serial_ir; #if defined(__i386__) /* @@ -241,18 +197,18 @@ static unsigned long space_width; * changed from 400 to 450 as this works better on slower machines; * faster machines will use the rdtsc code anyway */ -#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 +#define IR_SERIAL_TRANSMITTER_LATENCY 450 #else /* does anybody have information on other platforms ? */ /* 256 = 1<<8 */ -#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 +#define IR_SERIAL_TRANSMITTER_LATENCY 256 -#endif /* __i386__ */ +#endif /* __i386__ */ /* * FIXME: should we be using hrtimers instead of this - * LIRC_SERIAL_TRANSMITTER_LATENCY nonsense? + * IR_SERIAL_TRANSMITTER_LATENCY nonsense? */ /* fetch serial input packet (1 byte) from register offset */ @@ -324,8 +280,8 @@ static int init_timing_params(unsigned int new_duty_cycle, { __u64 loops_per_sec, work; - duty_cycle = new_duty_cycle; - freq = new_freq; + serial_ir.duty_cycle = new_duty_cycle; + serial_ir.freq = new_freq; loops_per_sec = __this_cpu_read(cpu.info.loops_per_jiffy); loops_per_sec *= HZ; @@ -338,12 +294,12 @@ static int init_timing_params(unsigned int new_duty_cycle, * Carrier period in clocks, approach good up to 32GHz clock, * gets carrier frequency within 8Hz */ - period = loops_per_sec >> 3; - period /= (freq >> 3); + serial_ir.period = loops_per_sec >> 3; + serial_ir.pperiod /= (freq >> 3); /* Derive pulse and space from the period */ - pulse_width = period * duty_cycle / 100; - space_width = period - pulse_width; + serial_ir.ppulse_width = serial_ir.period * serial.ir.duty_cycle / 100; + serial_ir.pspace_width = serial_ir.period - serial_ir.pulse_width; pr_debug("in init_timing_params, freq=%d, duty_cycle=%d, clk/jiffy=%ld, pulse=%ld, space=%ld, conv_us_to_clocks=%ld\n", freq, duty_cycle, __this_cpu_read(cpu_info.loops_per_jiffy), pulse_width, space_width, conv_us_to_clocks); @@ -358,18 +314,19 @@ static int init_timing_params(unsigned int new_duty_cycle, * IE multiplied by 256. */ if (256 * 1000000L / new_freq * new_duty_cycle / 100 <= - LIRC_SERIAL_TRANSMITTER_LATENCY) + IR_SERIAL_TRANSMITTER_LATENCY) return -EINVAL; if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <= - LIRC_SERIAL_TRANSMITTER_LATENCY) + IR_SERIAL_TRANSMITTER_LATENCY) return -EINVAL; - duty_cycle = new_duty_cycle; - freq = new_freq; - period = 256 * 1000000L / freq; - pulse_width = period * duty_cycle / 100; - space_width = period - pulse_width; + serial_ir.duty_cycle = new_duty_cycle; + serial_ir.freq = new_freq; + serial_ir.period = 256 * 1000000L / serial_ir.freq; + serial_ir.pulse_width = serial_ir.period * serial_ir.duty_cycle / 100; + serial_ir.space_width = serial_ir.period - serial_ir.pulse_width; pr_debug("in init_timing_params, freq=%d pulse=%ld, space=%ld\n", - freq, pulse_width, space_width); + serial_ir.freq, serial_ir.pulse_width, + serial_ir.space_width); return 0; } #endif /* USE_RDTSC */ @@ -386,7 +343,7 @@ static long send_pulse_irdeo(unsigned long length) /* how many bits have to be sent ? */ rawbits = length * 1152 / 10000; - if (duty_cycle > 50) + if (serial_ir.duty_cycle > 50) chunk = 3; else chunk = 1; @@ -429,6 +386,15 @@ static long send_pulse_irdeo(unsigned long length) /* To match 8 fractional bits used for pulse/space length */ +static void send_space_irdeo(long length) +{ + if (length <= 0) + return; + + safe_udelay(length); +} + +#ifdef CONFIG_IR_SERIAL_TRANSMITTER static long send_pulse_homebrew_softcarrier(unsigned long length) { int flag; @@ -440,19 +406,19 @@ static long send_pulse_homebrew_softcarrier(unsigned long length) while (actual < length) { if (flag) { off(); - target += space_width; + target += serial_ir.space_width; } else { on(); - target += pulse_width; + target += serial_ir.pulse_width; } d = (target - actual - - LIRC_SERIAL_TRANSMITTER_LATENCY + 128) >> 8; + IR_SERIAL_TRANSMITTER_LATENCY + 128) >> 8; /* * Note - we've checked in ioctl that the pulse/space * widths are big enough so that d is > 0 */ udelay(d); - actual += (d << 8) + LIRC_SERIAL_TRANSMITTER_LATENCY; + actual += (d << 8) + IR_SERIAL_TRANSMITTER_LATENCY; flag = !flag; } return (actual-length) >> 8; @@ -471,14 +437,6 @@ static long send_pulse_homebrew(unsigned long length) return 0; } -static void send_space_irdeo(long length) -{ - if (length <= 0) - return; - - safe_udelay(length); -} - static void send_space_homebrew(long length) { off(); @@ -486,67 +444,70 @@ static void send_space_homebrew(long length) return; safe_udelay(length); } +#endif -static void rbwrite(int l) -{ - if (lirc_buffer_full(&rbuf)) { - /* no new signals will be accepted */ - pr_debug("Buffer overrun\n"); - return; - } - lirc_buffer_write(&rbuf, (void *)&l); -} - -static void frbwrite(int l) +static void frbwrite(unsigned int l, bool is_pulse) { /* simple noise filter */ - static int pulse, space; - static unsigned int ptr; - - if (ptr > 0 && (l & PULSE_BIT)) { - pulse += l & PULSE_MASK; - if (pulse > 250) { - rbwrite(space); - rbwrite(pulse | PULSE_BIT); + static unsigned int ptr, pulse, space; + DEFINE_IR_RAW_EVENT(ev); + + if (ptr > 0 && is_pulse) { + pulse += l; + if (pulse > 250000) { + ev.duration = space; + ev.pulse = false; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ev.duration = pulse; + ev.pulse = true; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ptr = 0; pulse = 0; } return; } - if (!(l & PULSE_BIT)) { + if (!is_pulse) { if (ptr == 0) { - if (l > 20000) { + if (l > 20000000) { space = l; ptr++; return; } } else { - if (l > 20000) { + if (l > 20000000) { space += pulse; - if (space > PULSE_MASK) - space = PULSE_MASK; + if (space > IR_MAX_DURATION) + space = IR_MAX_DURATION; space += l; - if (space > PULSE_MASK) - space = PULSE_MASK; + if (space > IR_MAX_DURATION) + space = IR_MAX_DURATION; pulse = 0; return; } - rbwrite(space); - rbwrite(pulse | PULSE_BIT); + + ev.duration = space; + ev.pulse = false; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ev.duration = pulse; + ev.pulse = true; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ptr = 0; pulse = 0; } } - rbwrite(l); + + ev.duration = l; + ev.pulse = is_pulse; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); } -static irqreturn_t lirc_irq_handler(int i, void *blah) +static irqreturn_t serial_ir_irq_handler(int i, void *blah) { ktime_t kt; int counter, dcd; u8 status; ktime_t delkt; - int data; + unsigned int data; static int last_dcd = -1; if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { @@ -559,7 +520,7 @@ static irqreturn_t lirc_irq_handler(int i, void *blah) counter++; status = sinp(UART_MSR); if (counter > RS_ISR_PASS_LIMIT) { - pr_warn("AIEEEE: We're caught!\n"); + dev_err(&serial_ir.pdev->dev, "Trapped in interrupt"); break; } if ((status & hardware[type].signal_pin_change) @@ -567,47 +528,32 @@ static irqreturn_t lirc_irq_handler(int i, void *blah) /* get current time */ kt = ktime_get(); - /* New mode, written by Trent Piepho - . */ - /* - * The old format was not very portable. - * We now use an int to pass pulses - * and spaces to user space. - * - * If PULSE_BIT is set a pulse has been - * received, otherwise a space has been - * received. The driver needs to know if your - * receiver is active high or active low, or - * the space/pulse sense could be - * inverted. The bits denoted by PULSE_MASK are - * the length in microseconds. Lengths greater - * than or equal to 16 seconds are clamped to - * PULSE_MASK. All other bits are unused. - * This is a much simpler interface for user - * programs, as well as eliminating "out of - * phase" errors with space/pulse - * autodetection. + * The driver needs to know if your receiver is + * active high or active low, or the space/pulse + * sense could be inverted. */ - /* calc time since last interrupt in microseconds */ + /* calc time since last interrupt in nanoseconds */ dcd = (status & hardware[type].signal_pin) ? 1 : 0; if (dcd == last_dcd) { - pr_warn("ignoring spike: %d %d %llx %llx\n", - dcd, sense, ktime_to_us(kt), - ktime_to_us(lastkt)); + dev_err(&serial_ir.pdev->dev, + "ignoring spike: %d %d %lldns %lldns\n", + dcd, sense, ktime_to_ns(kt), + ktime_to_ns(serial_ir.lastkt)); continue; } - delkt = ktime_sub(kt, lastkt); + delkt = ktime_sub(kt, serial_ir.lastkt); if (ktime_compare(delkt, ktime_set(15, 0)) > 0) { - data = PULSE_MASK; /* really long time */ + data = IR_MAX_DURATION; /* really long time */ if (!(dcd^sense)) { /* sanity check */ - pr_warn("AIEEEE: %d %d %llx %llx\n", - dcd, sense, ktime_to_us(kt), - ktime_to_us(lastkt)); + dev_err(&serial_ir.pdev->dev, + "dcd unexpected: %d %d %lldns %lldns\n", + dcd, sense, ktime_to_ns(kt), + ktime_to_ns(serial_ir.lastkt)); /* * detecting pulse while this * MUST be a space! @@ -615,11 +561,11 @@ static irqreturn_t lirc_irq_handler(int i, void *blah) sense = sense ? 0 : 1; } } else - data = (int) ktime_to_us(delkt); - frbwrite(dcd^sense ? data : (data|PULSE_BIT)); - lastkt = kt; + data = ktime_to_ns(delkt); + frbwrite(data, !(dcd ^ sense)); + serial_ir.lastkt = kt; last_dcd = dcd; - wake_up_interruptible(&rbuf.wait_poll); + ir_raw_event_handle(serial_ir.rcdev); } } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ return IRQ_HANDLED; @@ -652,8 +598,6 @@ static int hardware_init_port(void) return -ENODEV; } - - /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); @@ -677,8 +621,8 @@ static int hardware_init_port(void) sinp(UART_MSR); switch (type) { - case LIRC_IRDEO: - case LIRC_IRDEO_REMOTE: + case IR_IRDEO: + case IR_IRDEO_REMOTE: /* setup port to 7N1 @ 115200 Baud */ /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ @@ -698,13 +642,13 @@ static int hardware_init_port(void) return 0; } -static int lirc_serial_probe(struct platform_device *dev) +static int serial_ir_probe(struct platform_device *dev) { int i, nlow, nhigh, result; - result = devm_request_irq(&dev->dev, irq, lirc_irq_handler, - (share_irq ? IRQF_SHARED : 0), - LIRC_DRIVER_NAME, &hardware); + result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, + share_irq ? IRQF_SHARED : 0, + KBUILD_MODNAME, &hardware); if (result < 0) { if (result == -EBUSY) dev_err(&dev->dev, "IRQ %d busy\n", irq); @@ -714,17 +658,12 @@ static int lirc_serial_probe(struct platform_device *dev) } /* Reserve io region. */ - /* - * Future MMAP-Developers: Attention! - * For memory mapped I/O you *might* need to use ioremap() first, - * for the NSLU2 it's done in boot code. - */ if (((iommap) && (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, - LIRC_DRIVER_NAME) == NULL)) + KBUILD_MODNAME) == NULL)) || ((!iommap) && (devm_request_region(&dev->dev, io, 8, - LIRC_DRIVER_NAME) == NULL))) { + KBUILD_MODNAME) == NULL))) { dev_err(&dev->dev, "port %04x already in use\n", io); dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n"); dev_warn(&dev->dev, @@ -738,7 +677,7 @@ static int lirc_serial_probe(struct platform_device *dev) return result; /* Initialize pulse/space widths */ - init_timing_params(duty_cycle, freq); + init_timing_params(50, 38000); /* If pin is high, then this must be an active low receiver. */ if (sense == -1) { @@ -769,12 +708,12 @@ static int lirc_serial_probe(struct platform_device *dev) return 0; } -static int set_use_inc(void *data) +static int serial_ir_open(struct rc_dev *rcdev) { unsigned long flags; /* initialize timestamp */ - lastkt = ktime_get(); + serial_ir.lastkt = ktime_get(); spin_lock_irqsave(&hardware[type].lock, flags); @@ -788,8 +727,9 @@ static int set_use_inc(void *data) return 0; } -static void set_use_dec(void *data) -{ unsigned long flags; +static void serial_ir_close(struct rc_dev *rcdev) +{ + unsigned long flags; spin_lock_irqsave(&hardware[type].lock, flags); @@ -802,136 +742,44 @@ static void set_use_dec(void *data) spin_unlock_irqrestore(&hardware[type].lock, flags); } -static ssize_t lirc_write(struct file *file, const char __user *buf, - size_t n, loff_t *ppos) +static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) { - int i, count; unsigned long flags; long delta = 0; - int *wbuf; - - if (!(hardware[type].features & LIRC_CAN_SEND_PULSE)) - return -EPERM; + int i; - count = n / sizeof(int); - if (n % sizeof(int) || count % 2 == 0) - return -EINVAL; - wbuf = memdup_user(buf, n); - if (IS_ERR(wbuf)) - return PTR_ERR(wbuf); spin_lock_irqsave(&hardware[type].lock, flags); - if (type == LIRC_IRDEO) { + if (type == IR_IRDEO) { /* DTR, RTS down */ on(); } for (i = 0; i < count; i++) { if (i%2) - hardware[type].send_space(wbuf[i] - delta); + hardware[type].send_space(txbuf[i] - delta); else - delta = hardware[type].send_pulse(wbuf[i]); + delta = hardware[type].send_pulse(txbuf[i]); } off(); spin_unlock_irqrestore(&hardware[type].lock, flags); - kfree(wbuf); - return n; + return count; } -static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle) { - int result; - u32 __user *uptr = (u32 __user *)arg; - u32 value; - - switch (cmd) { - case LIRC_GET_SEND_MODE: - if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) - return -ENOIOCTLCMD; - - result = put_user(LIRC_SEND2MODE - (hardware[type].features&LIRC_CAN_SEND_MASK), - uptr); - if (result) - return result; - break; - - case LIRC_SET_SEND_MODE: - if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) - return -ENOIOCTLCMD; - - result = get_user(value, uptr); - if (result) - return result; - /* only LIRC_MODE_PULSE supported */ - if (value != LIRC_MODE_PULSE) - return -EINVAL; - break; - - case LIRC_GET_LENGTH: - return -ENOIOCTLCMD; - - case LIRC_SET_SEND_DUTY_CYCLE: - pr_debug("SET_SEND_DUTY_CYCLE\n"); - if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) - return -ENOIOCTLCMD; - - result = get_user(value, uptr); - if (result) - return result; - if (value <= 0 || value > 100) - return -EINVAL; - return init_timing_params(value, freq); - - case LIRC_SET_SEND_CARRIER: - pr_debug("SET_SEND_CARRIER\n"); - if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) - return -ENOIOCTLCMD; - - result = get_user(value, uptr); - if (result) - return result; - if (value > 500000 || value < 20000) - return -EINVAL; - return init_timing_params(duty_cycle, value); - - default: - return lirc_dev_fop_ioctl(filep, cmd, arg); - } - return 0; + return init_timing_params(cycle, serial_ir.freq); } -static const struct file_operations lirc_fops = { - .owner = THIS_MODULE, - .write = lirc_write, - .unlocked_ioctl = lirc_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = lirc_ioctl, -#endif - .read = lirc_dev_fop_read, - .poll = lirc_dev_fop_poll, - .open = lirc_dev_fop_open, - .release = lirc_dev_fop_close, - .llseek = no_llseek, -}; - -static struct lirc_driver driver = { - .name = LIRC_DRIVER_NAME, - .minor = -1, - .code_length = 1, - .sample_rate = 0, - .data = NULL, - .add_to_buf = NULL, - .rbuf = &rbuf, - .set_use_inc = set_use_inc, - .set_use_dec = set_use_dec, - .fops = &lirc_fops, - .dev = NULL, - .owner = THIS_MODULE, -}; +static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) +{ + if (carrier > 500000 || carrier < 20000) + return -EINVAL; -static struct platform_device *lirc_serial_dev; + return init_timing_params(serial_ir.duty_cycle, carrier); +} -static int lirc_serial_suspend(struct platform_device *dev, - pm_message_t state) +static int serial_ir_suspend(struct platform_device *dev, + pm_message_t state) { /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); @@ -949,10 +797,7 @@ static int lirc_serial_suspend(struct platform_device *dev, return 0; } -/* twisty maze... need a forward-declaration here... */ -static void lirc_serial_exit(void); - -static int lirc_serial_resume(struct platform_device *dev) +static int serial_ir_resume(struct platform_device *dev) { unsigned long flags; int result; @@ -963,79 +808,68 @@ static int lirc_serial_resume(struct platform_device *dev) spin_lock_irqsave(&hardware[type].lock, flags); /* Enable Interrupt */ - lastkt = ktime_get(); + serial_ir.lastkt = ktime_get(); soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); off(); - lirc_buffer_clear(&rbuf); - spin_unlock_irqrestore(&hardware[type].lock, flags); return 0; } -static struct platform_driver lirc_serial_driver = { - .probe = lirc_serial_probe, - .suspend = lirc_serial_suspend, - .resume = lirc_serial_resume, +static struct platform_driver serial_ir_driver = { + .probe = serial_ir_probe, + .suspend = serial_ir_suspend, + .resume = serial_ir_resume, .driver = { - .name = "lirc_serial", + .name = "serial_ir", }, }; -static int __init lirc_serial_init(void) +static int __init serial_ir_init(void) { int result; - /* Init read buffer. */ - result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); - if (result < 0) + result = platform_driver_register(&serial_ir_driver); + if (result) return result; - result = platform_driver_register(&lirc_serial_driver); - if (result) { - printk("lirc register returned %d\n", result); - goto exit_buffer_free; - } - - lirc_serial_dev = platform_device_alloc("lirc_serial", 0); - if (!lirc_serial_dev) { + serial_ir.pdev = platform_device_alloc("serial_ir", 0); + if (!serial_ir.pdev) { result = -ENOMEM; goto exit_driver_unregister; } - result = platform_device_add(lirc_serial_dev); + result = platform_device_add(serial_ir.pdev); if (result) goto exit_device_put; return 0; exit_device_put: - platform_device_put(lirc_serial_dev); + platform_device_put(serial_ir.pdev); exit_driver_unregister: - platform_driver_unregister(&lirc_serial_driver); -exit_buffer_free: - lirc_buffer_free(&rbuf); + platform_driver_unregister(&serial_ir_driver); return result; } -static void lirc_serial_exit(void) +static void serial_ir_exit(void) { - platform_device_unregister(lirc_serial_dev); - platform_driver_unregister(&lirc_serial_driver); - lirc_buffer_free(&rbuf); + platform_device_unregister(serial_ir.pdev); + platform_driver_unregister(&serial_ir_driver); } -static int __init lirc_serial_init_module(void) +static int __init serial_ir_init_module(void) { + struct rc_dev *rcdev; int result; switch (type) { - case LIRC_HOMEBREW: - case LIRC_IRDEO: - case LIRC_IRDEO_REMOTE: - case LIRC_ANIMAX: - case LIRC_IGOR: + case IR_HOMEBREW: + case IR_IRDEO: + case IR_IRDEO_REMOTE: + case IR_ANIMAX: + case IR_IGOR: /* if nothing specified, use ttyS0/com1 and irq 4 */ io = io ? io : 0x3f8; irq = irq ? irq : 4; @@ -1045,11 +879,10 @@ static int __init lirc_serial_init_module(void) } if (!softcarrier) { switch (type) { - case LIRC_HOMEBREW: - case LIRC_IGOR: - hardware[type].features &= - ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| - LIRC_CAN_SET_SEND_CARRIER); + case IR_HOMEBREW: + case IR_IGOR: + hardware[type].set_send_carrier = false; + hardware[type].set_duty_cycle = false; break; } } @@ -1058,73 +891,111 @@ static int __init lirc_serial_init_module(void) if (sense != -1) sense = !!sense; - result = lirc_serial_init(); + result = serial_ir_init(); if (result) return result; - driver.features = hardware[type].features; - driver.dev = &lirc_serial_dev->dev; - driver.minor = lirc_register_driver(&driver); - if (driver.minor < 0) { - pr_err("register_chrdev failed!\n"); - lirc_serial_exit(); - return driver.minor; + rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev); + if (!rcdev) { + result = -ENOMEM; + goto serial_cleanup; } - return 0; + + if (hardware[type].send_pulse && hardware[type].send_space) + rcdev->tx_ir = serial_ir_tx; + if (hardware[type].set_send_carrier) + rcdev->s_tx_carrier = serial_ir_tx_carrier; + if (hardware[type].set_duty_cycle) + rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; + + switch (type) { + case IR_HOMEBREW: + rcdev->input_name = "Serial IR type home-brew"; + break; + case IR_IRDEO: + rcdev->input_name = "Serial IR type IRdeo"; + break; + case IR_IRDEO_REMOTE: + rcdev->input_name = "Serial IR type IRdeo remote"; + break; + case IR_ANIMAX: + rcdev->input_name = "Serial IR type AnimaX"; + break; + case IR_IGOR: + rcdev->input_name = "Serial IR type IgorPlug"; + break; + } + + rcdev->input_phys = KBUILD_MODNAME "/input0"; + rcdev->input_id.bustype = BUS_HOST; + rcdev->input_id.vendor = 0x0001; + rcdev->input_id.product = 0x0001; + rcdev->input_id.version = 0x0100; + rcdev->open = serial_ir_open; + rcdev->close = serial_ir_close; + rcdev->dev.parent = &serial_ir.pdev->dev; + rcdev->driver_type = RC_DRIVER_IR_RAW; + rcdev->allowed_protocols = RC_BIT_ALL; + rcdev->driver_name = KBUILD_MODNAME; + rcdev->map_name = RC_MAP_RC6_MCE; + rcdev->timeout = IR_DEFAULT_TIMEOUT; + rcdev->rx_resolution = 250000; + + serial_ir.rcdev = rcdev; + + result = rc_register_device(rcdev); + + if (!result) + return 0; +serial_cleanup: + serial_ir_exit(); + return result; } -static void __exit lirc_serial_exit_module(void) +static void __exit serial_ir_exit_module(void) { - lirc_unregister_driver(driver.minor); - lirc_serial_exit(); - pr_debug("cleaned up module\n"); + rc_unregister_device(serial_ir.rcdev); + serial_ir_exit(); } - -module_init(lirc_serial_init_module); -module_exit(lirc_serial_exit_module); +module_init(serial_ir_init_module); +module_exit(serial_ir_exit_module); MODULE_DESCRIPTION("Infra-red receiver driver for serial ports."); -MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, " - "Christoph Bartelmus, Andrei Tanas"); +MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus, Andrei Tanas"); MODULE_LICENSE("GPL"); -module_param(type, int, S_IRUGO); -MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo," - " 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug," - " 5 = NSLU2 RX:CTS2/TX:GreenLED)"); +module_param(type, int, 0444); +MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug"); -module_param(io, int, S_IRUGO); +module_param(io, int, 0444); MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); /* some architectures (e.g. intel xscale) have memory mapped registers */ -module_param(iommap, bool, S_IRUGO); -MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O" - " (0 = no memory mapped io)"); +module_param(iommap, bool, 0444); +MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)"); /* * some architectures (e.g. intel xscale) align the 8bit serial registers * on 32bit word boundaries. * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out() */ -module_param(ioshift, int, S_IRUGO); +module_param(ioshift, int, 0444); MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)"); -module_param(irq, int, S_IRUGO); +module_param(irq, int, 0444); MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); -module_param(share_irq, bool, S_IRUGO); +module_param(share_irq, bool, 0444); MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)"); -module_param(sense, int, S_IRUGO); -MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit" - " (0 = active high, 1 = active low )"); +module_param(sense, int, 0444); +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit (0 = active high, 1 = active low )"); -#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER -module_param(txsense, bool, S_IRUGO); -MODULE_PARM_DESC(txsense, "Sense of transmitter circuit" - " (0 = active high, 1 = active low )"); +#ifdef CONFIG_IR_SERIAL_TRANSMITTER +module_param(txsense, bool, 0444); +MODULE_PARM_DESC(txsense, "Sense of transmitter circuit (0 = active high, 1 = active low )"); #endif -module_param(softcarrier, bool, S_IRUGO); +module_param(softcarrier, bool, 0444); MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)"); -- cgit v1.2.3 From 0a847634849c64f6f477c68fb0e4baa24b09abd1 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 21 Nov 2016 19:55:52 -0200 Subject: [media] lirc_serial: use precision ktime rather than guessing This makes transmission more reliable and the code much cleaner. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_serial.c | 286 +++++++------------------------ 1 file changed, 65 insertions(+), 221 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 05a8a47aecef..7d1c2afcfdb5 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -21,29 +21,6 @@ * GNU General Public License for more details. */ -/* - * Steve's changes to improve transmission fidelity: - * - for systems with the rdtsc instruction and the clock counter, a - * send_pule that times the pulses directly using the counter. - * This means that the IR_SERIAL_TRANSMITTER_LATENCY fudge is - * not needed. Measurement shows very stable waveform, even where - * PCI activity slows the access to the UART, which trips up other - * versions. - * - For other system, non-integer-microsecond pulse/space lengths, - * done using fixed point binary. So, much more accurate carrier - * frequency. - * - fine tuned transmitter latency, taking advantage of fractional - * microseconds in previous change - * - Fixed bug in the way transmitter latency was accounted for by - * tuning the pulse lengths down - the send_pulse routine ignored - * this overhead as it timed the overall pulse length - so the - * pulse frequency was right but overall pulse length was too - * long. Fixed by accounting for latency on each pulse/space - * iteration. - * - * Steve Davies July 2001 - */ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include @@ -64,8 +41,8 @@ struct serial_ir_hw { u8 off; unsigned set_send_carrier:1; unsigned set_duty_cycle:1; - long (*send_pulse)(unsigned long length); - void (*send_space)(long length); + void (*send_pulse)(unsigned int length, ktime_t edge); + void (*send_space)(void); spinlock_t lock; }; @@ -87,11 +64,11 @@ static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ static bool txsense; /* 0 = active high, 1 = active low */ /* forward declarations */ -static long send_pulse_irdeo(unsigned long length); -static void send_space_irdeo(long length); +static void send_pulse_irdeo(unsigned int length, ktime_t edge); +static void send_space_irdeo(void); #ifdef CONFIG_IR_SERIAL_TRANSMITTER -static long send_pulse_homebrew(unsigned long length); -static void send_space_homebrew(long length); +static void send_pulse_homebrew(unsigned int length, ktime_t edge); +static void send_space_homebrew(void); #endif static struct serial_ir_hw hardware[] = { @@ -137,8 +114,6 @@ static struct serial_ir_hw hardware[] = { .signal_pin_change = UART_MSR_DDCD, .on = 0, .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .send_pulse = NULL, - .send_space = NULL, }, [IR_IGOR] = { @@ -166,51 +141,11 @@ struct serial_ir { unsigned int freq; unsigned int duty_cycle; - unsigned long period; - unsigned long pulse_width, space_width; + unsigned int pulse_width, space_width; }; static struct serial_ir serial_ir; -#if defined(__i386__) -/* - * From: - * Linux I/O port programming mini-HOWTO - * Author: Riku Saikkonen - * v, 28 December 1997 - * - * [...] - * Actually, a port I/O instruction on most ports in the 0-0x3ff range - * takes almost exactly 1 microsecond, so if you're, for example, using - * the parallel port directly, just do additional inb()s from that port - * to delay. - * [...] - */ -/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from - * comment above plus trimming to match actual measured frequency. - * This will be sensitive to cpu speed, though hopefully most of the 1.5us - * is spent in the uart access. Still - for reference test machine was a - * 1.13GHz Athlon system - Steve - */ - -/* - * changed from 400 to 450 as this works better on slower machines; - * faster machines will use the rdtsc code anyway - */ -#define IR_SERIAL_TRANSMITTER_LATENCY 450 - -#else - -/* does anybody have information on other platforms ? */ -/* 256 = 1<<8 */ -#define IR_SERIAL_TRANSMITTER_LATENCY 256 - -#endif /* __i386__ */ -/* - * FIXME: should we be using hrtimers instead of this - * IR_SERIAL_TRANSMITTER_LATENCY nonsense? - */ - /* fetch serial input packet (1 byte) from register offset */ static u8 sinp(int offset) { @@ -247,96 +182,21 @@ static void off(void) soutp(UART_MCR, hardware[type].off); } -#ifndef MAX_UDELAY_MS -#define MAX_UDELAY_US 5000 -#else -#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) -#endif - -static void safe_udelay(unsigned long usecs) +static void init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) { - while (usecs > MAX_UDELAY_US) { - udelay(MAX_UDELAY_US); - usecs -= MAX_UDELAY_US; - } - udelay(usecs); -} - -#ifdef USE_RDTSC -/* - * This is an overflow/precision juggle, complicated in that we can't - * do long long divide in the kernel - */ - -/* - * When we use the rdtsc instruction to measure clocks, we keep the - * pulse and space widths as clock cycles. As this is CPU speed - * dependent, the widths must be calculated in init_port and ioctl - * time - */ - -static int init_timing_params(unsigned int new_duty_cycle, - unsigned int new_freq) -{ - __u64 loops_per_sec, work; - serial_ir.duty_cycle = new_duty_cycle; serial_ir.freq = new_freq; - loops_per_sec = __this_cpu_read(cpu.info.loops_per_jiffy); - loops_per_sec *= HZ; - - /* How many clocks in a microsecond?, avoiding long long divide */ - work = loops_per_sec; - work *= 4295; /* 4295 = 2^32 / 1e6 */ - - /* - * Carrier period in clocks, approach good up to 32GHz clock, - * gets carrier frequency within 8Hz - */ - serial_ir.period = loops_per_sec >> 3; - serial_ir.pperiod /= (freq >> 3); - - /* Derive pulse and space from the period */ - serial_ir.ppulse_width = serial_ir.period * serial.ir.duty_cycle / 100; - serial_ir.pspace_width = serial_ir.period - serial_ir.pulse_width; - pr_debug("in init_timing_params, freq=%d, duty_cycle=%d, clk/jiffy=%ld, pulse=%ld, space=%ld, conv_us_to_clocks=%ld\n", - freq, duty_cycle, __this_cpu_read(cpu_info.loops_per_jiffy), - pulse_width, space_width, conv_us_to_clocks); - return 0; -} -#else /* ! USE_RDTSC */ -static int init_timing_params(unsigned int new_duty_cycle, - unsigned int new_freq) -{ -/* - * period, pulse/space width are kept with 8 binary places - - * IE multiplied by 256. - */ - if (256 * 1000000L / new_freq * new_duty_cycle / 100 <= - IR_SERIAL_TRANSMITTER_LATENCY) - return -EINVAL; - if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <= - IR_SERIAL_TRANSMITTER_LATENCY) - return -EINVAL; - serial_ir.duty_cycle = new_duty_cycle; - serial_ir.freq = new_freq; - serial_ir.period = 256 * 1000000L / serial_ir.freq; - serial_ir.pulse_width = serial_ir.period * serial_ir.duty_cycle / 100; - serial_ir.space_width = serial_ir.period - serial_ir.pulse_width; - pr_debug("in init_timing_params, freq=%d pulse=%ld, space=%ld\n", - serial_ir.freq, serial_ir.pulse_width, - serial_ir.space_width); - return 0; + serial_ir.pulse_width = DIV_ROUND_CLOSEST( + new_duty_cycle * NSEC_PER_SEC, new_freq * 100l); + serial_ir.space_width = DIV_ROUND_CLOSEST( + (100l - new_duty_cycle) * NSEC_PER_SEC, new_freq * 100l); } -#endif /* USE_RDTSC */ - -/* return value: space length delta */ - -static long send_pulse_irdeo(unsigned long length) +static void send_pulse_irdeo(unsigned int length, ktime_t target) { - long rawbits, ret; + long rawbits; int i; unsigned char output; unsigned char chunk, shifted; @@ -365,84 +225,53 @@ static long send_pulse_irdeo(unsigned long length) while (!(sinp(UART_LSR) & UART_LSR_TEMT)) ; } - - if (i == 0) - ret = (-rawbits) * 10000 / 1152; - else - ret = (3 - i) * 3 * 10000 / 1152 + (-rawbits) * 10000 / 1152; - - return ret; } -/* Version using udelay() */ - -/* - * here we use fixed point arithmetic, with 8 - * fractional bits. that gets us within 0.1% or so of the right average - * frequency, albeit with some jitter in pulse length - Steve - * - * This should use ndelay instead. - */ - -/* To match 8 fractional bits used for pulse/space length */ - -static void send_space_irdeo(long length) +static void send_space_irdeo(void) { - if (length <= 0) - return; - - safe_udelay(length); } #ifdef CONFIG_IR_SERIAL_TRANSMITTER -static long send_pulse_homebrew_softcarrier(unsigned long length) +static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge) { - int flag; - unsigned long actual, target, d; - - length <<= 8; + ktime_t now, target = ktime_add_us(edge, length); + /* + * delta should never exceed 4 seconds and on m68k + * ndelay(s64) does not compile; so use s32 rather than s64. + */ + s32 delta; - actual = 0; target = 0; flag = 0; - while (actual < length) { - if (flag) { - off(); - target += serial_ir.space_width; - } else { - on(); - target += serial_ir.pulse_width; - } - d = (target - actual - - IR_SERIAL_TRANSMITTER_LATENCY + 128) >> 8; - /* - * Note - we've checked in ioctl that the pulse/space - * widths are big enough so that d is > 0 - */ - udelay(d); - actual += (d << 8) + IR_SERIAL_TRANSMITTER_LATENCY; - flag = !flag; + for (;;) { + now = ktime_get(); + if (ktime_compare(now, target) >= 0) + break; + on(); + edge = ktime_add_ns(edge, serial_ir.pulse_width); + delta = ktime_to_ns(ktime_sub(edge, now)); + if (delta > 0) + ndelay(delta); + now = ktime_get(); + off(); + if (ktime_compare(now, target) >= 0) + break; + edge = ktime_add_ns(edge, serial_ir.space_width); + delta = ktime_to_ns(ktime_sub(edge, now)); + if (delta > 0) + ndelay(delta); } - return (actual-length) >> 8; } -static long send_pulse_homebrew(unsigned long length) +static void send_pulse_homebrew(unsigned int length, ktime_t edge) { - if (length <= 0) - return 0; - if (softcarrier) - return send_pulse_homebrew_softcarrier(length); - - on(); - safe_udelay(length); - return 0; + send_pulse_homebrew_softcarrier(length, edge); + else + on(); } -static void send_space_homebrew(long length) +static void send_space_homebrew(void) { off(); - if (length <= 0) - return; - safe_udelay(length); } #endif @@ -746,7 +575,8 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, unsigned int count) { unsigned long flags; - long delta = 0; + ktime_t edge; + s64 delta; int i; spin_lock_irqsave(&hardware[type].lock, flags); @@ -754,11 +584,23 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, /* DTR, RTS down */ on(); } + + edge = ktime_get(); for (i = 0; i < count; i++) { if (i%2) - hardware[type].send_space(txbuf[i] - delta); + hardware[type].send_space(); else - delta = hardware[type].send_pulse(txbuf[i]); + hardware[type].send_pulse(txbuf[i], edge); + + edge = ktime_add_us(edge, txbuf[i]); + delta = ktime_us_delta(edge, ktime_get()); + if (delta > 25) { + spin_unlock_irqrestore(&hardware[type].lock, flags); + usleep_range(delta - 25, delta + 25); + spin_lock_irqsave(&hardware[type].lock, flags); + } + else if (delta > 0) + udelay(delta); } off(); spin_unlock_irqrestore(&hardware[type].lock, flags); @@ -767,7 +609,8 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle) { - return init_timing_params(cycle, serial_ir.freq); + init_timing_params(cycle, serial_ir.freq); + return 0; } static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) @@ -775,7 +618,8 @@ static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) if (carrier > 500000 || carrier < 20000) return -EINVAL; - return init_timing_params(serial_ir.duty_cycle, carrier); + init_timing_params(serial_ir.duty_cycle, carrier); + return 0; } static int serial_ir_suspend(struct platform_device *dev, -- cgit v1.2.3 From a6f6ad4173b31bb900d69689b6dfb0c01968abbd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Nov 2016 05:46:14 -0200 Subject: lirc_serial: make checkpatch happy There are a few checkpatch complains here. As we're about to promote this driver out of staging, address them. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_serial.c | 37 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 7d1c2afcfdb5..9691ba4d55b9 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -352,8 +352,8 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) dev_err(&serial_ir.pdev->dev, "Trapped in interrupt"); break; } - if ((status & hardware[type].signal_pin_change) - && sense != -1) { + if ((status & hardware[type].signal_pin_change) && + sense != -1) { /* get current time */ kt = ktime_get(); @@ -377,7 +377,7 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) delkt = ktime_sub(kt, serial_ir.lastkt); if (ktime_compare(delkt, ktime_set(15, 0)) > 0) { data = IR_MAX_DURATION; /* really long time */ - if (!(dcd^sense)) { + if (!(dcd ^ sense)) { /* sanity check */ dev_err(&serial_ir.pdev->dev, "dcd unexpected: %d %d %lldns %lldns\n", @@ -389,8 +389,9 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) */ sense = sense ? 0 : 1; } - } else + } else { data = ktime_to_ns(delkt); + } frbwrite(data, !(dcd ^ sense)); serial_ir.lastkt = kt; last_dcd = dcd; @@ -400,7 +401,6 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) return IRQ_HANDLED; } - static int hardware_init_port(void) { u8 scratch, scratch2, scratch3; @@ -432,7 +432,7 @@ static int hardware_init_port(void) /* First of all, disable all interrupts */ soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); /* Clear registers. */ sinp(UART_LSR); @@ -487,12 +487,11 @@ static int serial_ir_probe(struct platform_device *dev) } /* Reserve io region. */ - if (((iommap) - && (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, - KBUILD_MODNAME) == NULL)) - || ((!iommap) - && (devm_request_region(&dev->dev, io, 8, - KBUILD_MODNAME) == NULL))) { + if ((iommap && + (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, + KBUILD_MODNAME) == NULL)) || + (!iommap && (devm_request_region(&dev->dev, io, 8, + KBUILD_MODNAME) == NULL))) { dev_err(&dev->dev, "port %04x already in use\n", io); dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n"); dev_warn(&dev->dev, @@ -549,7 +548,7 @@ static int serial_ir_open(struct rc_dev *rcdev) /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); spin_unlock_irqrestore(&hardware[type].lock, flags); @@ -567,7 +566,7 @@ static void serial_ir_close(struct rc_dev *rcdev) /* First of all, disable all interrupts */ soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); spin_unlock_irqrestore(&hardware[type].lock, flags); } @@ -587,7 +586,7 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, edge = ktime_get(); for (i = 0; i < count; i++) { - if (i%2) + if (i % 2) hardware[type].send_space(); else hardware[type].send_pulse(txbuf[i], edge); @@ -598,9 +597,9 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, spin_unlock_irqrestore(&hardware[type].lock, flags); usleep_range(delta - 25, delta + 25); spin_lock_irqsave(&hardware[type].lock, flags); - } - else if (delta > 0) + } else if (delta > 0) { udelay(delta); + } } off(); spin_unlock_irqrestore(&hardware[type].lock, flags); @@ -630,7 +629,7 @@ static int serial_ir_suspend(struct platform_device *dev, /* Disable all interrupts */ soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); /* Clear registers. */ sinp(UART_LSR); @@ -653,7 +652,7 @@ static int serial_ir_resume(struct platform_device *dev) spin_lock_irqsave(&hardware[type].lock, flags); /* Enable Interrupt */ serial_ir.lastkt = ktime_get(); - soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); off(); spin_unlock_irqrestore(&hardware[type].lock, flags); -- cgit v1.2.3 From fa5dc29c1fcc9151c3bcfd9e291a2899ae15f61d Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 21 Nov 2016 19:55:53 -0200 Subject: [media] lirc_serial: move out of staging and rename to serial_ir Signed-off-by: Sean Young --- MAINTAINERS | 6 + drivers/media/rc/Kconfig | 17 + drivers/media/rc/Makefile | 1 + drivers/media/rc/serial_ir.c | 844 +++++++++++++++++++++++++++++++ drivers/staging/media/lirc/Kconfig | 13 - drivers/staging/media/lirc/Makefile | 1 - drivers/staging/media/lirc/lirc_serial.c | 844 ------------------------------- 7 files changed, 868 insertions(+), 858 deletions(-) create mode 100644 drivers/media/rc/serial_ir.c delete mode 100644 drivers/staging/media/lirc/lirc_serial.c diff --git a/MAINTAINERS b/MAINTAINERS index 3db2078e0e47..52cc0775a799 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10631,6 +10631,12 @@ S: Maintained F: Documentation/devicetree/bindings/serial/ F: drivers/tty/serial/ +SERIAL IR RECEIVER +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/serial_ir.c + STI CEC DRIVER M: Benjamin Gaignard L: kernel@stlinux.com diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 370e16e07867..629e8ca15ab3 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -389,4 +389,21 @@ config IR_SUNXI To compile this driver as a module, choose M here: the module will be called sunxi-ir. +config IR_SERIAL + tristate "Homebrew Serial Port Receiver" + depends on RC_CORE + ---help--- + Say Y if you want to use Homebrew Serial Port Receivers and + Transceivers. + + To compile this driver as a module, choose M here: the module will + be called serial-ir. + +config IR_SERIAL_TRANSMITTER + bool "Serial Port Transmitter" + default y + depends on IR_SERIAL + ---help--- + Serial Port Transmitter support + endif #RC_DEVICES diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 379a5c0f1379..3a984ee301e2 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o obj-$(CONFIG_RC_ST) += st_rc.o obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o obj-$(CONFIG_IR_IMG) += img-ir/ +obj-$(CONFIG_IR_SERIAL) += serial_ir.o diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c new file mode 100644 index 000000000000..ba83b20913cd --- /dev/null +++ b/drivers/media/rc/serial_ir.c @@ -0,0 +1,844 @@ +/* + * serial_ir.c + * + * serial_ir - Device driver that records pulse- and pause-lengths + * (space-lengths) between DDCD event on a serial port. + * + * Copyright (C) 1996,97 Ralph Metzler + * Copyright (C) 1998 Trent Piepho + * Copyright (C) 1998 Ben Pfaff + * Copyright (C) 1999 Christoph Bartelmus + * Copyright (C) 2007 Andrei Tanas (suspend/resume support) + * Copyright (C) 2016 Sean Young (port to rc-core) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct serial_ir_hw { + int signal_pin; + int signal_pin_change; + u8 on; + u8 off; + unsigned set_send_carrier:1; + unsigned set_duty_cycle:1; + void (*send_pulse)(unsigned int length, ktime_t edge); + void (*send_space)(void); + spinlock_t lock; +}; + +#define IR_HOMEBREW 0 +#define IR_IRDEO 1 +#define IR_IRDEO_REMOTE 2 +#define IR_ANIMAX 3 +#define IR_IGOR 4 + +/* module parameters */ +static int type; +static int io; +static int irq; +static bool iommap; +static int ioshift; +static bool softcarrier = true; +static bool share_irq; +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ +static bool txsense; /* 0 = active high, 1 = active low */ + +/* forward declarations */ +static void send_pulse_irdeo(unsigned int length, ktime_t edge); +static void send_space_irdeo(void); +#ifdef CONFIG_IR_SERIAL_TRANSMITTER +static void send_pulse_homebrew(unsigned int length, ktime_t edge); +static void send_space_homebrew(void); +#endif + +static struct serial_ir_hw hardware[] = { + [IR_HOMEBREW] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_HOMEBREW].lock), + .signal_pin = UART_MSR_DCD, + .signal_pin_change = UART_MSR_DDCD, + .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), + .off = (UART_MCR_RTS | UART_MCR_OUT2), +#ifdef CONFIG_IR_SERIAL_TRANSMITTER + .send_pulse = send_pulse_homebrew, + .send_space = send_space_homebrew, + .set_send_carrier = true, + .set_duty_cycle = true, +#endif + }, + + [IR_IRDEO] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO].lock), + .signal_pin = UART_MSR_DSR, + .signal_pin_change = UART_MSR_DDSR, + .on = UART_MCR_OUT2, + .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), + .send_pulse = send_pulse_irdeo, + .send_space = send_space_irdeo, + .set_duty_cycle = true, + }, + + [IR_IRDEO_REMOTE] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO_REMOTE].lock), + .signal_pin = UART_MSR_DSR, + .signal_pin_change = UART_MSR_DDSR, + .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), + .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), + .send_pulse = send_pulse_irdeo, + .send_space = send_space_irdeo, + .set_duty_cycle = true, + }, + + [IR_ANIMAX] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_ANIMAX].lock), + .signal_pin = UART_MSR_DCD, + .signal_pin_change = UART_MSR_DDCD, + .on = 0, + .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), + }, + + [IR_IGOR] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IGOR].lock), + .signal_pin = UART_MSR_DSR, + .signal_pin_change = UART_MSR_DDSR, + .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), + .off = (UART_MCR_RTS | UART_MCR_OUT2), +#ifdef CONFIG_IR_SERIAL_TRANSMITTER + .send_pulse = send_pulse_homebrew, + .send_space = send_space_homebrew, + .set_send_carrier = true, + .set_duty_cycle = true, +#endif + }, +}; + +#define RS_ISR_PASS_LIMIT 256 + +struct serial_ir { + ktime_t lastkt; + struct rc_dev *rcdev; + struct platform_device *pdev; + + unsigned int freq; + unsigned int duty_cycle; + + unsigned int pulse_width, space_width; +}; + +static struct serial_ir serial_ir; + +/* fetch serial input packet (1 byte) from register offset */ +static u8 sinp(int offset) +{ + if (iommap) + /* the register is memory-mapped */ + offset <<= ioshift; + + return inb(io + offset); +} + +/* write serial output packet (1 byte) of value to register offset */ +static void soutp(int offset, u8 value) +{ + if (iommap) + /* the register is memory-mapped */ + offset <<= ioshift; + + outb(value, io + offset); +} + +static void on(void) +{ + if (txsense) + soutp(UART_MCR, hardware[type].off); + else + soutp(UART_MCR, hardware[type].on); +} + +static void off(void) +{ + if (txsense) + soutp(UART_MCR, hardware[type].on); + else + soutp(UART_MCR, hardware[type].off); +} + +static void init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ + serial_ir.duty_cycle = new_duty_cycle; + serial_ir.freq = new_freq; + + serial_ir.pulse_width = DIV_ROUND_CLOSEST( + new_duty_cycle * NSEC_PER_SEC, new_freq * 100l); + serial_ir.space_width = DIV_ROUND_CLOSEST( + (100l - new_duty_cycle) * NSEC_PER_SEC, new_freq * 100l); +} + +static void send_pulse_irdeo(unsigned int length, ktime_t target) +{ + long rawbits; + int i; + unsigned char output; + unsigned char chunk, shifted; + + /* how many bits have to be sent ? */ + rawbits = length * 1152 / 10000; + if (serial_ir.duty_cycle > 50) + chunk = 3; + else + chunk = 1; + for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { + shifted = chunk << (i * 3); + shifted >>= 1; + output &= (~shifted); + i++; + if (i == 3) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_THRE)) + ; + output = 0x7f; + i = 0; + } + } + if (i != 0) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_TEMT)) + ; + } +} + +static void send_space_irdeo(void) +{ +} + +#ifdef CONFIG_IR_SERIAL_TRANSMITTER +static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge) +{ + ktime_t now, target = ktime_add_us(edge, length); + /* + * delta should never exceed 4 seconds and on m68k + * ndelay(s64) does not compile; so use s32 rather than s64. + */ + s32 delta; + + for (;;) { + now = ktime_get(); + if (ktime_compare(now, target) >= 0) + break; + on(); + edge = ktime_add_ns(edge, serial_ir.pulse_width); + delta = ktime_to_ns(ktime_sub(edge, now)); + if (delta > 0) + ndelay(delta); + now = ktime_get(); + off(); + if (ktime_compare(now, target) >= 0) + break; + edge = ktime_add_ns(edge, serial_ir.space_width); + delta = ktime_to_ns(ktime_sub(edge, now)); + if (delta > 0) + ndelay(delta); + } +} + +static void send_pulse_homebrew(unsigned int length, ktime_t edge) +{ + if (softcarrier) + send_pulse_homebrew_softcarrier(length, edge); + else + on(); +} + +static void send_space_homebrew(void) +{ + off(); +} +#endif + +static void frbwrite(unsigned int l, bool is_pulse) +{ + /* simple noise filter */ + static unsigned int ptr, pulse, space; + DEFINE_IR_RAW_EVENT(ev); + + if (ptr > 0 && is_pulse) { + pulse += l; + if (pulse > 250000) { + ev.duration = space; + ev.pulse = false; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ev.duration = pulse; + ev.pulse = true; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ptr = 0; + pulse = 0; + } + return; + } + if (!is_pulse) { + if (ptr == 0) { + if (l > 20000000) { + space = l; + ptr++; + return; + } + } else { + if (l > 20000000) { + space += pulse; + if (space > IR_MAX_DURATION) + space = IR_MAX_DURATION; + space += l; + if (space > IR_MAX_DURATION) + space = IR_MAX_DURATION; + pulse = 0; + return; + } + + ev.duration = space; + ev.pulse = false; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ev.duration = pulse; + ev.pulse = true; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); + ptr = 0; + pulse = 0; + } + } + + ev.duration = l; + ev.pulse = is_pulse; + ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); +} + +static irqreturn_t serial_ir_irq_handler(int i, void *blah) +{ + ktime_t kt; + int counter, dcd; + u8 status; + ktime_t delkt; + unsigned int data; + static int last_dcd = -1; + + if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { + /* not our interrupt */ + return IRQ_NONE; + } + + counter = 0; + do { + counter++; + status = sinp(UART_MSR); + if (counter > RS_ISR_PASS_LIMIT) { + dev_err(&serial_ir.pdev->dev, "Trapped in interrupt"); + break; + } + if ((status & hardware[type].signal_pin_change) && + sense != -1) { + /* get current time */ + kt = ktime_get(); + + /* + * The driver needs to know if your receiver is + * active high or active low, or the space/pulse + * sense could be inverted. + */ + + /* calc time since last interrupt in nanoseconds */ + dcd = (status & hardware[type].signal_pin) ? 1 : 0; + + if (dcd == last_dcd) { + dev_err(&serial_ir.pdev->dev, + "ignoring spike: %d %d %lldns %lldns\n", + dcd, sense, ktime_to_ns(kt), + ktime_to_ns(serial_ir.lastkt)); + continue; + } + + delkt = ktime_sub(kt, serial_ir.lastkt); + if (ktime_compare(delkt, ktime_set(15, 0)) > 0) { + data = IR_MAX_DURATION; /* really long time */ + if (!(dcd ^ sense)) { + /* sanity check */ + dev_err(&serial_ir.pdev->dev, + "dcd unexpected: %d %d %lldns %lldns\n", + dcd, sense, ktime_to_ns(kt), + ktime_to_ns(serial_ir.lastkt)); + /* + * detecting pulse while this + * MUST be a space! + */ + sense = sense ? 0 : 1; + } + } else { + data = ktime_to_ns(delkt); + } + frbwrite(data, !(dcd ^ sense)); + serial_ir.lastkt = kt; + last_dcd = dcd; + ir_raw_event_handle(serial_ir.rcdev); + } + } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ + return IRQ_HANDLED; +} + +static int hardware_init_port(void) +{ + u8 scratch, scratch2, scratch3; + + /* + * This is a simple port existence test, borrowed from the autoconfig + * function in drivers/serial/8250.c + */ + scratch = sinp(UART_IER); + soutp(UART_IER, 0); +#ifdef __i386__ + outb(0xff, 0x080); +#endif + scratch2 = sinp(UART_IER) & 0x0f; + soutp(UART_IER, 0x0f); +#ifdef __i386__ + outb(0x00, 0x080); +#endif + scratch3 = sinp(UART_IER) & 0x0f; + soutp(UART_IER, scratch); + if (scratch2 != 0 || scratch3 != 0x0f) { + /* we fail, there's nothing here */ + pr_err("port existence test failed, cannot continue\n"); + return -ENODEV; + } + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + /* Set line for power source */ + off(); + + /* Clear registers again to be sure. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + switch (type) { + case IR_IRDEO: + case IR_IRDEO_REMOTE: + /* setup port to 7N1 @ 115200 Baud */ + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + /* Set DLAB 0 + 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + /* THR interrupt already disabled at this point */ + break; + default: + break; + } + + return 0; +} + +static int serial_ir_probe(struct platform_device *dev) +{ + int i, nlow, nhigh, result; + + result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, + share_irq ? IRQF_SHARED : 0, + KBUILD_MODNAME, &hardware); + if (result < 0) { + if (result == -EBUSY) + dev_err(&dev->dev, "IRQ %d busy\n", irq); + else if (result == -EINVAL) + dev_err(&dev->dev, "Bad irq number or handler\n"); + return result; + } + + /* Reserve io region. */ + if ((iommap && + (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, + KBUILD_MODNAME) == NULL)) || + (!iommap && (devm_request_region(&dev->dev, io, 8, + KBUILD_MODNAME) == NULL))) { + dev_err(&dev->dev, "port %04x already in use\n", io); + dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n"); + dev_warn(&dev->dev, + "or compile the serial port driver as module and\n"); + dev_warn(&dev->dev, "make sure this module is loaded first\n"); + return -EBUSY; + } + + result = hardware_init_port(); + if (result < 0) + return result; + + /* Initialize pulse/space widths */ + init_timing_params(50, 38000); + + /* If pin is high, then this must be an active low receiver. */ + if (sense == -1) { + /* wait 1/2 sec for the power supply */ + msleep(500); + + /* + * probe 9 times every 0.04s, collect "votes" for + * active high/low + */ + nlow = 0; + nhigh = 0; + for (i = 0; i < 9; i++) { + if (sinp(UART_MSR) & hardware[type].signal_pin) + nlow++; + else + nhigh++; + msleep(40); + } + sense = nlow >= nhigh ? 1 : 0; + dev_info(&dev->dev, "auto-detected active %s receiver\n", + sense ? "low" : "high"); + } else + dev_info(&dev->dev, "Manually using active %s receiver\n", + sense ? "low" : "high"); + + dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io); + return 0; +} + +static int serial_ir_open(struct rc_dev *rcdev) +{ + unsigned long flags; + + /* initialize timestamp */ + serial_ir.lastkt = ktime_get(); + + spin_lock_irqsave(&hardware[type].lock, flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); + + spin_unlock_irqrestore(&hardware[type].lock, flags); + + return 0; +} + +static void serial_ir_close(struct rc_dev *rcdev) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware[type].lock, flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); + spin_unlock_irqrestore(&hardware[type].lock, flags); +} + +static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) +{ + unsigned long flags; + ktime_t edge; + s64 delta; + int i; + + spin_lock_irqsave(&hardware[type].lock, flags); + if (type == IR_IRDEO) { + /* DTR, RTS down */ + on(); + } + + edge = ktime_get(); + for (i = 0; i < count; i++) { + if (i % 2) + hardware[type].send_space(); + else + hardware[type].send_pulse(txbuf[i], edge); + + edge = ktime_add_us(edge, txbuf[i]); + delta = ktime_us_delta(edge, ktime_get()); + if (delta > 25) { + spin_unlock_irqrestore(&hardware[type].lock, flags); + usleep_range(delta - 25, delta + 25); + spin_lock_irqsave(&hardware[type].lock, flags); + } else if (delta > 0) { + udelay(delta); + } + } + off(); + spin_unlock_irqrestore(&hardware[type].lock, flags); + return count; +} + +static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle) +{ + init_timing_params(cycle, serial_ir.freq); + return 0; +} + +static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) +{ + if (carrier > 500000 || carrier < 20000) + return -EINVAL; + + init_timing_params(serial_ir.duty_cycle, carrier); + return 0; +} + +static int serial_ir_suspend(struct platform_device *dev, + pm_message_t state) +{ + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + return 0; +} + +static int serial_ir_resume(struct platform_device *dev) +{ + unsigned long flags; + int result; + + result = hardware_init_port(); + if (result < 0) + return result; + + spin_lock_irqsave(&hardware[type].lock, flags); + /* Enable Interrupt */ + serial_ir.lastkt = ktime_get(); + soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); + off(); + + spin_unlock_irqrestore(&hardware[type].lock, flags); + + return 0; +} + +static struct platform_driver serial_ir_driver = { + .probe = serial_ir_probe, + .suspend = serial_ir_suspend, + .resume = serial_ir_resume, + .driver = { + .name = "serial_ir", + }, +}; + +static int __init serial_ir_init(void) +{ + int result; + + result = platform_driver_register(&serial_ir_driver); + if (result) + return result; + + serial_ir.pdev = platform_device_alloc("serial_ir", 0); + if (!serial_ir.pdev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(serial_ir.pdev); + if (result) + goto exit_device_put; + + return 0; + +exit_device_put: + platform_device_put(serial_ir.pdev); +exit_driver_unregister: + platform_driver_unregister(&serial_ir_driver); + return result; +} + +static void serial_ir_exit(void) +{ + platform_device_unregister(serial_ir.pdev); + platform_driver_unregister(&serial_ir_driver); +} + +static int __init serial_ir_init_module(void) +{ + struct rc_dev *rcdev; + int result; + + switch (type) { + case IR_HOMEBREW: + case IR_IRDEO: + case IR_IRDEO_REMOTE: + case IR_ANIMAX: + case IR_IGOR: + /* if nothing specified, use ttyS0/com1 and irq 4 */ + io = io ? io : 0x3f8; + irq = irq ? irq : 4; + break; + default: + return -EINVAL; + } + if (!softcarrier) { + switch (type) { + case IR_HOMEBREW: + case IR_IGOR: + hardware[type].set_send_carrier = false; + hardware[type].set_duty_cycle = false; + break; + } + } + + /* make sure sense is either -1, 0, or 1 */ + if (sense != -1) + sense = !!sense; + + result = serial_ir_init(); + if (result) + return result; + + rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev); + if (!rcdev) { + result = -ENOMEM; + goto serial_cleanup; + } + + if (hardware[type].send_pulse && hardware[type].send_space) + rcdev->tx_ir = serial_ir_tx; + if (hardware[type].set_send_carrier) + rcdev->s_tx_carrier = serial_ir_tx_carrier; + if (hardware[type].set_duty_cycle) + rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; + + switch (type) { + case IR_HOMEBREW: + rcdev->input_name = "Serial IR type home-brew"; + break; + case IR_IRDEO: + rcdev->input_name = "Serial IR type IRdeo"; + break; + case IR_IRDEO_REMOTE: + rcdev->input_name = "Serial IR type IRdeo remote"; + break; + case IR_ANIMAX: + rcdev->input_name = "Serial IR type AnimaX"; + break; + case IR_IGOR: + rcdev->input_name = "Serial IR type IgorPlug"; + break; + } + + rcdev->input_phys = KBUILD_MODNAME "/input0"; + rcdev->input_id.bustype = BUS_HOST; + rcdev->input_id.vendor = 0x0001; + rcdev->input_id.product = 0x0001; + rcdev->input_id.version = 0x0100; + rcdev->open = serial_ir_open; + rcdev->close = serial_ir_close; + rcdev->dev.parent = &serial_ir.pdev->dev; + rcdev->driver_type = RC_DRIVER_IR_RAW; + rcdev->allowed_protocols = RC_BIT_ALL; + rcdev->driver_name = KBUILD_MODNAME; + rcdev->map_name = RC_MAP_RC6_MCE; + rcdev->timeout = IR_DEFAULT_TIMEOUT; + rcdev->rx_resolution = 250000; + + serial_ir.rcdev = rcdev; + + result = rc_register_device(rcdev); + + if (!result) + return 0; +serial_cleanup: + serial_ir_exit(); + return result; +} + +static void __exit serial_ir_exit_module(void) +{ + rc_unregister_device(serial_ir.rcdev); + serial_ir_exit(); +} + +module_init(serial_ir_init_module); +module_exit(serial_ir_exit_module); + +MODULE_DESCRIPTION("Infra-red receiver driver for serial ports."); +MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus, Andrei Tanas"); +MODULE_LICENSE("GPL"); + +module_param(type, int, 0444); +MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); + +/* some architectures (e.g. intel xscale) have memory mapped registers */ +module_param(iommap, bool, 0444); +MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)"); + +/* + * some architectures (e.g. intel xscale) align the 8bit serial registers + * on 32bit word boundaries. + * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out() + */ +module_param(ioshift, int, 0444); +MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); + +module_param(share_irq, bool, 0444); +MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)"); + +module_param(sense, int, 0444); +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit (0 = active high, 1 = active low )"); + +#ifdef CONFIG_IR_SERIAL_TRANSMITTER +module_param(txsense, bool, 0444); +MODULE_PARM_DESC(txsense, "Sense of transmitter circuit (0 = active high, 1 = active low )"); +#endif + +module_param(softcarrier, bool, 0444); +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)"); diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig index 6879c4651b46..25b7e7ccf554 100644 --- a/drivers/staging/media/lirc/Kconfig +++ b/drivers/staging/media/lirc/Kconfig @@ -38,19 +38,6 @@ config LIRC_SASEM help Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module -config LIRC_SERIAL - tristate "Homebrew Serial Port Receiver" - depends on LIRC - help - Driver for Homebrew Serial Port Receivers - -config LIRC_SERIAL_TRANSMITTER - bool "Serial Port Transmitter" - default y - depends on LIRC_SERIAL - help - Serial Port Transmitter support - config LIRC_SIR tristate "Built-in SIR IrDA port" depends on LIRC diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile index 5430adf0475d..7f919eab1989 100644 --- a/drivers/staging/media/lirc/Makefile +++ b/drivers/staging/media/lirc/Makefile @@ -7,6 +7,5 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o obj-$(CONFIG_LIRC_IMON) += lirc_imon.o obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o -obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o obj-$(CONFIG_LIRC_SIR) += lirc_sir.o obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c deleted file mode 100644 index 9691ba4d55b9..000000000000 --- a/drivers/staging/media/lirc/lirc_serial.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * lirc_serial.c - * - * lirc_serial - Device driver that records pulse- and pause-lengths - * (space-lengths) between DDCD event on a serial port. - * - * Copyright (C) 1996,97 Ralph Metzler - * Copyright (C) 1998 Trent Piepho - * Copyright (C) 1998 Ben Pfaff - * Copyright (C) 1999 Christoph Bartelmus - * Copyright (C) 2007 Andrei Tanas (suspend/resume support) - * Copyright (C) 2016 Sean Young (port to rc-core) - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct serial_ir_hw { - int signal_pin; - int signal_pin_change; - u8 on; - u8 off; - unsigned set_send_carrier:1; - unsigned set_duty_cycle:1; - void (*send_pulse)(unsigned int length, ktime_t edge); - void (*send_space)(void); - spinlock_t lock; -}; - -#define IR_HOMEBREW 0 -#define IR_IRDEO 1 -#define IR_IRDEO_REMOTE 2 -#define IR_ANIMAX 3 -#define IR_IGOR 4 - -/* module parameters */ -static int type; -static int io; -static int irq; -static bool iommap; -static int ioshift; -static bool softcarrier = true; -static bool share_irq; -static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ -static bool txsense; /* 0 = active high, 1 = active low */ - -/* forward declarations */ -static void send_pulse_irdeo(unsigned int length, ktime_t edge); -static void send_space_irdeo(void); -#ifdef CONFIG_IR_SERIAL_TRANSMITTER -static void send_pulse_homebrew(unsigned int length, ktime_t edge); -static void send_space_homebrew(void); -#endif - -static struct serial_ir_hw hardware[] = { - [IR_HOMEBREW] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_HOMEBREW].lock), - .signal_pin = UART_MSR_DCD, - .signal_pin_change = UART_MSR_DDCD, - .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), - .off = (UART_MCR_RTS | UART_MCR_OUT2), -#ifdef CONFIG_IR_SERIAL_TRANSMITTER - .send_pulse = send_pulse_homebrew, - .send_space = send_space_homebrew, - .set_send_carrier = true, - .set_duty_cycle = true, -#endif - }, - - [IR_IRDEO] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO].lock), - .signal_pin = UART_MSR_DSR, - .signal_pin_change = UART_MSR_DDSR, - .on = UART_MCR_OUT2, - .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .send_pulse = send_pulse_irdeo, - .send_space = send_space_irdeo, - .set_duty_cycle = true, - }, - - [IR_IRDEO_REMOTE] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO_REMOTE].lock), - .signal_pin = UART_MSR_DSR, - .signal_pin_change = UART_MSR_DDSR, - .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - .send_pulse = send_pulse_irdeo, - .send_space = send_space_irdeo, - .set_duty_cycle = true, - }, - - [IR_ANIMAX] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_ANIMAX].lock), - .signal_pin = UART_MSR_DCD, - .signal_pin_change = UART_MSR_DDCD, - .on = 0, - .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), - }, - - [IR_IGOR] = { - .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IGOR].lock), - .signal_pin = UART_MSR_DSR, - .signal_pin_change = UART_MSR_DDSR, - .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), - .off = (UART_MCR_RTS | UART_MCR_OUT2), -#ifdef CONFIG_IR_SERIAL_TRANSMITTER - .send_pulse = send_pulse_homebrew, - .send_space = send_space_homebrew, - .set_send_carrier = true, - .set_duty_cycle = true, -#endif - }, -}; - -#define RS_ISR_PASS_LIMIT 256 - -struct serial_ir { - ktime_t lastkt; - struct rc_dev *rcdev; - struct platform_device *pdev; - - unsigned int freq; - unsigned int duty_cycle; - - unsigned int pulse_width, space_width; -}; - -static struct serial_ir serial_ir; - -/* fetch serial input packet (1 byte) from register offset */ -static u8 sinp(int offset) -{ - if (iommap) - /* the register is memory-mapped */ - offset <<= ioshift; - - return inb(io + offset); -} - -/* write serial output packet (1 byte) of value to register offset */ -static void soutp(int offset, u8 value) -{ - if (iommap) - /* the register is memory-mapped */ - offset <<= ioshift; - - outb(value, io + offset); -} - -static void on(void) -{ - if (txsense) - soutp(UART_MCR, hardware[type].off); - else - soutp(UART_MCR, hardware[type].on); -} - -static void off(void) -{ - if (txsense) - soutp(UART_MCR, hardware[type].on); - else - soutp(UART_MCR, hardware[type].off); -} - -static void init_timing_params(unsigned int new_duty_cycle, - unsigned int new_freq) -{ - serial_ir.duty_cycle = new_duty_cycle; - serial_ir.freq = new_freq; - - serial_ir.pulse_width = DIV_ROUND_CLOSEST( - new_duty_cycle * NSEC_PER_SEC, new_freq * 100l); - serial_ir.space_width = DIV_ROUND_CLOSEST( - (100l - new_duty_cycle) * NSEC_PER_SEC, new_freq * 100l); -} - -static void send_pulse_irdeo(unsigned int length, ktime_t target) -{ - long rawbits; - int i; - unsigned char output; - unsigned char chunk, shifted; - - /* how many bits have to be sent ? */ - rawbits = length * 1152 / 10000; - if (serial_ir.duty_cycle > 50) - chunk = 3; - else - chunk = 1; - for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { - shifted = chunk << (i * 3); - shifted >>= 1; - output &= (~shifted); - i++; - if (i == 3) { - soutp(UART_TX, output); - while (!(sinp(UART_LSR) & UART_LSR_THRE)) - ; - output = 0x7f; - i = 0; - } - } - if (i != 0) { - soutp(UART_TX, output); - while (!(sinp(UART_LSR) & UART_LSR_TEMT)) - ; - } -} - -static void send_space_irdeo(void) -{ -} - -#ifdef CONFIG_IR_SERIAL_TRANSMITTER -static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge) -{ - ktime_t now, target = ktime_add_us(edge, length); - /* - * delta should never exceed 4 seconds and on m68k - * ndelay(s64) does not compile; so use s32 rather than s64. - */ - s32 delta; - - for (;;) { - now = ktime_get(); - if (ktime_compare(now, target) >= 0) - break; - on(); - edge = ktime_add_ns(edge, serial_ir.pulse_width); - delta = ktime_to_ns(ktime_sub(edge, now)); - if (delta > 0) - ndelay(delta); - now = ktime_get(); - off(); - if (ktime_compare(now, target) >= 0) - break; - edge = ktime_add_ns(edge, serial_ir.space_width); - delta = ktime_to_ns(ktime_sub(edge, now)); - if (delta > 0) - ndelay(delta); - } -} - -static void send_pulse_homebrew(unsigned int length, ktime_t edge) -{ - if (softcarrier) - send_pulse_homebrew_softcarrier(length, edge); - else - on(); -} - -static void send_space_homebrew(void) -{ - off(); -} -#endif - -static void frbwrite(unsigned int l, bool is_pulse) -{ - /* simple noise filter */ - static unsigned int ptr, pulse, space; - DEFINE_IR_RAW_EVENT(ev); - - if (ptr > 0 && is_pulse) { - pulse += l; - if (pulse > 250000) { - ev.duration = space; - ev.pulse = false; - ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); - ev.duration = pulse; - ev.pulse = true; - ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); - ptr = 0; - pulse = 0; - } - return; - } - if (!is_pulse) { - if (ptr == 0) { - if (l > 20000000) { - space = l; - ptr++; - return; - } - } else { - if (l > 20000000) { - space += pulse; - if (space > IR_MAX_DURATION) - space = IR_MAX_DURATION; - space += l; - if (space > IR_MAX_DURATION) - space = IR_MAX_DURATION; - pulse = 0; - return; - } - - ev.duration = space; - ev.pulse = false; - ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); - ev.duration = pulse; - ev.pulse = true; - ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); - ptr = 0; - pulse = 0; - } - } - - ev.duration = l; - ev.pulse = is_pulse; - ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); -} - -static irqreturn_t serial_ir_irq_handler(int i, void *blah) -{ - ktime_t kt; - int counter, dcd; - u8 status; - ktime_t delkt; - unsigned int data; - static int last_dcd = -1; - - if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { - /* not our interrupt */ - return IRQ_NONE; - } - - counter = 0; - do { - counter++; - status = sinp(UART_MSR); - if (counter > RS_ISR_PASS_LIMIT) { - dev_err(&serial_ir.pdev->dev, "Trapped in interrupt"); - break; - } - if ((status & hardware[type].signal_pin_change) && - sense != -1) { - /* get current time */ - kt = ktime_get(); - - /* - * The driver needs to know if your receiver is - * active high or active low, or the space/pulse - * sense could be inverted. - */ - - /* calc time since last interrupt in nanoseconds */ - dcd = (status & hardware[type].signal_pin) ? 1 : 0; - - if (dcd == last_dcd) { - dev_err(&serial_ir.pdev->dev, - "ignoring spike: %d %d %lldns %lldns\n", - dcd, sense, ktime_to_ns(kt), - ktime_to_ns(serial_ir.lastkt)); - continue; - } - - delkt = ktime_sub(kt, serial_ir.lastkt); - if (ktime_compare(delkt, ktime_set(15, 0)) > 0) { - data = IR_MAX_DURATION; /* really long time */ - if (!(dcd ^ sense)) { - /* sanity check */ - dev_err(&serial_ir.pdev->dev, - "dcd unexpected: %d %d %lldns %lldns\n", - dcd, sense, ktime_to_ns(kt), - ktime_to_ns(serial_ir.lastkt)); - /* - * detecting pulse while this - * MUST be a space! - */ - sense = sense ? 0 : 1; - } - } else { - data = ktime_to_ns(delkt); - } - frbwrite(data, !(dcd ^ sense)); - serial_ir.lastkt = kt; - last_dcd = dcd; - ir_raw_event_handle(serial_ir.rcdev); - } - } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ - return IRQ_HANDLED; -} - -static int hardware_init_port(void) -{ - u8 scratch, scratch2, scratch3; - - /* - * This is a simple port existence test, borrowed from the autoconfig - * function in drivers/serial/8250.c - */ - scratch = sinp(UART_IER); - soutp(UART_IER, 0); -#ifdef __i386__ - outb(0xff, 0x080); -#endif - scratch2 = sinp(UART_IER) & 0x0f; - soutp(UART_IER, 0x0f); -#ifdef __i386__ - outb(0x00, 0x080); -#endif - scratch3 = sinp(UART_IER) & 0x0f; - soutp(UART_IER, scratch); - if (scratch2 != 0 || scratch3 != 0x0f) { - /* we fail, there's nothing here */ - pr_err("port existence test failed, cannot continue\n"); - return -ENODEV; - } - - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - /* First of all, disable all interrupts */ - soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); - - /* Clear registers. */ - sinp(UART_LSR); - sinp(UART_RX); - sinp(UART_IIR); - sinp(UART_MSR); - - /* Set line for power source */ - off(); - - /* Clear registers again to be sure. */ - sinp(UART_LSR); - sinp(UART_RX); - sinp(UART_IIR); - sinp(UART_MSR); - - switch (type) { - case IR_IRDEO: - case IR_IRDEO_REMOTE: - /* setup port to 7N1 @ 115200 Baud */ - /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ - - /* Set DLAB 1. */ - soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); - /* Set divisor to 1 => 115200 Baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 1); - /* Set DLAB 0 + 7N1 */ - soutp(UART_LCR, UART_LCR_WLEN7); - /* THR interrupt already disabled at this point */ - break; - default: - break; - } - - return 0; -} - -static int serial_ir_probe(struct platform_device *dev) -{ - int i, nlow, nhigh, result; - - result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, - share_irq ? IRQF_SHARED : 0, - KBUILD_MODNAME, &hardware); - if (result < 0) { - if (result == -EBUSY) - dev_err(&dev->dev, "IRQ %d busy\n", irq); - else if (result == -EINVAL) - dev_err(&dev->dev, "Bad irq number or handler\n"); - return result; - } - - /* Reserve io region. */ - if ((iommap && - (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, - KBUILD_MODNAME) == NULL)) || - (!iommap && (devm_request_region(&dev->dev, io, 8, - KBUILD_MODNAME) == NULL))) { - dev_err(&dev->dev, "port %04x already in use\n", io); - dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n"); - dev_warn(&dev->dev, - "or compile the serial port driver as module and\n"); - dev_warn(&dev->dev, "make sure this module is loaded first\n"); - return -EBUSY; - } - - result = hardware_init_port(); - if (result < 0) - return result; - - /* Initialize pulse/space widths */ - init_timing_params(50, 38000); - - /* If pin is high, then this must be an active low receiver. */ - if (sense == -1) { - /* wait 1/2 sec for the power supply */ - msleep(500); - - /* - * probe 9 times every 0.04s, collect "votes" for - * active high/low - */ - nlow = 0; - nhigh = 0; - for (i = 0; i < 9; i++) { - if (sinp(UART_MSR) & hardware[type].signal_pin) - nlow++; - else - nhigh++; - msleep(40); - } - sense = nlow >= nhigh ? 1 : 0; - dev_info(&dev->dev, "auto-detected active %s receiver\n", - sense ? "low" : "high"); - } else - dev_info(&dev->dev, "Manually using active %s receiver\n", - sense ? "low" : "high"); - - dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io); - return 0; -} - -static int serial_ir_open(struct rc_dev *rcdev) -{ - unsigned long flags; - - /* initialize timestamp */ - serial_ir.lastkt = ktime_get(); - - spin_lock_irqsave(&hardware[type].lock, flags); - - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); - - spin_unlock_irqrestore(&hardware[type].lock, flags); - - return 0; -} - -static void serial_ir_close(struct rc_dev *rcdev) -{ - unsigned long flags; - - spin_lock_irqsave(&hardware[type].lock, flags); - - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - /* First of all, disable all interrupts */ - soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); - spin_unlock_irqrestore(&hardware[type].lock, flags); -} - -static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, - unsigned int count) -{ - unsigned long flags; - ktime_t edge; - s64 delta; - int i; - - spin_lock_irqsave(&hardware[type].lock, flags); - if (type == IR_IRDEO) { - /* DTR, RTS down */ - on(); - } - - edge = ktime_get(); - for (i = 0; i < count; i++) { - if (i % 2) - hardware[type].send_space(); - else - hardware[type].send_pulse(txbuf[i], edge); - - edge = ktime_add_us(edge, txbuf[i]); - delta = ktime_us_delta(edge, ktime_get()); - if (delta > 25) { - spin_unlock_irqrestore(&hardware[type].lock, flags); - usleep_range(delta - 25, delta + 25); - spin_lock_irqsave(&hardware[type].lock, flags); - } else if (delta > 0) { - udelay(delta); - } - } - off(); - spin_unlock_irqrestore(&hardware[type].lock, flags); - return count; -} - -static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle) -{ - init_timing_params(cycle, serial_ir.freq); - return 0; -} - -static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) -{ - if (carrier > 500000 || carrier < 20000) - return -EINVAL; - - init_timing_params(serial_ir.duty_cycle, carrier); - return 0; -} - -static int serial_ir_suspend(struct platform_device *dev, - pm_message_t state) -{ - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - /* Disable all interrupts */ - soutp(UART_IER, sinp(UART_IER) & - (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); - - /* Clear registers. */ - sinp(UART_LSR); - sinp(UART_RX); - sinp(UART_IIR); - sinp(UART_MSR); - - return 0; -} - -static int serial_ir_resume(struct platform_device *dev) -{ - unsigned long flags; - int result; - - result = hardware_init_port(); - if (result < 0) - return result; - - spin_lock_irqsave(&hardware[type].lock, flags); - /* Enable Interrupt */ - serial_ir.lastkt = ktime_get(); - soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI); - off(); - - spin_unlock_irqrestore(&hardware[type].lock, flags); - - return 0; -} - -static struct platform_driver serial_ir_driver = { - .probe = serial_ir_probe, - .suspend = serial_ir_suspend, - .resume = serial_ir_resume, - .driver = { - .name = "serial_ir", - }, -}; - -static int __init serial_ir_init(void) -{ - int result; - - result = platform_driver_register(&serial_ir_driver); - if (result) - return result; - - serial_ir.pdev = platform_device_alloc("serial_ir", 0); - if (!serial_ir.pdev) { - result = -ENOMEM; - goto exit_driver_unregister; - } - - result = platform_device_add(serial_ir.pdev); - if (result) - goto exit_device_put; - - return 0; - -exit_device_put: - platform_device_put(serial_ir.pdev); -exit_driver_unregister: - platform_driver_unregister(&serial_ir_driver); - return result; -} - -static void serial_ir_exit(void) -{ - platform_device_unregister(serial_ir.pdev); - platform_driver_unregister(&serial_ir_driver); -} - -static int __init serial_ir_init_module(void) -{ - struct rc_dev *rcdev; - int result; - - switch (type) { - case IR_HOMEBREW: - case IR_IRDEO: - case IR_IRDEO_REMOTE: - case IR_ANIMAX: - case IR_IGOR: - /* if nothing specified, use ttyS0/com1 and irq 4 */ - io = io ? io : 0x3f8; - irq = irq ? irq : 4; - break; - default: - return -EINVAL; - } - if (!softcarrier) { - switch (type) { - case IR_HOMEBREW: - case IR_IGOR: - hardware[type].set_send_carrier = false; - hardware[type].set_duty_cycle = false; - break; - } - } - - /* make sure sense is either -1, 0, or 1 */ - if (sense != -1) - sense = !!sense; - - result = serial_ir_init(); - if (result) - return result; - - rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev); - if (!rcdev) { - result = -ENOMEM; - goto serial_cleanup; - } - - if (hardware[type].send_pulse && hardware[type].send_space) - rcdev->tx_ir = serial_ir_tx; - if (hardware[type].set_send_carrier) - rcdev->s_tx_carrier = serial_ir_tx_carrier; - if (hardware[type].set_duty_cycle) - rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; - - switch (type) { - case IR_HOMEBREW: - rcdev->input_name = "Serial IR type home-brew"; - break; - case IR_IRDEO: - rcdev->input_name = "Serial IR type IRdeo"; - break; - case IR_IRDEO_REMOTE: - rcdev->input_name = "Serial IR type IRdeo remote"; - break; - case IR_ANIMAX: - rcdev->input_name = "Serial IR type AnimaX"; - break; - case IR_IGOR: - rcdev->input_name = "Serial IR type IgorPlug"; - break; - } - - rcdev->input_phys = KBUILD_MODNAME "/input0"; - rcdev->input_id.bustype = BUS_HOST; - rcdev->input_id.vendor = 0x0001; - rcdev->input_id.product = 0x0001; - rcdev->input_id.version = 0x0100; - rcdev->open = serial_ir_open; - rcdev->close = serial_ir_close; - rcdev->dev.parent = &serial_ir.pdev->dev; - rcdev->driver_type = RC_DRIVER_IR_RAW; - rcdev->allowed_protocols = RC_BIT_ALL; - rcdev->driver_name = KBUILD_MODNAME; - rcdev->map_name = RC_MAP_RC6_MCE; - rcdev->timeout = IR_DEFAULT_TIMEOUT; - rcdev->rx_resolution = 250000; - - serial_ir.rcdev = rcdev; - - result = rc_register_device(rcdev); - - if (!result) - return 0; -serial_cleanup: - serial_ir_exit(); - return result; -} - -static void __exit serial_ir_exit_module(void) -{ - rc_unregister_device(serial_ir.rcdev); - serial_ir_exit(); -} - -module_init(serial_ir_init_module); -module_exit(serial_ir_exit_module); - -MODULE_DESCRIPTION("Infra-red receiver driver for serial ports."); -MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus, Andrei Tanas"); -MODULE_LICENSE("GPL"); - -module_param(type, int, 0444); -MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug"); - -module_param(io, int, 0444); -MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); - -/* some architectures (e.g. intel xscale) have memory mapped registers */ -module_param(iommap, bool, 0444); -MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)"); - -/* - * some architectures (e.g. intel xscale) align the 8bit serial registers - * on 32bit word boundaries. - * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out() - */ -module_param(ioshift, int, 0444); -MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)"); - -module_param(irq, int, 0444); -MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); - -module_param(share_irq, bool, 0444); -MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)"); - -module_param(sense, int, 0444); -MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit (0 = active high, 1 = active low )"); - -#ifdef CONFIG_IR_SERIAL_TRANSMITTER -module_param(txsense, bool, 0444); -MODULE_PARM_DESC(txsense, "Sense of transmitter circuit (0 = active high, 1 = active low )"); -#endif - -module_param(softcarrier, bool, 0444); -MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)"); -- cgit v1.2.3 From c60b4088108c44529e6f679d9e991e3d3c945950 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Nov 2016 06:17:44 -0200 Subject: [media] serial_ir: fix reference to 8250 serial code While checking why we need i386 checking, I noticed that the serial code referred at the driver was moved to another place. Update it to make clear from where such code came from. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/serial_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index ba83b20913cd..436bd58b5f05 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -407,7 +407,7 @@ static int hardware_init_port(void) /* * This is a simple port existence test, borrowed from the autoconfig - * function in drivers/serial/8250.c + * function in drivers/tty/serial/8250/8250_port.c */ scratch = sinp(UART_IER); soutp(UART_IER, 0); -- cgit v1.2.3 From e4e9aeaf8c2f6b2c4a5ca5049b9326de05384185 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:11 -0200 Subject: [media] media: ti-vpe: vpdma: Make vpdma library into its own module The VPDMA (Video Port DMA) as found in devices such as DRA7xx is used for both the Video Processing Engine (VPE) and the Video Input Port (VIP). In preparation for this we need to turn vpdma into its own kernel module. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 6 ++++++ drivers/media/platform/ti-vpe/Makefile | 4 +++- drivers/media/platform/ti-vpe/vpdma.c | 28 +++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 3c5a0b6b23a9..b52b6771fc4d 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -364,6 +364,7 @@ config VIDEO_TI_VPE depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV + select VIDEO_TI_VPDMA default n ---help--- Support for the TI VPE(Video Processing Engine) block @@ -377,6 +378,11 @@ config VIDEO_TI_VPE_DEBUG endif # V4L_MEM2MEM_DRIVERS +# TI VIDEO PORT Helper Modules +# These will be selected by VPE and VIP +config VIDEO_TI_VPDMA + tristate + menuconfig V4L_TEST_DRIVERS bool "Media test drivers" depends on MEDIA_CAMERA_SUPPORT diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile index e236059a60ad..faca5e115c1d 100644 --- a/drivers/media/platform/ti-vpe/Makefile +++ b/drivers/media/platform/ti-vpe/Makefile @@ -1,6 +1,8 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o +obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o -ti-vpe-y := vpe.o sc.o csc.o vpdma.o +ti-vpe-y := vpe.o sc.o csc.o +ti-vpdma-y := vpdma.o ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 4aff05915051..7de0f3f55dcc 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -75,6 +75,7 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = { .depth = 16, }, }; +EXPORT_SYMBOL(vpdma_yuv_fmts); const struct vpdma_data_format vpdma_rgb_fmts[] = { [VPDMA_DATA_FMT_RGB565] = { @@ -178,6 +179,7 @@ const struct vpdma_data_format vpdma_rgb_fmts[] = { .depth = 32, }, }; +EXPORT_SYMBOL(vpdma_rgb_fmts); const struct vpdma_data_format vpdma_misc_fmts[] = { [VPDMA_DATA_FMT_MV] = { @@ -186,6 +188,7 @@ const struct vpdma_data_format vpdma_misc_fmts[] = { .depth = 4, }, }; +EXPORT_SYMBOL(vpdma_misc_fmts); struct vpdma_channel_info { int num; /* VPDMA channel number */ @@ -317,6 +320,7 @@ void vpdma_dump_regs(struct vpdma_data *vpdma) DUMPREG(VIP_UP_UV_CSTAT); DUMPREG(VPI_CTL_CSTAT); } +EXPORT_SYMBOL(vpdma_dump_regs); /* * Allocate a DMA buffer @@ -333,6 +337,7 @@ int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size) return 0; } +EXPORT_SYMBOL(vpdma_alloc_desc_buf); void vpdma_free_desc_buf(struct vpdma_buf *buf) { @@ -341,6 +346,7 @@ void vpdma_free_desc_buf(struct vpdma_buf *buf) buf->addr = NULL; buf->size = 0; } +EXPORT_SYMBOL(vpdma_free_desc_buf); /* * map descriptor/payload DMA buffer, enabling DMA access @@ -361,6 +367,7 @@ int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) return 0; } +EXPORT_SYMBOL(vpdma_map_desc_buf); /* * unmap descriptor/payload DMA buffer, disabling DMA access and @@ -375,6 +382,7 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) buf->mapped = false; } +EXPORT_SYMBOL(vpdma_unmap_desc_buf); /* * create a descriptor list, the user of this list will append configuration, @@ -396,6 +404,7 @@ int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type) return 0; } +EXPORT_SYMBOL(vpdma_create_desc_list); /* * once a descriptor list is parsed by VPDMA, we reset the list by emptying it, @@ -405,6 +414,7 @@ void vpdma_reset_desc_list(struct vpdma_desc_list *list) { list->next = list->buf.addr; } +EXPORT_SYMBOL(vpdma_reset_desc_list); /* * free the buffer allocated fot the VPDMA descriptor list, this should be @@ -416,11 +426,13 @@ void vpdma_free_desc_list(struct vpdma_desc_list *list) list->next = NULL; } +EXPORT_SYMBOL(vpdma_free_desc_list); -static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num) +bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num) { return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16); } +EXPORT_SYMBOL(vpdma_list_busy); /* * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion @@ -446,6 +458,7 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list) return 0; } +EXPORT_SYMBOL(vpdma_submit_descs); static void dump_cfd(struct vpdma_cfd *cfd) { @@ -498,6 +511,7 @@ void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, dump_cfd(cfd); } +EXPORT_SYMBOL(vpdma_add_cfd_block); /* * append a configuration descriptor to the given descriptor list, where the @@ -526,6 +540,7 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, dump_cfd(cfd); }; +EXPORT_SYMBOL(vpdma_add_cfd_adb); /* * control descriptor format change based on what type of control descriptor it @@ -563,6 +578,7 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, dump_ctd(ctd); } +EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd); static void dump_dtd(struct vpdma_dtd *dtd) { @@ -672,6 +688,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, dump_dtd(dtd); } +EXPORT_SYMBOL(vpdma_add_out_dtd); /* * append an inbound data transfer descriptor to the given descriptor list, @@ -745,6 +762,7 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, dump_dtd(dtd); } +EXPORT_SYMBOL(vpdma_add_in_dtd); /* set or clear the mask for list complete interrupt */ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, @@ -759,6 +777,7 @@ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, val &= ~(1 << (list_num * 2)); write_reg(vpdma, VPDMA_INT_LIST0_MASK, val); } +EXPORT_SYMBOL(vpdma_enable_list_complete_irq); /* clear previosuly occured list intterupts in the LIST_STAT register */ void vpdma_clear_list_stat(struct vpdma_data *vpdma) @@ -766,6 +785,7 @@ void vpdma_clear_list_stat(struct vpdma_data *vpdma) write_reg(vpdma, VPDMA_INT_LIST0_STAT, read_reg(vpdma, VPDMA_INT_LIST0_STAT)); } +EXPORT_SYMBOL(vpdma_clear_list_stat); /* * configures the output mode of the line buffer for the given client, the @@ -780,6 +800,7 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, write_field_reg(vpdma, client_cstat, line_mode, VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT); } +EXPORT_SYMBOL(vpdma_set_line_mode); /* * configures the event which should trigger VPDMA transfer for the given @@ -794,6 +815,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma, write_field_reg(vpdma, client_cstat, fs_event, VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT); } +EXPORT_SYMBOL(vpdma_set_frame_start_event); static void vpdma_firmware_cb(const struct firmware *f, void *context) { @@ -907,4 +929,8 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev, return vpdma; } +EXPORT_SYMBOL(vpdma_create); + +MODULE_AUTHOR("Texas Instruments Inc."); MODULE_FIRMWARE(VPDMA_FIRMWARE); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 2f88703a0bfd1a4e88e1a7cf2542880ef72fdcc0 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:12 -0200 Subject: [media] media: ti-vpe: vpdma: Add multi-instance and multi-client support The VPDMA (Video Port DMA) as found in devices such as DRA7xx is used for both the Video Processing Engine (VPE) and the Video Input Port (VIP). Some devices may have multiple VIP instances each with its own VPDMA engine. Within VIP two slices can use a single VPDMA engine simultaneously. So support for multi instances and multiple clients has been added to VPDMA. Needed modification to the existing helper functions were then reflected to VPE. Multi-clients registers offset have also been added in preparation. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 104 +++++++++++++++++++++++++---- drivers/media/platform/ti-vpe/vpdma.h | 25 +++++-- drivers/media/platform/ti-vpe/vpdma_priv.h | 15 ++++- drivers/media/platform/ti-vpe/vpe.c | 8 +-- 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 7de0f3f55dcc..2b094016b470 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -437,10 +437,9 @@ EXPORT_SYMBOL(vpdma_list_busy); /* * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion */ -int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list) +int vpdma_submit_descs(struct vpdma_data *vpdma, + struct vpdma_desc_list *list, int list_num) { - /* we always use the first list */ - int list_num = 0; int list_size; if (vpdma_list_busy(vpdma, list_num)) @@ -460,6 +459,40 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list) } EXPORT_SYMBOL(vpdma_submit_descs); +static void dump_dtd(struct vpdma_dtd *dtd); + +void vpdma_update_dma_addr(struct vpdma_data *vpdma, + struct vpdma_desc_list *list, dma_addr_t dma_addr, + void *write_dtd, int drop, int idx) +{ + struct vpdma_dtd *dtd = list->buf.addr; + dma_addr_t write_desc_addr; + int offset; + + dtd += idx; + vpdma_unmap_desc_buf(vpdma, &list->buf); + + dtd->start_addr = dma_addr; + + /* Calculate write address from the offset of write_dtd from start + * of the list->buf + */ + offset = (void *)write_dtd - list->buf.addr; + write_desc_addr = list->buf.dma_addr + offset; + + if (drop) + dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr, + 1, 1, 0); + else + dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr, + 1, 0, 0); + + vpdma_map_desc_buf(vpdma, &list->buf); + + dump_dtd(dtd); +} +EXPORT_SYMBOL(vpdma_update_dma_addr); + static void dump_cfd(struct vpdma_cfd *cfd) { int class; @@ -641,6 +674,16 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, enum vpdma_channel chan, u32 flags) +{ + vpdma_rawchan_add_out_dtd(list, width, c_rect, fmt, dma_addr, + chan_info[chan].num, flags); +} +EXPORT_SYMBOL(vpdma_add_out_dtd); + +void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, + const struct v4l2_rect *c_rect, + const struct vpdma_data_format *fmt, dma_addr_t dma_addr, + int raw_vpdma_chan, u32 flags) { int priority = 0; int field = 0; @@ -651,7 +694,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, int stride; struct vpdma_dtd *dtd; - channel = next_chan = chan_info[chan].num; + channel = next_chan = raw_vpdma_chan; if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && fmt->data_type == DATA_TYPE_C420) { @@ -688,7 +731,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, dump_dtd(dtd); } -EXPORT_SYMBOL(vpdma_add_out_dtd); +EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd); /* * append an inbound data transfer descriptor to the given descriptor list, @@ -765,25 +808,62 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, EXPORT_SYMBOL(vpdma_add_in_dtd); /* set or clear the mask for list complete interrupt */ -void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, - bool enable) +void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, + int list_num, bool enable) { + u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num; u32 val; - val = read_reg(vpdma, VPDMA_INT_LIST0_MASK); + val = read_reg(vpdma, reg_addr); if (enable) val |= (1 << (list_num * 2)); else val &= ~(1 << (list_num * 2)); - write_reg(vpdma, VPDMA_INT_LIST0_MASK, val); + write_reg(vpdma, reg_addr, val); } EXPORT_SYMBOL(vpdma_enable_list_complete_irq); +/* set or clear the mask for list complete interrupt */ +void vpdma_enable_list_notify_irq(struct vpdma_data *vpdma, int irq_num, + int list_num, bool enable) +{ + u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num; + u32 val; + + val = read_reg(vpdma, reg_addr); + if (enable) + val |= (1 << ((list_num * 2) + 1)); + else + val &= ~(1 << ((list_num * 2) + 1)); + write_reg(vpdma, reg_addr, val); +} +EXPORT_SYMBOL(vpdma_enable_list_notify_irq); + +/* get the LIST_STAT register */ +unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num) +{ + u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num; + + return read_reg(vpdma, reg_addr); +} +EXPORT_SYMBOL(vpdma_get_list_stat); + +/* get the LIST_MASK register */ +unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num) +{ + u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num; + + return read_reg(vpdma, reg_addr); +} +EXPORT_SYMBOL(vpdma_get_list_mask); + /* clear previosuly occured list intterupts in the LIST_STAT register */ -void vpdma_clear_list_stat(struct vpdma_data *vpdma) +void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num) { - write_reg(vpdma, VPDMA_INT_LIST0_STAT, - read_reg(vpdma, VPDMA_INT_LIST0_STAT)); + u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num; + + write_reg(vpdma, reg_addr, + read_reg(vpdma, reg_addr)); } EXPORT_SYMBOL(vpdma_clear_list_stat); diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 2bd8fb050381..83325d887546 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -134,6 +134,11 @@ enum vpdma_channel { VPE_CHAN_RGB_OUT, }; +#define VIP_CHAN_VIP2_OFFSET 70 +#define VIP_CHAN_MULT_PORTB_OFFSET 16 +#define VIP_CHAN_YUV_PORTB_OFFSET 2 +#define VIP_CHAN_RGB_PORTB_OFFSET 1 + /* flags for VPDMA data descriptors */ #define VPDMA_DATA_ODD_LINE_SKIP (1 << 0) #define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1) @@ -177,8 +182,12 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf); int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type); void vpdma_reset_desc_list(struct vpdma_desc_list *list); void vpdma_free_desc_list(struct vpdma_desc_list *list); -int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list); - +int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list, + int list_num); +bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num); +void vpdma_update_dma_addr(struct vpdma_data *vpdma, + struct vpdma_desc_list *list, dma_addr_t dma_addr, + void *write_dtd, int drop, int idx); /* helpers for creating vpdma descriptors */ void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, struct vpdma_buf *blk, u32 dest_offset); @@ -190,6 +199,10 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, enum vpdma_channel chan, u32 flags); +void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, + const struct v4l2_rect *c_rect, + const struct vpdma_data_format *fmt, dma_addr_t dma_addr, + int raw_vpdma_chan, u32 flags); void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, @@ -197,9 +210,11 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, int frame_height, int start_h, int start_v); /* vpdma list interrupt management */ -void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, - bool enable); -void vpdma_clear_list_stat(struct vpdma_data *vpdma); +void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, + int list_num, bool enable); +void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num); +unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num); +unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num); /* vpdma client configuration */ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h index c1a6ce1884f3..65f0c067bed1 100644 --- a/drivers/media/platform/ti-vpe/vpdma_priv.h +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h @@ -39,9 +39,11 @@ #define VPDMA_INT_LIST0_STAT 0x88 #define VPDMA_INT_LIST0_MASK 0x8c +#define VPDMA_INTX_OFFSET 0x50 + #define VPDMA_PERFMON(i) (0x200 + i * 4) -/* VPE specific client registers */ +/* VIP/VPE client registers */ #define VPDMA_DEI_CHROMA1_CSTAT 0x0300 #define VPDMA_DEI_LUMA1_CSTAT 0x0304 #define VPDMA_DEI_LUMA2_CSTAT 0x0308 @@ -50,6 +52,8 @@ #define VPDMA_DEI_CHROMA3_CSTAT 0x0314 #define VPDMA_DEI_MV_IN_CSTAT 0x0330 #define VPDMA_DEI_MV_OUT_CSTAT 0x033c +#define VPDMA_VIP_LO_Y_CSTAT 0x0388 +#define VPDMA_VIP_LO_UV_CSTAT 0x038c #define VPDMA_VIP_UP_Y_CSTAT 0x0390 #define VPDMA_VIP_UP_UV_CSTAT 0x0394 #define VPDMA_VPI_CTL_CSTAT 0x03d0 @@ -103,7 +107,7 @@ #define DATA_TYPE_MV 0x3 -/* VPDMA channel numbers(only VPE channels for now) */ +/* VPDMA channel numbers, some are common between VIP/VPE and appear twice */ #define VPE_CHAN_NUM_LUMA1_IN 0 #define VPE_CHAN_NUM_CHROMA1_IN 1 #define VPE_CHAN_NUM_LUMA2_IN 2 @@ -112,10 +116,15 @@ #define VPE_CHAN_NUM_CHROMA3_IN 5 #define VPE_CHAN_NUM_MV_IN 12 #define VPE_CHAN_NUM_MV_OUT 15 +#define VIP1_CHAN_NUM_MULT_PORT_A_SRC0 38 +#define VIP1_CHAN_NUM_MULT_ANC_A_SRC0 70 #define VPE_CHAN_NUM_LUMA_OUT 102 #define VPE_CHAN_NUM_CHROMA_OUT 103 +#define VIP1_CHAN_NUM_PORT_A_LUMA 102 +#define VIP1_CHAN_NUM_PORT_A_CHROMA 103 #define VPE_CHAN_NUM_RGB_OUT 106 - +#define VIP1_CHAN_NUM_PORT_A_RGB 106 +#define VIP1_CHAN_NUM_PORT_B_RGB 107 /* * a VPDMA address data block payload for a configuration descriptor needs to * have each sub block length as a multiple of 16 bytes. Therefore, the overall diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 1cf4a4c1b899..bd385c5bae2f 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1077,7 +1077,7 @@ static void enable_irqs(struct vpe_ctx *ctx) write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT | VPE_DS1_UV_ERROR_INT); - vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, true); + vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, true); } static void disable_irqs(struct vpe_ctx *ctx) @@ -1085,7 +1085,7 @@ static void disable_irqs(struct vpe_ctx *ctx) write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff); write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff); - vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, false); + vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, false); } /* device_run() - prepares and starts the device @@ -1202,7 +1202,7 @@ static void device_run(void *priv) enable_irqs(ctx); vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf); - vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list); + vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list, 0); } static void dei_error(struct vpe_ctx *ctx) @@ -1257,7 +1257,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) if (irqst0) { if (irqst0 & VPE_INT0_LIST0_COMPLETE) - vpdma_clear_list_stat(ctx->dev->vpdma); + vpdma_clear_list_stat(ctx->dev->vpdma, 0); irqst0 &= ~(VPE_INT0_LIST0_COMPLETE); } -- cgit v1.2.3 From 3f43554c0a3c2a311f484b9131a7b9edf183f6e0 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:13 -0200 Subject: [media] media: ti-vpe: vpdma: Add helper to set a background color Add a helper to set the background color during vpdma transfer. This is needed when VPDMA is generating 32 bits RGB format to have the Alpha channel set to an appropriate value. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 10 ++++++++++ drivers/media/platform/ti-vpe/vpdma.h | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 2b094016b470..133154628543 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -867,6 +867,16 @@ void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num) } EXPORT_SYMBOL(vpdma_clear_list_stat); +void vpdma_set_bg_color(struct vpdma_data *vpdma, + struct vpdma_data_format *fmt, u32 color) +{ + if (fmt->type == VPDMA_DATA_FMT_TYPE_RGB) + write_reg(vpdma, VPDMA_BG_RGB, color); + else if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV) + write_reg(vpdma, VPDMA_BG_YUV, color); +} +EXPORT_SYMBOL(vpdma_set_bg_color); + /* * configures the output mode of the line buffer for the given client, the * line buffer content can either be mirrored(each line repeated twice) or diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 83325d887546..220dc7e793f6 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -221,7 +221,8 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, enum vpdma_channel chan); void vpdma_set_frame_start_event(struct vpdma_data *vpdma, enum vpdma_frame_start_event fs_event, enum vpdma_channel chan); - +void vpdma_set_bg_color(struct vpdma_data *vpdma, + struct vpdma_data_format *fmt, u32 color); void vpdma_dump_regs(struct vpdma_data *vpdma); /* initialize vpdma, passed with VPE's platform device pointer */ -- cgit v1.2.3 From 4f36178188e0b33ea594e3d4849f407e40f8149d Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:14 -0200 Subject: [media] media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor On DRA7 since l3_noc event are being reported it was found that when the write descriptor was being written it was consistently causing bus error events. The write address was improperly programmed. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma_priv.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h index 65f0c067bed1..aeade5edc8ac 100644 --- a/drivers/media/platform/ti-vpe/vpdma_priv.h +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h @@ -212,6 +212,7 @@ struct vpdma_dtd { #define DTD_V_START_MASK 0xffff #define DTD_V_START_SHFT 0 +#define DTD_DESC_START_MASK 0xffffffe0 #define DTD_DESC_START_SHIFT 5 #define DTD_WRITE_DESC_MASK 0x01 #define DTD_WRITE_DESC_SHIFT 2 @@ -294,7 +295,7 @@ static inline u32 dtd_frame_width_height(int width, int height) static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc, bool drop_data, bool use_desc) { - return (addr << DTD_DESC_START_SHIFT) | + return (addr & DTD_DESC_START_MASK) | (write_desc << DTD_WRITE_DESC_SHIFT) | (drop_data << DTD_DROP_DATA_SHIFT) | use_desc; @@ -399,7 +400,7 @@ static inline int dtd_get_frame_height(struct vpdma_dtd *dtd) static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd) { - return dtd->desc_write_addr >> DTD_DESC_START_SHIFT; + return dtd->desc_write_addr & DTD_DESC_START_MASK; } static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd) -- cgit v1.2.3 From 15f632e665653da078a121f8478586f09dd56b4d Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 18 Nov 2016 21:20:15 -0200 Subject: [media] media: ti-vpe: Use line average de-interlacing for first 2 frames The motion detection block requires 3 fields to create the motion vector data. This means that using the default method the first progressive frame is only generated after 3rd field is consumed. Hence by default for N input field we would generate N - 2 progressive frames. In order to generate N progressive frames from N fields we use the line averaging mode of the de-interlacer for the first 2 fields and then revert back to the preferred Edge Directed Interpolation method (using the motion vector). Thus creating 2 line averaged frames + N - 2 motion based frames for a total of N frames. Signed-off-by: Archit Taneja Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index bd385c5bae2f..ad838b8a98c4 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -141,7 +141,7 @@ struct vpe_dei_regs { */ static const struct vpe_dei_regs dei_regs = { .mdt_spacial_freq_thr_reg = 0x020C0804u, - .edi_config_reg = 0x0118100Fu, + .edi_config_reg = 0x0118100Cu, .edi_lut_reg0 = 0x08040200u, .edi_lut_reg1 = 0x1010100Cu, .edi_lut_reg2 = 0x10101010u, @@ -798,6 +798,23 @@ static void set_dei_shadow_registers(struct vpe_ctx *ctx) ctx->load_mmrs = true; } +static void config_edi_input_mode(struct vpe_ctx *ctx, int mode) +{ + struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; + u32 *edi_config_reg = &mmr_adb->dei_regs[3]; + + if (mode & 0x2) + write_field(edi_config_reg, 1, 1, 2); /* EDI_ENABLE_3D */ + + if (mode & 0x3) + write_field(edi_config_reg, 1, 1, 3); /* EDI_CHROMA_3D */ + + write_field(edi_config_reg, mode, VPE_EDI_INP_MODE_MASK, + VPE_EDI_INP_MODE_SHIFT); + + ctx->load_mmrs = true; +} + /* * Set the shadow registers whose values are modified when either the * source or destination format is changed. @@ -1111,6 +1128,15 @@ static void device_run(void *priv) ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); WARN_ON(ctx->dst_vb == NULL); + if (ctx->deinterlacing) { + /* + * we have output the first 2 frames through line average, we + * now switch to EDI de-interlacer + */ + if (ctx->sequence == 2) + config_edi_input_mode(ctx, 0x3); /* EDI (Y + UV) */ + } + /* config descriptors */ if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) { vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb); @@ -1864,7 +1890,10 @@ static void vpe_buf_queue(struct vb2_buffer *vb) static int vpe_start_streaming(struct vb2_queue *q, unsigned int count) { - /* currently we do nothing here */ + struct vpe_ctx *ctx = vb2_get_drv_priv(q); + + if (ctx->deinterlacing) + config_edi_input_mode(ctx, 0x0); return 0; } -- cgit v1.2.3 From 5dc07f20b67dc30ea2f7988eb76d2231a40a97bc Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:16 -0200 Subject: [media] media: ti-vpe: vpe: Do not perform job transaction atomically Current VPE driver does not start the job until all the buffers for a transaction are queued. When running in multiple context, this might increase the processing latency. Alternate solution would be to try to continue the same context as long as buffers for the transaction are ready; else switch the context. This may increase number of context switches but it reduces latency significantly. In this approach, the job_ready always succeeds as long as there are buffers on the CAPTURE and OUTPUT stream. Processing may start immediately as the first 2 iterations don't need extra source buffers. Shift all the source buffers after each iteration and remove the oldest buffer. Also, with this removes the constraint of pre buffering 3 buffers before call to STREAMON in case of de-interlacing. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index ad838b8a98c4..9b7b9be5641d 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -898,15 +898,14 @@ static struct vpe_ctx *file2ctx(struct file *file) static int job_ready(void *priv) { struct vpe_ctx *ctx = priv; - int needed = ctx->bufs_per_job; - if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) - needed += 2; /* need additional two most recent fields */ - - if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < needed) - return 0; - - if (v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < needed) + /* + * This check is needed as this might be called directly from driver + * When called by m2m framework, this will always satisfy, but when + * called from vpe_irq, this might fail. (src stream with zero buffers) + */ + if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 || + v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0) return 0; return 1; @@ -1116,19 +1115,20 @@ static void device_run(void *priv) struct sc_data *sc = ctx->dev->sc; struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; - if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) { - ctx->src_vbs[2] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - WARN_ON(ctx->src_vbs[2] == NULL); - ctx->src_vbs[1] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - WARN_ON(ctx->src_vbs[1] == NULL); - } - ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); WARN_ON(ctx->src_vbs[0] == NULL); ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); WARN_ON(ctx->dst_vb == NULL); if (ctx->deinterlacing) { + + if (ctx->src_vbs[2] == NULL) { + ctx->src_vbs[2] = ctx->src_vbs[0]; + WARN_ON(ctx->src_vbs[2] == NULL); + ctx->src_vbs[1] = ctx->src_vbs[0]; + WARN_ON(ctx->src_vbs[1] == NULL); + } + /* * we have output the first 2 frames through line average, we * now switch to EDI de-interlacer @@ -1348,7 +1348,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) } ctx->bufs_completed++; - if (ctx->bufs_completed < ctx->bufs_per_job) { + if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) { device_run(ctx); goto handled; } -- cgit v1.2.3 From 823f4208b2284dcc7137b17d036e71a16199572c Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:17 -0200 Subject: [media] media: ti-vpe: Add support for SEQ_TB buffers The video source can generate the data in the SEQ_TB buffer format. In the case of TI SoC, the IVA_HD can generate the interlaced content in the SEQ_TB buffer format. This is the format where the top and bottom field data can be contained in a single buffer. For example, for NV12, interlaced format, the data in Y buffer will be arranged as Y-top followed by Y-bottom. And likewise for UV plane. Also, queuing one buffer of SEQ_TB is equivalent to queuing two different buffers for top and bottom fields. Driver needs to take care of this when handling source buffer lists. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 125 +++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 9b7b9be5641d..e5d55575350f 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -320,9 +320,13 @@ struct vpe_q_data { }; /* vpe_q_data flag bits */ -#define Q_DATA_FRAME_1D (1 << 0) -#define Q_DATA_MODE_TILED (1 << 1) -#define Q_DATA_INTERLACED (1 << 2) +#define Q_DATA_FRAME_1D BIT(0) +#define Q_DATA_MODE_TILED BIT(1) +#define Q_DATA_INTERLACED_ALTERNATE BIT(2) +#define Q_DATA_INTERLACED_SEQ_TB BIT(3) + +#define Q_IS_INTERLACED (Q_DATA_INTERLACED_ALTERNATE | \ + Q_DATA_INTERLACED_SEQ_TB) enum { Q_DATA_SRC = 0, @@ -638,7 +642,7 @@ static void set_us_coefficients(struct vpe_ctx *ctx) cp = &us_coeffs[0].anchor_fid0_c0; - if (s_q_data->flags & Q_DATA_INTERLACED) /* interlaced */ + if (s_q_data->flags & Q_IS_INTERLACED) /* interlaced */ cp += sizeof(us_coeffs[0]) / sizeof(*cp); end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp); @@ -765,8 +769,7 @@ static void set_dei_regs(struct vpe_ctx *ctx) * for both progressive and interlace content in interlace bypass mode. * It has been recommended not to use progressive bypass mode. */ - if ((!ctx->deinterlacing && (s_q_data->flags & Q_DATA_INTERLACED)) || - !(s_q_data->flags & Q_DATA_INTERLACED)) { + if (!(s_q_data->flags & Q_IS_INTERLACED) || !ctx->deinterlacing) { deinterlace = false; val = VPE_DEI_INTERLACE_BYPASS; } @@ -834,8 +837,8 @@ static int set_srcdst_params(struct vpe_ctx *ctx) ctx->sequence = 0; ctx->field = V4L2_FIELD_TOP; - if ((s_q_data->flags & Q_DATA_INTERLACED) && - !(d_q_data->flags & Q_DATA_INTERLACED)) { + if ((s_q_data->flags & Q_IS_INTERLACED) && + !(d_q_data->flags & Q_IS_INTERLACED)) { int bytes_per_line; const struct vpdma_data_format *mv = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; @@ -1066,6 +1069,28 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port) port); return; } + + if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) { + /* + * Use top or bottom field from same vb alternately + * f,f-1,f-2 = TBT when seq is even + * f,f-1,f-2 = BTB when seq is odd + */ + field = (p_data->vb_index + (ctx->sequence % 2)) % 2; + + if (field) { + /* + * bottom field of a SEQ_TB buffer + * Skip the top field data by + */ + int height = q_data->height / 2; + int bpp = fmt->fourcc == V4L2_PIX_FMT_NV12 ? + 1 : (vpdma_fmt->depth >> 3); + if (plane) + height /= 2; + dma_addr += q_data->width * height * bpp; + } + } } if (q_data->flags & Q_DATA_FRAME_1D) @@ -1114,9 +1139,22 @@ static void device_run(void *priv) struct vpe_ctx *ctx = priv; struct sc_data *sc = ctx->dev->sc; struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; + struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; + + if (ctx->deinterlacing && s_q_data->flags & Q_DATA_INTERLACED_SEQ_TB && + ctx->sequence % 2 == 0) { + /* When using SEQ_TB buffers, When using it first time, + * No need to remove the buffer as the next field is present + * in the same buffer. (so that job_ready won't fail) + * It will be removed when using bottom field + */ + ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + WARN_ON(ctx->src_vbs[0] == NULL); + } else { + ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + WARN_ON(ctx->src_vbs[0] == NULL); + } - ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - WARN_ON(ctx->src_vbs[0] == NULL); ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); WARN_ON(ctx->dst_vb == NULL); @@ -1320,7 +1358,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) d_vb->sequence = ctx->sequence; d_q_data = &ctx->q_data[Q_DATA_DST]; - if (d_q_data->flags & Q_DATA_INTERLACED) { + if (d_q_data->flags & Q_IS_INTERLACED) { d_vb->field = ctx->field; if (ctx->field == V4L2_FIELD_BOTTOM) { ctx->sequence++; @@ -1334,12 +1372,28 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) ctx->sequence++; } - if (ctx->deinterlacing) - s_vb = ctx->src_vbs[2]; + if (ctx->deinterlacing) { + /* + * Allow source buffer to be dequeued only if it won't be used + * in the next iteration. All vbs are initialized to first + * buffer and we are shifting buffers every iteration, for the + * first two iterations, no buffer will be dequeued. + * This ensures that driver will keep (n-2)th (n-1)th and (n)th + * field when deinterlacing is enabled + */ + if (ctx->src_vbs[2] != ctx->src_vbs[1]) + s_vb = ctx->src_vbs[2]; + else + s_vb = NULL; + } spin_lock_irqsave(&dev->lock, flags); - v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE); + + if (s_vb) + v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE); + v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE); + spin_unlock_irqrestore(&dev->lock, flags); if (ctx->deinterlacing) { @@ -1455,7 +1509,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; struct v4l2_plane_pix_format *plane_fmt; unsigned int w_align; - int i, depth, depth_bytes; + int i, depth, depth_bytes, height; if (!fmt || !(fmt->types & type)) { vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", @@ -1463,7 +1517,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, return -EINVAL; } - if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE) + if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE + && pix->field != V4L2_FIELD_SEQ_TB) pix->field = V4L2_FIELD_NONE; depth = fmt->vpdma_fmt[VPE_LUMA]->depth; @@ -1497,6 +1552,15 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, pix->num_planes = fmt->coplanar ? 2 : 1; pix->pixelformat = fmt->fourcc; + /* + * For the actual image parameters, we need to consider the field + * height of the image for SEQ_TB buffers. + */ + if (pix->field == V4L2_FIELD_SEQ_TB) + height = pix->height / 2; + else + height = pix->height; + if (!pix->colorspace) { if (fmt->fourcc == V4L2_PIX_FMT_RGB24 || fmt->fourcc == V4L2_PIX_FMT_BGR24 || @@ -1504,7 +1568,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, fmt->fourcc == V4L2_PIX_FMT_BGR32) { pix->colorspace = V4L2_COLORSPACE_SRGB; } else { - if (pix->height > 1280) /* HD */ + if (height > 1280) /* HD */ pix->colorspace = V4L2_COLORSPACE_REC709; else /* SD */ pix->colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -1581,9 +1645,15 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f) q_data->c_rect.height = q_data->height; if (q_data->field == V4L2_FIELD_ALTERNATE) - q_data->flags |= Q_DATA_INTERLACED; + q_data->flags |= Q_DATA_INTERLACED_ALTERNATE; + else if (q_data->field == V4L2_FIELD_SEQ_TB) + q_data->flags |= Q_DATA_INTERLACED_SEQ_TB; else - q_data->flags &= ~Q_DATA_INTERLACED; + q_data->flags &= ~Q_IS_INTERLACED; + + /* the crop height is halved for the case of SEQ_TB buffers */ + if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) + q_data->c_rect.height /= 2; vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d", f->type, q_data->width, q_data->height, q_data->fmt->fourcc, @@ -1619,6 +1689,7 @@ static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f) static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s) { struct vpe_q_data *q_data; + int height; if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) @@ -1653,13 +1724,22 @@ static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s) return -EINVAL; } + /* + * For SEQ_TB buffers, crop height should be less than the height of + * the field height, not the buffer height + */ + if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) + height = q_data->height / 2; + else + height = q_data->height; + if (s->r.top < 0 || s->r.left < 0) { vpe_err(ctx->dev, "negative values for top and left\n"); s->r.top = s->r.left = 0; } v4l_bound_align_image(&s->r.width, MIN_W, q_data->width, 1, - &s->r.height, MIN_H, q_data->height, H_ALIGN, S_ALIGN); + &s->r.height, MIN_H, height, H_ALIGN, S_ALIGN); /* adjust left/top if cropping rectangle is out of bounds */ if (s->r.left + s->r.width > q_data->width) @@ -1855,11 +1935,12 @@ static int vpe_buf_prepare(struct vb2_buffer *vb) num_planes = q_data->fmt->coplanar ? 2 : 1; if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - if (!(q_data->flags & Q_DATA_INTERLACED)) { + if (!(q_data->flags & Q_IS_INTERLACED)) { vbuf->field = V4L2_FIELD_NONE; } else { if (vbuf->field != V4L2_FIELD_TOP && - vbuf->field != V4L2_FIELD_BOTTOM) + vbuf->field != V4L2_FIELD_BOTTOM && + vbuf->field != V4L2_FIELD_SEQ_TB) return -EINVAL; } } -- cgit v1.2.3 From 8028bfed42dd2f5b612be3cc346699bdf327e16c Mon Sep 17 00:00:00 2001 From: Harinarayan Bhatta Date: Fri, 18 Nov 2016 21:20:18 -0200 Subject: [media] media: ti-vpe: Increasing max buffer height and width Increasing max buffer height and width to allow for padded buffers. Signed-off-by: Harinarayan Bhatta Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index e5d55575350f..c624f5db7f08 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -53,8 +53,8 @@ /* minimum and maximum frame sizes */ #define MIN_W 32 #define MIN_H 32 -#define MAX_W 1920 -#define MAX_H 1080 +#define MAX_W 2048 +#define MAX_H 1184 /* required alignments */ #define S_ALIGN 0 /* multiple of 1 */ -- cgit v1.2.3 From 072915b57a85e8d65e22be5595a639110afdcc90 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:19 -0200 Subject: [media] media: ti-vpe: vpe: Return NULL for invalid buffer type get_q_data can be called with different values for type e.g. vpe_try_crop calls it with the buffer type which gets passed from user space Framework doesn't check wheather its correct type or not If user space passes wrong type, kernel should not crash. Return NULL when the passed type is invalid. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index c624f5db7f08..4b6e8839dd83 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -420,7 +420,7 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx, case V4L2_BUF_TYPE_VIDEO_CAPTURE: return &ctx->q_data[Q_DATA_DST]; default: - BUG(); + return NULL; } return NULL; } -- cgit v1.2.3 From f43aa420a89a4a17117e21553283e2a50cf86df8 Mon Sep 17 00:00:00 2001 From: Harinarayan Bhatta Date: Fri, 18 Nov 2016 21:20:20 -0200 Subject: [media] media: ti-vpe: Free vpdma buffers in vpe_release Free vpdma buffers in vpe_release. Otherwise it was generating random backtrace. Signed-off-by: Harinarayan Bhatta Signed-off-by: Somnath Mukherjee Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 4b6e8839dd83..f2b90d42b408 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2182,6 +2182,9 @@ static int vpe_release(struct file *file) vpdma_free_desc_list(&ctx->desc_list); vpdma_free_desc_buf(&ctx->mmr_adb); + vpdma_free_desc_buf(&ctx->sc_coeff_v); + vpdma_free_desc_buf(&ctx->sc_coeff_h); + v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->hdl); -- cgit v1.2.3 From 634271f8f67532d48db6bf0fcacd5423e941bb5e Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:21 -0200 Subject: [media] media: ti-vpe: vpdma: Add support for setting max width height Add a helper function to be able to set the maximum VPDMA transfer size to limit potential buffer overrun. Added enums for max_width and max_height fields of the outbound data descriptor. Changed vpdma_add_out_dtd to accept two more arguments for max width and height. Make use of different max width & height sets for different of capture module (i.e. slices). Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 27 ++++++++++++++++---- drivers/media/platform/ti-vpe/vpdma.h | 32 ++++++++++++++++++++++-- drivers/media/platform/ti-vpe/vpdma_priv.h | 40 +++--------------------------- drivers/media/platform/ti-vpe/vpe.c | 7 +++++- 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 133154628543..1a0152842a17 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -493,6 +493,22 @@ void vpdma_update_dma_addr(struct vpdma_data *vpdma, } EXPORT_SYMBOL(vpdma_update_dma_addr); +void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr, + u32 width, u32 height) +{ + if (reg_addr != VPDMA_MAX_SIZE1 && reg_addr != VPDMA_MAX_SIZE2 && + reg_addr != VPDMA_MAX_SIZE3) + reg_addr = VPDMA_MAX_SIZE1; + + write_field_reg(vpdma, reg_addr, width - 1, + VPDMA_MAX_SIZE_WIDTH_MASK, VPDMA_MAX_SIZE_WIDTH_SHFT); + + write_field_reg(vpdma, reg_addr, height - 1, + VPDMA_MAX_SIZE_HEIGHT_MASK, VPDMA_MAX_SIZE_HEIGHT_SHFT); + +} +EXPORT_SYMBOL(vpdma_set_max_size); + static void dump_cfd(struct vpdma_cfd *cfd) { int class; @@ -667,23 +683,25 @@ static void dump_dtd(struct vpdma_dtd *dtd) * @c_rect: compose params of output image * @fmt: vpdma data format of the buffer * dma_addr: dma address as seen by VPDMA + * max_width: enum for maximum width of data transfer + * max_height: enum for maximum height of data transfer * chan: VPDMA channel * flags: VPDMA flags to configure some descriptor fileds */ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, - enum vpdma_channel chan, u32 flags) + int max_w, int max_h, enum vpdma_channel chan, u32 flags) { vpdma_rawchan_add_out_dtd(list, width, c_rect, fmt, dma_addr, - chan_info[chan].num, flags); + max_w, max_h, chan_info[chan].num, flags); } EXPORT_SYMBOL(vpdma_add_out_dtd); void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, - int raw_vpdma_chan, u32 flags) + int max_w, int max_h, int raw_vpdma_chan, u32 flags) { int priority = 0; int field = 0; @@ -722,8 +740,7 @@ void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), DTD_DIR_OUT, channel, priority, next_chan); dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0); - dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920, - MAX_OUT_HEIGHT_1080); + dtd->max_width_height = dtd_max_width_height(max_w, max_h); dtd->client_attr0 = 0; dtd->client_attr1 = 0; diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 220dc7e793f6..32b9ed5191c5 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -117,6 +117,30 @@ enum vpdma_frame_start_event { VPDMA_FSEVENT_CHANNEL_ACTIVE, }; +/* max width configurations */ +enum vpdma_max_width { + MAX_OUT_WIDTH_UNLIMITED = 0, + MAX_OUT_WIDTH_REG1, + MAX_OUT_WIDTH_REG2, + MAX_OUT_WIDTH_REG3, + MAX_OUT_WIDTH_352, + MAX_OUT_WIDTH_768, + MAX_OUT_WIDTH_1280, + MAX_OUT_WIDTH_1920, +}; + +/* max height configurations */ +enum vpdma_max_height { + MAX_OUT_HEIGHT_UNLIMITED = 0, + MAX_OUT_HEIGHT_REG1, + MAX_OUT_HEIGHT_REG2, + MAX_OUT_HEIGHT_REG3, + MAX_OUT_HEIGHT_288, + MAX_OUT_HEIGHT_576, + MAX_OUT_HEIGHT_720, + MAX_OUT_HEIGHT_1080, +}; + /* * VPDMA channel numbers */ @@ -198,11 +222,12 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, - enum vpdma_channel chan, u32 flags); + int max_w, int max_h, enum vpdma_channel chan, u32 flags); void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, - int raw_vpdma_chan, u32 flags); + int max_w, int max_h, int raw_vpdma_chan, u32 flags); + void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, @@ -221,6 +246,9 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, enum vpdma_channel chan); void vpdma_set_frame_start_event(struct vpdma_data *vpdma, enum vpdma_frame_start_event fs_event, enum vpdma_channel chan); +void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr, + u32 width, u32 height); + void vpdma_set_bg_color(struct vpdma_data *vpdma, struct vpdma_data_format *fmt, u32 color); void vpdma_dump_regs(struct vpdma_data *vpdma); diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h index aeade5edc8ac..54b6aa866c74 100644 --- a/drivers/media/platform/ti-vpe/vpdma_priv.h +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h @@ -28,6 +28,10 @@ #define VPDMA_MAX_SIZE1 0x34 #define VPDMA_MAX_SIZE2 0x38 #define VPDMA_MAX_SIZE3 0x3c +#define VPDMA_MAX_SIZE_WIDTH_MASK 0xffff +#define VPDMA_MAX_SIZE_WIDTH_SHFT 16 +#define VPDMA_MAX_SIZE_HEIGHT_MASK 0xffff +#define VPDMA_MAX_SIZE_HEIGHT_SHFT 0 /* Interrupts */ #define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8) @@ -227,42 +231,6 @@ struct vpdma_dtd { #define DTD_MAX_HEIGHT_MASK 0x07 #define DTD_MAX_HEIGHT_SHFT 0 -/* max width configurations */ - /* unlimited width */ -#define MAX_OUT_WIDTH_UNLIMITED 0 -/* as specified in max_size1 reg */ -#define MAX_OUT_WIDTH_REG1 1 -/* as specified in max_size2 reg */ -#define MAX_OUT_WIDTH_REG2 2 -/* as specified in max_size3 reg */ -#define MAX_OUT_WIDTH_REG3 3 -/* maximum of 352 pixels as width */ -#define MAX_OUT_WIDTH_352 4 -/* maximum of 768 pixels as width */ -#define MAX_OUT_WIDTH_768 5 -/* maximum of 1280 pixels width */ -#define MAX_OUT_WIDTH_1280 6 -/* maximum of 1920 pixels as width */ -#define MAX_OUT_WIDTH_1920 7 - -/* max height configurations */ - /* unlimited height */ -#define MAX_OUT_HEIGHT_UNLIMITED 0 -/* as specified in max_size1 reg */ -#define MAX_OUT_HEIGHT_REG1 1 -/* as specified in max_size2 reg */ -#define MAX_OUT_HEIGHT_REG2 2 -/* as specified in max_size3 reg */ -#define MAX_OUT_HEIGHT_REG3 3 -/* maximum of 288 lines as height */ -#define MAX_OUT_HEIGHT_288 4 -/* maximum of 576 lines as height */ -#define MAX_OUT_HEIGHT_576 5 -/* maximum of 720 lines as height */ -#define MAX_OUT_HEIGHT_720 6 -/* maximum of 1080 lines as height */ -#define MAX_OUT_HEIGHT_1080 7 - static inline u32 dtd_type_ctl_stride(int type, bool notify, int field, bool one_d, bool even_line_skip, bool odd_line_skip, int line_stride) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index f2b90d42b408..151a9280bb85 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -44,6 +44,7 @@ #include #include "vpdma.h" +#include "vpdma_priv.h" #include "vpe_regs.h" #include "sc.h" #include "csc.h" @@ -1035,8 +1036,12 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) if (q_data->flags & Q_DATA_MODE_TILED) flags |= VPDMA_DATA_MODE_TILED; + vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1, + MAX_W, MAX_H); + vpdma_add_out_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect, - vpdma_fmt, dma_addr, p_data->channel, flags); + vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1, + MAX_OUT_HEIGHT_REG1, p_data->channel, flags); } static void add_in_dtd(struct vpe_ctx *ctx, int port) -- cgit v1.2.3 From dc12b124353b2b4d8d46b2d0826f4f7905d44612 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:22 -0200 Subject: [media] media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs Whenever VPDMA processes a data descriptor of a list, it processes it and sets up the channel for the DMA transaction. List manager holds the descriptor in the list until the DMA is complete. If sync_on_channel descriptor, or another descriptor for the same channel is present in the FIFO, list manager keeps them until the current channel is free. When the capture stream is closed suddenly while there are pending descriptors in the FIFO (streamON failed, application killed), it would keep the VPDMA in a busy state. Any further list post would fail with EBUSY. To avoid this, drivers need to stop the current processing list and cleanup all the resources VPDMA has taken and also clear the internal FSM of list manager. The state machine is cleared by issuing channel specific abort descriptor. Therefore, the vpdma_list_cleanup accepts an array of channels for which abort_channel descriptors should be posted. It is driver's responsibility to post for all the channels or the channels which were used in the last context. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 75 +++++++++++++++++++++++++++++++++++ drivers/media/platform/ti-vpe/vpdma.h | 6 +++ 2 files changed, 81 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 1a0152842a17..7808c9c1828b 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -384,6 +384,56 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) } EXPORT_SYMBOL(vpdma_unmap_desc_buf); +/* + * Cleanup all pending descriptors of a list + * First, stop the current list being processed. + * If the VPDMA was busy, this step makes vpdma to accept post lists. + * To cleanup the internal FSM, post abort list descriptor for all the + * channels from @channels array of size @size. + */ +int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num, + int *channels, int size) +{ + struct vpdma_desc_list abort_list; + int i, ret, timeout = 500; + + write_reg(vpdma, VPDMA_LIST_ATTR, + (list_num << VPDMA_LIST_NUM_SHFT) | + (1 << VPDMA_LIST_STOP_SHFT)); + + if (size <= 0 || !channels) + return 0; + + ret = vpdma_create_desc_list(&abort_list, + size * sizeof(struct vpdma_dtd), VPDMA_LIST_TYPE_NORMAL); + if (ret) + return ret; + + for (i = 0; i < size; i++) + vpdma_add_abort_channel_ctd(&abort_list, channels[i]); + + ret = vpdma_map_desc_buf(vpdma, &abort_list.buf); + if (ret) + return ret; + ret = vpdma_submit_descs(vpdma, &abort_list, list_num); + if (ret) + return ret; + + while (vpdma_list_busy(vpdma, list_num) && timeout--) + ; + + if (timeout == 0) { + dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n"); + return -EBUSY; + } + + vpdma_unmap_desc_buf(vpdma, &abort_list.buf); + vpdma_free_desc_buf(&abort_list.buf); + + return 0; +} +EXPORT_SYMBOL(vpdma_list_cleanup); + /* * create a descriptor list, the user of this list will append configuration, * control and data descriptors to this list, this list will be submitted to @@ -629,6 +679,31 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, } EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd); +/* + * append an 'abort_channel' type control descriptor to the given descriptor + * list, this descriptor aborts any DMA transaction happening using the + * specified channel + */ +void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list, + int chan_num) +{ + struct vpdma_ctd *ctd; + + ctd = list->next; + WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size)); + + ctd->w0 = 0; + ctd->w1 = 0; + ctd->w2 = 0; + ctd->type_source_ctl = ctd_type_source_ctl(chan_num, + CTD_TYPE_ABORT_CHANNEL); + + list->next = ctd + 1; + + dump_ctd(ctd); +} +EXPORT_SYMBOL(vpdma_add_abort_channel_ctd); + static void dump_dtd(struct vpdma_dtd *dtd) { int dir, chan; diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 32b9ed5191c5..4dafc1bcf116 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -163,6 +163,8 @@ enum vpdma_channel { #define VIP_CHAN_YUV_PORTB_OFFSET 2 #define VIP_CHAN_RGB_PORTB_OFFSET 1 +#define VPDMA_MAX_CHANNELS 256 + /* flags for VPDMA data descriptors */ #define VPDMA_DATA_ODD_LINE_SKIP (1 << 0) #define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1) @@ -219,6 +221,8 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, struct vpdma_buf *adb); void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, enum vpdma_channel chan); +void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list, + int chan_num); void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, const struct v4l2_rect *c_rect, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, @@ -233,6 +237,8 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, const struct vpdma_data_format *fmt, dma_addr_t dma_addr, enum vpdma_channel chan, int field, u32 flags, int frame_width, int frame_height, int start_h, int start_v); +int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num, + int *channels, int size); /* vpdma list interrupt management */ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, -- cgit v1.2.3 From 4e4676d250efbc81c70e699fc1c805d3ab370e70 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:23 -0200 Subject: [media] media: ti-vpe: vpdma: Make list post atomic operation Writing to the "VPDMA list attribute" register is considered as a list post. This informs the VPDMA firmware to load the list from the address which should be taken from the "VPDMA list address" register. As these two register writes are dependent, it is important that the two writes happen in atomic manner. This ensures multiple slices (which share same VPDMA) can post lists asynchronously and all of them point to the correct addresses. Slightly modified to implementation for the original patch to use spin_lock instead of mutex as the list post is also called from interrupt context. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 4 ++++ drivers/media/platform/ti-vpe/vpdma.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 7808c9c1828b..ffc281d2b065 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -491,6 +491,7 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list, int list_num) { int list_size; + unsigned long flags; if (vpdma_list_busy(vpdma, list_num)) return -EBUSY; @@ -498,12 +499,14 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, /* 16-byte granularity */ list_size = (list->next - list->buf.addr) >> 4; + spin_lock_irqsave(&vpdma->lock, flags); write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr); write_reg(vpdma, VPDMA_LIST_ATTR, (list_num << VPDMA_LIST_NUM_SHFT) | (list->type << VPDMA_LIST_TYPE_SHFT) | list_size); + spin_unlock_irqrestore(&vpdma->lock, flags); return 0; } @@ -1090,6 +1093,7 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev, vpdma->pdev = pdev; vpdma->cb = cb; + spin_lock_init(&vpdma->lock); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); if (res == NULL) { diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 4dafc1bcf116..f08f4370ce4a 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -35,6 +35,7 @@ struct vpdma_data { struct platform_device *pdev; + spinlock_t lock; /* callback to VPE driver when the firmware is loaded */ void (*cb)(struct platform_device *pdev); }; -- cgit v1.2.3 From afbc0ae9a42e3a447365edc47ba4a206183566ac Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:24 -0200 Subject: [media] media: ti-vpe: vpdma: Clear IRQs for individual lists VPDMA IRQs are registered for multiple lists When clearing an IRQ for a list interrupt, all the IRQs for the individual lists are to be cleared separately. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 6 +++--- drivers/media/platform/ti-vpe/vpdma.h | 3 ++- drivers/media/platform/ti-vpe/vpe.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index ffc281d2b065..c0a4e035bc2a 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -953,12 +953,12 @@ unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num) EXPORT_SYMBOL(vpdma_get_list_mask); /* clear previosuly occured list intterupts in the LIST_STAT register */ -void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num) +void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num, + int list_num) { u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num; - write_reg(vpdma, reg_addr, - read_reg(vpdma, reg_addr)); + write_reg(vpdma, reg_addr, 3 << (list_num * 2)); } EXPORT_SYMBOL(vpdma_clear_list_stat); diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index f08f4370ce4a..65961147e8f7 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -244,7 +244,8 @@ int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num, /* vpdma list interrupt management */ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, int list_num, bool enable); -void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num); +void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num, + int list_num); unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num); unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num); diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 151a9280bb85..6fcdd0ea50e4 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1326,7 +1326,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) if (irqst0) { if (irqst0 & VPE_INT0_LIST0_COMPLETE) - vpdma_clear_list_stat(ctx->dev->vpdma, 0); + vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0); irqst0 &= ~(VPE_INT0_LIST0_COMPLETE); } -- cgit v1.2.3 From 655e465671914b9d8c69d827f54d628b558dd58f Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:25 -0200 Subject: [media] media: ti-vpe: vpe: configure line mode separately Current driver configures the line mode of the DEI clients from the open function directly. Even if the newly created context is not yet scheduled, it updates some of the VPDMA registers. This causes a problem in multi instance use case where just opening the m2m device second time causes the running job to stall. This happens especially if the source buffers used are NV12. While all other configuration is being written to context specific shadow registers, only line mode configuration is happening directly. As there is no shadow register for line mode configuration, it's better to separate the config_mode setting and line_mode setting. Call the new "set_line_modes" functions only when actually loading the mmrs. This makes sure that no non-running job will write to the registers directly. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 6fcdd0ea50e4..c79137b404ea 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -660,14 +660,13 @@ static void set_us_coefficients(struct vpe_ctx *ctx) /* * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs. */ -static void set_cfg_and_line_modes(struct vpe_ctx *ctx) +static void set_cfg_modes(struct vpe_ctx *ctx) { struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; u32 *us1_reg0 = &mmr_adb->us1_regs[0]; u32 *us2_reg0 = &mmr_adb->us2_regs[0]; u32 *us3_reg0 = &mmr_adb->us3_regs[0]; - int line_mode = 1; int cfg_mode = 1; /* @@ -675,15 +674,24 @@ static void set_cfg_and_line_modes(struct vpe_ctx *ctx) * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing. */ - if (fmt->fourcc == V4L2_PIX_FMT_NV12) { + if (fmt->fourcc == V4L2_PIX_FMT_NV12) cfg_mode = 0; - line_mode = 0; /* double lines to line buffer */ - } write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); + ctx->load_mmrs = true; +} + +static void set_line_modes(struct vpe_ctx *ctx) +{ + struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; + int line_mode = 1; + + if (fmt->fourcc == V4L2_PIX_FMT_NV12) + line_mode = 0; /* double lines to line buffer */ + /* regs for now */ vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN); vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN); @@ -708,8 +716,6 @@ static void set_cfg_and_line_modes(struct vpe_ctx *ctx) /* frame start for MV in client */ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, VPE_CHAN_MV_IN); - - ctx->load_mmrs = true; } /* @@ -868,7 +874,7 @@ static int set_srcdst_params(struct vpe_ctx *ctx) if (ret) return ret; - set_cfg_and_line_modes(ctx); + set_cfg_modes(ctx); set_dei_regs(ctx); csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0], @@ -1184,6 +1190,9 @@ static void device_run(void *priv) if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) { vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb); vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb); + + set_line_modes(ctx); + ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr; ctx->load_mmrs = false; } -- cgit v1.2.3 From 0f469c1acf20b88bb8b9b91d652009dca9e9c561 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:26 -0200 Subject: [media] media: ti-vpe: vpe: Setup srcdst parameters in start_streaming For deinterlacing operation, each operation needs 2 fields in the history. This is achieved by holding three buffers in ctx->src_vbs[0,1,2] (f,f-1,f-2) This is achieved by using the ctx->sequence which gets reset via the s_fmt ioctl. These buffers are dequeued in stream OFF by calling free_vbs() But the corresponding references aren't removed anywhere. When application tries to stream ON and OFF continuously, s_fmt ioctl won't be called and it won't setup the srcdst parameters. Setting source/destination parameters in stream ON ioctl would make sure that the context is re-initialized before it is being used by the driver. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index c79137b404ea..1ee7e611e41b 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -869,6 +869,7 @@ static int set_srcdst_params(struct vpe_ctx *ctx) } free_vbs(ctx); + ctx->src_vbs[2] = ctx->src_vbs[1] = ctx->src_vbs[0] = NULL; ret = realloc_mv_buffers(ctx, mv_buf_size); if (ret) @@ -1990,6 +1991,9 @@ static int vpe_start_streaming(struct vb2_queue *q, unsigned int count) if (ctx->deinterlacing) config_edi_input_mode(ctx, 0x0); + if (ctx->sequence != 0) + set_srcdst_params(ctx); + return 0; } -- cgit v1.2.3 From 5b6179570fb3d89758c6bc93b322018edc2b2a8f Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:27 -0200 Subject: [media] media: ti-vpe: vpe: Post next descriptor only for list complete IRQ vpe_irq checks for the possible interrupt sources and prints the errors for the DEI_ERROR and DS_UV interrupts. But it also post the next descriptor list irrespective of whichever interrupt has occurred. Because of this, driver may release the buffers even before DMA is complete and also schedule next descriptor list. Fix this by _actually_ handling the IRQ only when ListComplete IRQ occurs. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 1ee7e611e41b..0f652a049ede 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1304,6 +1304,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) struct vb2_v4l2_buffer *s_vb, *d_vb; unsigned long flags; u32 irqst0, irqst1; + bool list_complete = false; irqst0 = read_reg(dev, VPE_INT0_STATUS0); if (irqst0) { @@ -1339,6 +1340,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0); irqst0 &= ~(VPE_INT0_LIST0_COMPLETE); + list_complete = true; } if (irqst0 | irqst1) { @@ -1346,6 +1348,13 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) irqst0, irqst1); } + /* + * Setup next operation only when list complete IRQ occurs + * otherwise, skip the following code + */ + if (!list_complete) + goto handled; + disable_irqs(ctx); vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); -- cgit v1.2.3 From b28b8f1d7fc73f283532cd33702b3e7a92c09fcf Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:28 -0200 Subject: [media] media: ti-vpe: vpe: Add RGB565 and RGB5551 support VPE hardware can generate output in RGB565 or in RGB5551 format. Add these formats in the supported format list for CAPTURE stream. Also, for RGB5551 format, the alpha component is not processed, so the alpha value is taken from the default color. Set the default color to make alpha component full when the dst format is of RGB color space. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 0f652a049ede..d3412accf564 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -302,6 +302,22 @@ static struct vpe_fmt vpe_formats[] = { .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32], }, }, + { + .name = "RGB565", + .fourcc = V4L2_PIX_FMT_RGB565, + .types = VPE_FMT_TYPE_CAPTURE, + .coplanar = 0, + .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB565], + }, + }, + { + .name = "RGB5551", + .fourcc = V4L2_PIX_FMT_RGB555, + .types = VPE_FMT_TYPE_CAPTURE, + .coplanar = 0, + .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGBA16_5551], + }, + }, }; /* @@ -738,9 +754,11 @@ static void set_dst_registers(struct vpe_ctx *ctx) struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; u32 val = 0; - if (clrspc == V4L2_COLORSPACE_SRGB) + if (clrspc == V4L2_COLORSPACE_SRGB) { val |= VPE_RGB_OUT_SELECT; - else if (fmt->fourcc == V4L2_PIX_FMT_NV16) + vpdma_set_bg_color(ctx->dev->vpdma, + (struct vpdma_data_format *)fmt->vpdma_fmt[0], 0xff); + } else if (fmt->fourcc == V4L2_PIX_FMT_NV16) val |= VPE_COLOR_SEPARATE_422; /* -- cgit v1.2.3 From c1cd15ea4283454f98ef22c5d1d02a59e4510b0e Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:29 -0200 Subject: [media] media: ti-vpe: vpdma: allocate and maintain hwlist VPDMA block used in ti-vip and ti-vpe modules have support for up to 8 hardware descriptor lists. A descriptor list can be submitted to any of the 8 lists (as long as it's not busy). When multiple clients want to transfer data in parallel, its easier to allocate one list per client and let it use it. This way, the list numbers need not be hard-coded into the driver. Add support for allocating hwlist and maintain them with a priv data. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 44 +++++++++++++++++++++++++++++++++++ drivers/media/platform/ti-vpe/vpdma.h | 9 +++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index c0a4e035bc2a..f85727a0ac44 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -902,6 +902,50 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, } EXPORT_SYMBOL(vpdma_add_in_dtd); +int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv) +{ + int i, list_num = -1; + unsigned long flags; + + spin_lock_irqsave(&vpdma->lock, flags); + for (i = 0; i < VPDMA_MAX_NUM_LIST && + vpdma->hwlist_used[i] == true; i++) + ; + + if (i < VPDMA_MAX_NUM_LIST) { + list_num = i; + vpdma->hwlist_used[i] = true; + vpdma->hwlist_priv[i] = priv; + } + spin_unlock_irqrestore(&vpdma->lock, flags); + + return list_num; +} +EXPORT_SYMBOL(vpdma_hwlist_alloc); + +void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num) +{ + if (!vpdma || list_num >= VPDMA_MAX_NUM_LIST) + return NULL; + + return vpdma->hwlist_priv[list_num]; +} +EXPORT_SYMBOL(vpdma_hwlist_get_priv); + +void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num) +{ + void *priv; + unsigned long flags; + + spin_lock_irqsave(&vpdma->lock, flags); + vpdma->hwlist_used[list_num] = false; + priv = vpdma->hwlist_priv; + spin_unlock_irqrestore(&vpdma->lock, flags); + + return priv; +} +EXPORT_SYMBOL(vpdma_hwlist_release); + /* set or clear the mask for list complete interrupt */ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, int list_num, bool enable) diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 65961147e8f7..ccf871ad8800 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -13,6 +13,7 @@ #ifndef __TI_VPDMA_H_ #define __TI_VPDMA_H_ +#define VPDMA_MAX_NUM_LIST 8 /* * A vpdma_buf tracks the size, DMA address and mapping status of each * driver DMA area. @@ -36,6 +37,8 @@ struct vpdma_data { struct platform_device *pdev; spinlock_t lock; + bool hwlist_used[VPDMA_MAX_NUM_LIST]; + void *hwlist_priv[VPDMA_MAX_NUM_LIST]; /* callback to VPE driver when the firmware is loaded */ void (*cb)(struct platform_device *pdev); }; @@ -215,6 +218,12 @@ bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num); void vpdma_update_dma_addr(struct vpdma_data *vpdma, struct vpdma_desc_list *list, dma_addr_t dma_addr, void *write_dtd, int drop, int idx); + +/* VPDMA hardware list funcs */ +int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv); +void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num); +void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num); + /* helpers for creating vpdma descriptors */ void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, struct vpdma_buf *blk, u32 dest_offset); -- cgit v1.2.3 From e228467caa6eb18db05c0ca62e852bba47d08f58 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:30 -0200 Subject: [media] media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint ti_vpe module currently does not get loaded automatically. Added MODULE_DEVICE_TABLE hint to the driver to assist. Signed-off-by: Benoit Parrot Reviewed-by: Javier Martinez Canillas Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index d3412accf564..05b793595ce9 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2447,6 +2447,7 @@ static const struct of_device_id vpe_of_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, vpe_of_match); #endif static struct platform_driver vpe_pdrv = { -- cgit v1.2.3 From eaa6808d1d815d8d25c7a47649503da678e48e2e Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:31 -0200 Subject: [media] media: ti-vpe: vpdma: Corrected YUV422 data type label The YUV data type definition below are taken from both the TRM and i839 Errata information. Use the correct data type considering byte reordering of components. Added the 2 missing YUV422 variant. Also since the single use of "C" in the 422 case to mean "Cr" (i.e. V component). It was decided to explicitly label them CR to remove any confusion. Bear in mind that the type label refer to the memory packed order (LSB - MSB). Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 18 ++++++++++++++---- drivers/media/platform/ti-vpe/vpdma.h | 6 ++++-- drivers/media/platform/ti-vpe/vpdma_priv.h | 19 ++++++++++++++++--- drivers/media/platform/ti-vpe/vpe.c | 8 ++++---- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index f85727a0ac44..8f0d608c70f6 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -59,9 +59,9 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = { .data_type = DATA_TYPE_C420, .depth = 4, }, - [VPDMA_DATA_FMT_YC422] = { + [VPDMA_DATA_FMT_YCR422] = { .type = VPDMA_DATA_FMT_TYPE_YUV, - .data_type = DATA_TYPE_YC422, + .data_type = DATA_TYPE_YCR422, .depth = 16, }, [VPDMA_DATA_FMT_YC444] = { @@ -69,9 +69,19 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = { .data_type = DATA_TYPE_YC444, .depth = 24, }, - [VPDMA_DATA_FMT_CY422] = { + [VPDMA_DATA_FMT_CRY422] = { .type = VPDMA_DATA_FMT_TYPE_YUV, - .data_type = DATA_TYPE_CY422, + .data_type = DATA_TYPE_CRY422, + .depth = 16, + }, + [VPDMA_DATA_FMT_CBY422] = { + .type = VPDMA_DATA_FMT_TYPE_YUV, + .data_type = DATA_TYPE_CBY422, + .depth = 16, + }, + [VPDMA_DATA_FMT_YCB422] = { + .type = VPDMA_DATA_FMT_TYPE_YUV, + .data_type = DATA_TYPE_YCB422, .depth = 16, }, }; diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index ccf871ad8800..405a6febc254 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -74,9 +74,11 @@ enum vpdma_yuv_formats { VPDMA_DATA_FMT_C444, VPDMA_DATA_FMT_C422, VPDMA_DATA_FMT_C420, - VPDMA_DATA_FMT_YC422, + VPDMA_DATA_FMT_YCR422, VPDMA_DATA_FMT_YC444, - VPDMA_DATA_FMT_CY422, + VPDMA_DATA_FMT_CRY422, + VPDMA_DATA_FMT_CBY422, + VPDMA_DATA_FMT_YCB422, }; enum vpdma_rgb_formats { diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h index 54b6aa866c74..f974a803fa27 100644 --- a/drivers/media/platform/ti-vpe/vpdma_priv.h +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h @@ -77,16 +77,29 @@ #define VPDMA_LIST_TYPE_SHFT 16 #define VPDMA_LIST_SIZE_MASK 0xffff -/* VPDMA data type values for data formats */ +/* + * The YUV data type definition below are taken from + * both the TRM and i839 Errata information. + * Use the correct data type considering byte + * reordering of components. + * + * Also since the single use of "C" in the 422 case + * to mean "Cr" (i.e. V component). It was decided + * to explicitly label them CR to remove any confusion. + * Bear in mind that the type label refer to the memory + * packed order (LSB - MSB). + */ #define DATA_TYPE_Y444 0x0 #define DATA_TYPE_Y422 0x1 #define DATA_TYPE_Y420 0x2 #define DATA_TYPE_C444 0x4 #define DATA_TYPE_C422 0x5 #define DATA_TYPE_C420 0x6 -#define DATA_TYPE_YC422 0x7 #define DATA_TYPE_YC444 0x8 -#define DATA_TYPE_CY422 0x27 +#define DATA_TYPE_YCB422 0x7 +#define DATA_TYPE_YCR422 0x17 +#define DATA_TYPE_CBY422 0x27 +#define DATA_TYPE_CRY422 0x37 #define DATA_TYPE_RGB16_565 0x0 #define DATA_TYPE_ARGB_1555 0x1 diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 05b793595ce9..ef55fb45d0be 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -237,7 +237,7 @@ struct vpe_fmt { static struct vpe_fmt vpe_formats[] = { { - .name = "YUV 422 co-planar", + .name = "NV16 YUV 422 co-planar", .fourcc = V4L2_PIX_FMT_NV16, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 1, @@ -246,7 +246,7 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "YUV 420 co-planar", + .name = "NV12 YUV 420 co-planar", .fourcc = V4L2_PIX_FMT_NV12, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 1, @@ -259,7 +259,7 @@ static struct vpe_fmt vpe_formats[] = { .fourcc = V4L2_PIX_FMT_YUYV, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 0, - .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YC422], + .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCB422], }, }, { @@ -267,7 +267,7 @@ static struct vpe_fmt vpe_formats[] = { .fourcc = V4L2_PIX_FMT_UYVY, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 0, - .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422], + .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CBY422], }, }, { -- cgit v1.2.3 From 3d7e61f6e25dd8000b46d6773b0a0249839c9554 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:32 -0200 Subject: [media] media: ti-vpe: vpdma: RGB data type yield inverted data The VPDMA RGB data type definition have been updated to match with Errata i839. But some of the ARGB definition appeared to be wrong in the document also. As they would yield RGBA instead. They have been corrected based on experimentation. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma_priv.h | 49 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h index f974a803fa27..72c7f13b4a9d 100644 --- a/drivers/media/platform/ti-vpe/vpdma_priv.h +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h @@ -101,26 +101,35 @@ #define DATA_TYPE_CBY422 0x27 #define DATA_TYPE_CRY422 0x37 -#define DATA_TYPE_RGB16_565 0x0 -#define DATA_TYPE_ARGB_1555 0x1 -#define DATA_TYPE_ARGB_4444 0x2 -#define DATA_TYPE_RGBA_5551 0x3 -#define DATA_TYPE_RGBA_4444 0x4 -#define DATA_TYPE_ARGB24_6666 0x5 -#define DATA_TYPE_RGB24_888 0x6 -#define DATA_TYPE_ARGB32_8888 0x7 -#define DATA_TYPE_RGBA24_6666 0x8 -#define DATA_TYPE_RGBA32_8888 0x9 -#define DATA_TYPE_BGR16_565 0x10 -#define DATA_TYPE_ABGR_1555 0x11 -#define DATA_TYPE_ABGR_4444 0x12 -#define DATA_TYPE_BGRA_5551 0x13 -#define DATA_TYPE_BGRA_4444 0x14 -#define DATA_TYPE_ABGR24_6666 0x15 -#define DATA_TYPE_BGR24_888 0x16 -#define DATA_TYPE_ABGR32_8888 0x17 -#define DATA_TYPE_BGRA24_6666 0x18 -#define DATA_TYPE_BGRA32_8888 0x19 +/* + * The RGB data type definition below are defined + * to follow Errata i819. + * The initial values were taken from: + * VPDMA_data_type_mapping_v0.2vayu_c.pdf + * But some of the ARGB definition appeared to be wrong + * in the document also. As they would yield RGBA instead. + * They have been corrected based on experimentation. + */ +#define DATA_TYPE_RGB16_565 0x10 +#define DATA_TYPE_ARGB_1555 0x13 +#define DATA_TYPE_ARGB_4444 0x14 +#define DATA_TYPE_RGBA_5551 0x11 +#define DATA_TYPE_RGBA_4444 0x12 +#define DATA_TYPE_ARGB24_6666 0x18 +#define DATA_TYPE_RGB24_888 0x16 +#define DATA_TYPE_ARGB32_8888 0x17 +#define DATA_TYPE_RGBA24_6666 0x15 +#define DATA_TYPE_RGBA32_8888 0x19 +#define DATA_TYPE_BGR16_565 0x0 +#define DATA_TYPE_ABGR_1555 0x3 +#define DATA_TYPE_ABGR_4444 0x4 +#define DATA_TYPE_BGRA_5551 0x1 +#define DATA_TYPE_BGRA_4444 0x2 +#define DATA_TYPE_ABGR24_6666 0x8 +#define DATA_TYPE_BGR24_888 0x6 +#define DATA_TYPE_ABGR32_8888 0x7 +#define DATA_TYPE_BGRA24_6666 0x5 +#define DATA_TYPE_BGRA32_8888 0x9 #define DATA_TYPE_MV 0x3 -- cgit v1.2.3 From bc809bfc1796accdd0c15c3bccd4e8af33922018 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:33 -0200 Subject: [media] media: ti-vpe: sc: Fix incorrect optimization Current scaler library implementation of sc_set_hs_coeffs and sc_set_vs_coeffs tries to return immediately if the calculated coefficient index is already being used. As the same scaler block is going to be used for all the VPE contexts, even if the calculated index is same, the parameters have to be reconfigured for each of the context. Because of this, when multiple contexts use the same coefficients, all other contexts would have zero scaling coefficients. Fix this and also remove the unnecessary hs_index and vs_index fields. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/sc.c | 9 --------- drivers/media/platform/ti-vpe/sc.h | 3 --- 2 files changed, 12 deletions(-) diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c index f82d1c7f667f..02f3dae8ae42 100644 --- a/drivers/media/platform/ti-vpe/sc.c +++ b/drivers/media/platform/ti-vpe/sc.c @@ -84,9 +84,6 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w, } } - if (idx == sc->hs_index) - return; - cp = scaler_hs_coeffs[idx]; for (i = 0; i < SC_NUM_PHASES * 2; i++) { @@ -101,8 +98,6 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w, coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS; } - sc->hs_index = idx; - sc->load_coeff_h = true; } @@ -130,9 +125,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h, idx = VS_LT_9_16_SCALE + sixteenths - 8; } - if (idx == sc->vs_index) - return; - cp = scaler_vs_coeffs[idx]; for (i = 0; i < SC_NUM_PHASES * 2; i++) { @@ -146,7 +138,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h, coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS; } - sc->vs_index = idx; sc->load_coeff_v = true; } diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h index 60e411e05c30..de947db98990 100644 --- a/drivers/media/platform/ti-vpe/sc.h +++ b/drivers/media/platform/ti-vpe/sc.h @@ -189,9 +189,6 @@ struct sc_data { bool load_coeff_h; /* have new h SC coeffs */ bool load_coeff_v; /* have new v SC coeffs */ - unsigned int hs_index; /* h SC coeffs selector */ - unsigned int vs_index; /* v SC coeffs selector */ - struct platform_device *pdev; }; -- cgit v1.2.3 From dfe1349dc805aa3113e6fba9db55761d24ce63fe Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:34 -0200 Subject: [media] media: ti-vpe: vpe: Fix vb2 buffer cleanup When stop_streaming is called we need to cleanup the queued vb2 buffers properly. This was not previously being done which caused kernel warning when the application using the resources was killed. Kernel warnings were also generated on successful completion of a de-interlacing case as well as upon aborting a conversion. Make sure every vb2 buffers is properly handled in all cases. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index ef55fb45d0be..f92ad7a473c1 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -605,7 +605,10 @@ static void free_vbs(struct vpe_ctx *ctx) spin_lock_irqsave(&dev->lock, flags); if (ctx->src_vbs[2]) { v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE); - v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE); + if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2])) + v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE); + ctx->src_vbs[2] = NULL; + ctx->src_vbs[1] = NULL; } spin_unlock_irqrestore(&dev->lock, flags); } @@ -1443,6 +1446,14 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data) ctx->src_vbs[1] = ctx->src_vbs[0]; } + /* + * Since the vb2_buf_done has already been called fir therse + * buffer we can now NULL them out so that we won't try + * to clean out stray pointer later on. + */ + ctx->src_vbs[0] = NULL; + ctx->dst_vb = NULL; + ctx->bufs_completed++; if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) { device_run(ctx); @@ -2027,9 +2038,57 @@ static int vpe_start_streaming(struct vb2_queue *q, unsigned int count) static void vpe_stop_streaming(struct vb2_queue *q) { struct vpe_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb; + unsigned long flags; vpe_dump_regs(ctx->dev); vpdma_dump_regs(ctx->dev->vpdma); + + for (;;) { + if (V4L2_TYPE_IS_OUTPUT(q->type)) + vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + else + vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + if (!vb) + break; + spin_lock_irqsave(&ctx->dev->lock, flags); + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + spin_unlock_irqrestore(&ctx->dev->lock, flags); + } + + /* + * Cleanup the in-transit vb2 buffers that have been + * removed from their respective queue already but for + * which procecessing has not been completed yet. + */ + if (V4L2_TYPE_IS_OUTPUT(q->type)) { + spin_lock_irqsave(&ctx->dev->lock, flags); + + if (ctx->src_vbs[2]) + v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_ERROR); + + if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2])) + v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_ERROR); + + if (ctx->src_vbs[0] && + (ctx->src_vbs[0] != ctx->src_vbs[1]) && + (ctx->src_vbs[0] != ctx->src_vbs[2])) + v4l2_m2m_buf_done(ctx->src_vbs[0], VB2_BUF_STATE_ERROR); + + ctx->src_vbs[2] = NULL; + ctx->src_vbs[1] = NULL; + ctx->src_vbs[0] = NULL; + + spin_unlock_irqrestore(&ctx->dev->lock, flags); + } else { + if (ctx->dst_vb) { + spin_lock_irqsave(&ctx->dev->lock, flags); + + v4l2_m2m_buf_done(ctx->dst_vb, VB2_BUF_STATE_ERROR); + ctx->dst_vb = NULL; + spin_unlock_irqrestore(&ctx->dev->lock, flags); + } + } } static const struct vb2_ops vpe_qops = { @@ -2222,7 +2281,6 @@ static int vpe_release(struct file *file) vpe_dbg(dev, "releasing instance %p\n", ctx); mutex_lock(&dev->dev_mutex); - free_vbs(ctx); free_mv_buffers(ctx); vpdma_free_desc_list(&ctx->desc_list); vpdma_free_desc_buf(&ctx->mmr_adb); -- cgit v1.2.3 From c786595beb89d74ff709b2ee382f34a1e0040d88 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:35 -0200 Subject: [media] media: ti-vpe: vpdma: Fix race condition for firmware loading vpdma_create API is supposed to allocated the struct vpdma_data and return it to the driver. Also, it would call the callback function when the VPDMA firmware is loaded. Typically, VPE driver have following function call: dev->vpdma = vpdma_create(pdev, firmware_load_callback); And the callback implementation would continue the probe further. Also, the dev->vpdma is accessed from the callback implementation. This may lead to race condition between assignment of dev->vpdma and the callback function being triggered. This would lead to kernel crash because of NULL pointer access. Fix this by passing a driver wrapped &vpdma_data instead of allocating inside vpdma_create. Change the vpdma_create prototype accordingly and fix return paths. Also, update the VPE driver to use the updated API and initialize the dev->vpdma before hand so that the race condition is avoided. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 17 +++++------------ drivers/media/platform/ti-vpe/vpdma.h | 2 +- drivers/media/platform/ti-vpe/vpe.c | 8 ++++---- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 8f0d608c70f6..070937fe1af6 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -1130,21 +1130,14 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma) return 0; } -struct vpdma_data *vpdma_create(struct platform_device *pdev, +int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma, void (*cb)(struct platform_device *pdev)) { struct resource *res; - struct vpdma_data *vpdma; int r; dev_dbg(&pdev->dev, "vpdma_create\n"); - vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL); - if (!vpdma) { - dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n"); - return ERR_PTR(-ENOMEM); - } - vpdma->pdev = pdev; vpdma->cb = cb; spin_lock_init(&vpdma->lock); @@ -1152,22 +1145,22 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); if (res == NULL) { dev_err(&pdev->dev, "missing platform resources data\n"); - return ERR_PTR(-ENODEV); + return -ENODEV; } vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!vpdma->base) { dev_err(&pdev->dev, "failed to ioremap\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } r = vpdma_load_firmware(vpdma); if (r) { pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE); - return ERR_PTR(r); + return r; } - return vpdma; + return 0; } EXPORT_SYMBOL(vpdma_create); diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 405a6febc254..0df156b7c1cf 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -273,7 +273,7 @@ void vpdma_set_bg_color(struct vpdma_data *vpdma, void vpdma_dump_regs(struct vpdma_data *vpdma); /* initialize vpdma, passed with VPE's platform device pointer */ -struct vpdma_data *vpdma_create(struct platform_device *pdev, +int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma, void (*cb)(struct platform_device *pdev)); #endif diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index f92ad7a473c1..15e846b95719 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -383,6 +383,7 @@ struct vpe_dev { void __iomem *base; struct resource *res; + struct vpdma_data vpdma_data; struct vpdma_data *vpdma; /* vpdma data handle */ struct sc_data *sc; /* scaler data handle */ struct csc_data *csc; /* csc data handle */ @@ -2462,11 +2463,10 @@ static int vpe_probe(struct platform_device *pdev) goto runtime_put; } - dev->vpdma = vpdma_create(pdev, vpe_fw_cb); - if (IS_ERR(dev->vpdma)) { - ret = PTR_ERR(dev->vpdma); + dev->vpdma = &dev->vpdma_data; + ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb); + if (ret) goto runtime_put; - } return 0; -- cgit v1.2.3 From 07e72eb0725ccd20b5cc26ee463def3f34606c7f Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:36 -0200 Subject: [media] media: ti-vpe: vpdma: Use bidirectional cached buffers VPDMA buffer will be used by CPU as well as by the VPDMA. CPU will write/update the VPDMA descriptors containing data about the video buffer DMA addresses. VPDMA will write the "write descriptor" containing the data about the DMA operation. When mapping/unmapping the buffer, driver has to take care of WriteBack and invalidation of the cache so that all the coherency is maintained from both directions. Use DMA_BIDIRECTIONAL to maintain coherency between CPU and VPDMA. Signed-off-by: Nikhil Devshatwar Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 070937fe1af6..2d13644a28a8 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -367,7 +367,7 @@ int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) WARN_ON(buf->mapped); buf->dma_addr = dma_map_single(dev, buf->addr, buf->size, - DMA_TO_DEVICE); + DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, buf->dma_addr)) { dev_err(dev, "failed to map buffer\n"); return -EINVAL; @@ -388,7 +388,8 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) struct device *dev = &vpdma->pdev->dev; if (buf->mapped) - dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE); + dma_unmap_single(dev, buf->dma_addr, buf->size, + DMA_BIDIRECTIONAL); buf->mapped = false; } -- cgit v1.2.3 From 00db969964c8de88ccb33db08db330634e111778 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Fri, 18 Nov 2016 21:20:37 -0200 Subject: [media] media: ti-vpe: vpe: Fix line stride for output motion vector For deinterlacing operation, VPE hardware uses motion vectors. MV calculated in the previous iteration are used for next interation. Therefore driver allocates two motion vectors in ping-pong fashion. For every transaction, one MV is DMAed in and one is DMAed out. All the outbound DMAs (DMA to memory) use output parameters, but as the motion vectors is generated purely out of input fields, it should use the input parameters for DMA. Fix the add_out_dtd to use source q_data for creating descriptor. If the output size is greater than input stride, without this change, MV DMA may overwrite the buffer causing memory corruption. This CRITICAL fix ensures that the motion vector DMA descriptor is created based on the attributes with which the buffer was allocated. Signed-off-by: Nikhil Devshatwar Signed-off-by: Ravikumar Kattekola Signed-off-by: Ravi Babu Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 15e846b95719..608d11344147 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1046,6 +1046,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) if (port == VPE_PORT_MV_OUT) { vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; dma_addr = ctx->mv_buf_dma[mv_buf_selector]; + q_data = &ctx->q_data[Q_DATA_SRC]; } else { /* to incorporate interleaved formats */ int plane = fmt->coplanar ? p_data->vb_part : 0; -- cgit v1.2.3 From b8b3ac44ddf156d0719eee1b0fb23a10a86c8163 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:38 -0200 Subject: [media] media: ti-vpe: vpe: Enable DMABUF export Allow VPE to be able to export DMA buffer. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 608d11344147..1d780ac7ff82 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1944,6 +1944,7 @@ static const struct v4l2_ioctl_ops vpe_ioctl_ops = { .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -- cgit v1.2.3 From 1c6e81783cff1a54e05b08691f5ae034af82ba0a Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:39 -0200 Subject: [media] media: ti-vpe: Make scaler library into its own module In preparation to add scaler support into VIP we need to turn sc.c into its own kernel module. Add support for multiple SC memory block as VIP contains 2 scaler instances. This is done by passing the resource name to sc_create() and modify the vpe invocation accordingly. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 4 ++++ drivers/media/platform/ti-vpe/Makefile | 4 +++- drivers/media/platform/ti-vpe/sc.c | 17 ++++++++++++++--- drivers/media/platform/ti-vpe/sc.h | 2 +- drivers/media/platform/ti-vpe/vpe.c | 2 +- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index b52b6771fc4d..5d7befad90e0 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -365,6 +365,7 @@ config VIDEO_TI_VPE select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV select VIDEO_TI_VPDMA + select VIDEO_TI_SC default n ---help--- Support for the TI VPE(Video Processing Engine) block @@ -383,6 +384,9 @@ endif # V4L_MEM2MEM_DRIVERS config VIDEO_TI_VPDMA tristate +config VIDEO_TI_SC + tristate + menuconfig V4L_TEST_DRIVERS bool "Media test drivers" depends on MEDIA_CAMERA_SUPPORT diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile index faca5e115c1d..736558d309ad 100644 --- a/drivers/media/platform/ti-vpe/Makefile +++ b/drivers/media/platform/ti-vpe/Makefile @@ -1,8 +1,10 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o +obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o -ti-vpe-y := vpe.o sc.o csc.o +ti-vpe-y := vpe.o csc.o ti-vpdma-y := vpdma.o +ti-sc-y := sc.o ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c index 02f3dae8ae42..52ce1450362f 100644 --- a/drivers/media/platform/ti-vpe/sc.c +++ b/drivers/media/platform/ti-vpe/sc.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -52,6 +53,7 @@ void sc_dump_regs(struct sc_data *sc) #undef DUMPREG } +EXPORT_SYMBOL(sc_dump_regs); /* * set the horizontal scaler coefficients according to the ratio of output to @@ -100,6 +102,7 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w, sc->load_coeff_h = true; } +EXPORT_SYMBOL(sc_set_hs_coeffs); /* * set the vertical scaler coefficients according to the ratio of output to @@ -140,6 +143,7 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h, sc->load_coeff_v = true; } +EXPORT_SYMBOL(sc_set_vs_coeffs); void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8, u32 *sc_reg17, unsigned int src_w, unsigned int src_h, @@ -267,8 +271,9 @@ void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8, *sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT); } +EXPORT_SYMBOL(sc_config_scaler); -struct sc_data *sc_create(struct platform_device *pdev) +struct sc_data *sc_create(struct platform_device *pdev, const char *res_name) { struct sc_data *sc; @@ -282,9 +287,10 @@ struct sc_data *sc_create(struct platform_device *pdev) sc->pdev = pdev; - sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sc"); + sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); if (!sc->res) { - dev_err(&pdev->dev, "missing platform resources data\n"); + dev_err(&pdev->dev, "missing '%s' platform resources data\n", + res_name); return ERR_PTR(-ENODEV); } @@ -296,3 +302,8 @@ struct sc_data *sc_create(struct platform_device *pdev) return sc; } +EXPORT_SYMBOL(sc_create); + +MODULE_DESCRIPTION("TI VIP/VPE Scaler"); +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h index de947db98990..d0aab5ef0eca 100644 --- a/drivers/media/platform/ti-vpe/sc.h +++ b/drivers/media/platform/ti-vpe/sc.h @@ -200,6 +200,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h, void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8, u32 *sc_reg17, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h); -struct sc_data *sc_create(struct platform_device *pdev); +struct sc_data *sc_create(struct platform_device *pdev, const char *res_name); #endif diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 1d780ac7ff82..ebde4f4586e6 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2453,7 +2453,7 @@ static int vpe_probe(struct platform_device *pdev) vpe_top_vpdma_reset(dev); - dev->sc = sc_create(pdev); + dev->sc = sc_create(pdev, "sc"); if (IS_ERR(dev->sc)) { ret = PTR_ERR(dev->sc); goto runtime_put; -- cgit v1.2.3 From d6a617877368c73c96d9f3adce9d9c8092bbff7d Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:40 -0200 Subject: [media] media: ti-vpe: scaler: Add debug support for multi-instance Since there might be more then one instance it is better to show the base address when dumping registers to help with debugging. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/sc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c index 52ce1450362f..e9273b713782 100644 --- a/drivers/media/platform/ti-vpe/sc.c +++ b/drivers/media/platform/ti-vpe/sc.c @@ -28,6 +28,8 @@ void sc_dump_regs(struct sc_data *sc) #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \ ioread32(sc->base + CFG_##r)) + dev_dbg(dev, "SC Registers @ %pa:\n", &sc->res->start); + DUMPREG(SC0); DUMPREG(SC1); DUMPREG(SC2); -- cgit v1.2.3 From 35be6d865c2b6c0866164fef14832ecc5def9d2b Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:41 -0200 Subject: [media] media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity When scaler is to be used we need to make sure that the input and output frame size do not exceed the maximum frame sizes that the scaler h/w can handle otherwise streaming stall as the scaler cannot proceed. The scaler buffer is limited to 2047 pixels (i.e. 11 bits) when attempting anything larger (2048 for example) the scaler stalls. Realistically in an mem2mem device we can only check for this type of issue when start_streaming is called. We can't do it during the try_fmt/s_fmt because we do not have all of the info needed at that point. So instead when start_streaming is called we need to check that the input and output frames size do not exceed the scaler's capability. The only time larger frame size are allowed is when the input frame szie is the same as the output frame size. Now in the case where we need to fail, start_streaming must return all previously queued buffer back otherwise the vb2 framework will issue kernel WARN messages. In this case we also give an error message. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/sc.h | 6 ++++ drivers/media/platform/ti-vpe/vpe.c | 71 ++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h index d0aab5ef0eca..f1fe80b38c9f 100644 --- a/drivers/media/platform/ti-vpe/sc.h +++ b/drivers/media/platform/ti-vpe/sc.h @@ -173,6 +173,12 @@ /* number of taps expected by the scaler in it's coefficient memory */ #define SC_NUM_TAPS_MEM_ALIGN 8 +/* Maximum frame width the scaler can handle (in pixels) */ +#define SC_MAX_PIXEL_WIDTH 2047 + +/* Maximum frame height the scaler can handle (in lines) */ +#define SC_MAX_PIXEL_HEIGHT 2047 + /* * coefficient memory size in bytes: * num phases x num sets(luma and chroma) x num taps(aligned) x coeff size diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index ebde4f4586e6..32489d6369ca 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2025,28 +2025,33 @@ static void vpe_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); } -static int vpe_start_streaming(struct vb2_queue *q, unsigned int count) +static int check_srcdst_sizes(struct vpe_ctx *ctx) { - struct vpe_ctx *ctx = vb2_get_drv_priv(q); + struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; + struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; + unsigned int src_w = s_q_data->c_rect.width; + unsigned int src_h = s_q_data->c_rect.height; + unsigned int dst_w = d_q_data->c_rect.width; + unsigned int dst_h = d_q_data->c_rect.height; - if (ctx->deinterlacing) - config_edi_input_mode(ctx, 0x0); + if (src_w == dst_w && src_h == dst_h) + return 0; - if (ctx->sequence != 0) - set_srcdst_params(ctx); + if (src_h <= SC_MAX_PIXEL_HEIGHT && + src_w <= SC_MAX_PIXEL_WIDTH && + dst_h <= SC_MAX_PIXEL_HEIGHT && + dst_w <= SC_MAX_PIXEL_WIDTH) + return 0; - return 0; + return -1; } -static void vpe_stop_streaming(struct vb2_queue *q) +static void vpe_return_all_buffers(struct vpe_ctx *ctx, struct vb2_queue *q, + enum vb2_buffer_state state) { - struct vpe_ctx *ctx = vb2_get_drv_priv(q); struct vb2_v4l2_buffer *vb; unsigned long flags; - vpe_dump_regs(ctx->dev); - vpdma_dump_regs(ctx->dev->vpdma); - for (;;) { if (V4L2_TYPE_IS_OUTPUT(q->type)) vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); @@ -2055,7 +2060,7 @@ static void vpe_stop_streaming(struct vb2_queue *q) if (!vb) break; spin_lock_irqsave(&ctx->dev->lock, flags); - v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(vb, state); spin_unlock_irqrestore(&ctx->dev->lock, flags); } @@ -2068,15 +2073,15 @@ static void vpe_stop_streaming(struct vb2_queue *q) spin_lock_irqsave(&ctx->dev->lock, flags); if (ctx->src_vbs[2]) - v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(ctx->src_vbs[2], state); if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2])) - v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(ctx->src_vbs[1], state); if (ctx->src_vbs[0] && (ctx->src_vbs[0] != ctx->src_vbs[1]) && (ctx->src_vbs[0] != ctx->src_vbs[2])) - v4l2_m2m_buf_done(ctx->src_vbs[0], VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(ctx->src_vbs[0], state); ctx->src_vbs[2] = NULL; ctx->src_vbs[1] = NULL; @@ -2087,13 +2092,45 @@ static void vpe_stop_streaming(struct vb2_queue *q) if (ctx->dst_vb) { spin_lock_irqsave(&ctx->dev->lock, flags); - v4l2_m2m_buf_done(ctx->dst_vb, VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(ctx->dst_vb, state); ctx->dst_vb = NULL; spin_unlock_irqrestore(&ctx->dev->lock, flags); } } } +static int vpe_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct vpe_ctx *ctx = vb2_get_drv_priv(q); + + /* Check any of the size exceed maximum scaling sizes */ + if (check_srcdst_sizes(ctx)) { + vpe_err(ctx->dev, + "Conversion setup failed, check source and destination parameters\n" + ); + vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_QUEUED); + return -EINVAL; + } + + if (ctx->deinterlacing) + config_edi_input_mode(ctx, 0x0); + + if (ctx->sequence != 0) + set_srcdst_params(ctx); + + return 0; +} + +static void vpe_stop_streaming(struct vb2_queue *q) +{ + struct vpe_ctx *ctx = vb2_get_drv_priv(q); + + vpe_dump_regs(ctx->dev); + vpdma_dump_regs(ctx->dev->vpdma); + + vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_ERROR); +} + static const struct vb2_ops vpe_qops = { .queue_setup = vpe_queue_setup, .buf_prepare = vpe_buf_prepare, -- cgit v1.2.3 From ee1c02949d99be22485c790fe1c26aaa88e77837 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:42 -0200 Subject: [media] media: ti-vpe: vpdma: Add RAW8 and RAW16 data types Add RAW8 and RAW16 data type to VPDMA. To handle RAW format we are re-using the YUV CBY422 vpdma data type so that we use the vpdma to re-order the incoming bytes, as the VIP parser assumes that the first byte presented on the bus is the MSB of a 2 bytes value. RAW8 handles from 1 to 8 bits. RAW16 handles from 9 to 16 bits. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 23 +++++++++++++++++++++++ drivers/media/platform/ti-vpe/vpdma.h | 6 ++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index 2d13644a28a8..c8f842fd7f75 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -191,6 +191,29 @@ const struct vpdma_data_format vpdma_rgb_fmts[] = { }; EXPORT_SYMBOL(vpdma_rgb_fmts); +/* + * To handle RAW format we are re-using the CBY422 + * vpdma data type so that we use the vpdma to re-order + * the incoming bytes, as the parser assumes that the + * first byte presented on the bus is the MSB of a 2 + * bytes value. + * RAW8 handles from 1 to 8 bits + * RAW16 handles from 9 to 16 bits + */ +const struct vpdma_data_format vpdma_raw_fmts[] = { + [VPDMA_DATA_FMT_RAW8] = { + .type = VPDMA_DATA_FMT_TYPE_YUV, + .data_type = DATA_TYPE_CBY422, + .depth = 8, + }, + [VPDMA_DATA_FMT_RAW16] = { + .type = VPDMA_DATA_FMT_TYPE_YUV, + .data_type = DATA_TYPE_CBY422, + .depth = 16, + }, +}; +EXPORT_SYMBOL(vpdma_raw_fmts); + const struct vpdma_data_format vpdma_misc_fmts[] = { [VPDMA_DATA_FMT_MV] = { .type = VPDMA_DATA_FMT_TYPE_MISC, diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index 0df156b7c1cf..131700c112b2 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h @@ -104,12 +104,18 @@ enum vpdma_rgb_formats { VPDMA_DATA_FMT_BGRA32, }; +enum vpdma_raw_formats { + VPDMA_DATA_FMT_RAW8 = 0, + VPDMA_DATA_FMT_RAW16, +}; + enum vpdma_misc_formats { VPDMA_DATA_FMT_MV = 0, }; extern const struct vpdma_data_format vpdma_yuv_fmts[]; extern const struct vpdma_data_format vpdma_rgb_fmts[]; +extern const struct vpdma_data_format vpdma_raw_fmts[]; extern const struct vpdma_data_format vpdma_misc_fmts[]; enum vpdma_frame_start_event { -- cgit v1.2.3 From 51b56c3941410c046c28005fce7c72f02327b42d Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:43 -0200 Subject: [media] media: ti-vpe: Make colorspace converter library into its own module In preparation to add colorspace conversion support to VIP, we need to turn csc.c into its own kernel module. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 4 ++++ drivers/media/platform/ti-vpe/Makefile | 4 +++- drivers/media/platform/ti-vpe/csc.c | 16 +++++++++++++--- drivers/media/platform/ti-vpe/csc.h | 2 +- drivers/media/platform/ti-vpe/vpe.c | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 5d7befad90e0..60e20e5f4282 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -366,6 +366,7 @@ config VIDEO_TI_VPE select V4L2_MEM2MEM_DEV select VIDEO_TI_VPDMA select VIDEO_TI_SC + select VIDEO_TI_CSC default n ---help--- Support for the TI VPE(Video Processing Engine) block @@ -387,6 +388,9 @@ config VIDEO_TI_VPDMA config VIDEO_TI_SC tristate +config VIDEO_TI_CSC + tristate + menuconfig V4L_TEST_DRIVERS bool "Media test drivers" depends on MEDIA_CAMERA_SUPPORT diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile index 736558d309ad..32504b724b5d 100644 --- a/drivers/media/platform/ti-vpe/Makefile +++ b/drivers/media/platform/ti-vpe/Makefile @@ -1,10 +1,12 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o +obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o -ti-vpe-y := vpe.o csc.o +ti-vpe-y := vpe.o ti-vpdma-y := vpdma.o ti-sc-y := sc.o +ti-csc-y := csc.o ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c index bec674994752..9fc6f70adeeb 100644 --- a/drivers/media/platform/ti-vpe/csc.c +++ b/drivers/media/platform/ti-vpe/csc.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -105,11 +106,13 @@ void csc_dump_regs(struct csc_data *csc) #undef DUMPREG } +EXPORT_SYMBOL(csc_dump_regs); void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5) { *csc_reg5 |= CSC_BYPASS; } +EXPORT_SYMBOL(csc_set_coeff_bypass); /* * set the color space converter coefficient shadow register values @@ -160,8 +163,9 @@ void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0, for (; coeff < end_coeff; coeff += 2) *shadow_csc++ = (*(coeff + 1) << 16) | *coeff; } +EXPORT_SYMBOL(csc_set_coeff); -struct csc_data *csc_create(struct platform_device *pdev) +struct csc_data *csc_create(struct platform_device *pdev, const char *res_name) { struct csc_data *csc; @@ -176,9 +180,10 @@ struct csc_data *csc_create(struct platform_device *pdev) csc->pdev = pdev; csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "csc"); + res_name); if (csc->res == NULL) { - dev_err(&pdev->dev, "missing platform resources data\n"); + dev_err(&pdev->dev, "missing '%s' platform resources data\n", + res_name); return ERR_PTR(-ENODEV); } @@ -190,3 +195,8 @@ struct csc_data *csc_create(struct platform_device *pdev) return csc; } +EXPORT_SYMBOL(csc_create); + +MODULE_DESCRIPTION("TI VIP/VPE Color Space Converter"); +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti-vpe/csc.h index 1ad2b6dad561..024700b15152 100644 --- a/drivers/media/platform/ti-vpe/csc.h +++ b/drivers/media/platform/ti-vpe/csc.h @@ -63,6 +63,6 @@ void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5); void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0, enum v4l2_colorspace src_colorspace, enum v4l2_colorspace dst_colorspace); -struct csc_data *csc_create(struct platform_device *pdev); +struct csc_data *csc_create(struct platform_device *pdev, const char *res_name); #endif diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 32489d6369ca..1e4d614bd3b6 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2496,7 +2496,7 @@ static int vpe_probe(struct platform_device *pdev) goto runtime_put; } - dev->csc = csc_create(pdev); + dev->csc = csc_create(pdev, "csc"); if (IS_ERR(dev->csc)) { ret = PTR_ERR(dev->csc); goto runtime_put; -- cgit v1.2.3 From 3ce0f30f8eadbcabab22a41b5c8cb6af7fcdefca Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:44 -0200 Subject: [media] media: ti-vpe: csc: Add debug support for multi-instance Since there might be more then one instance it is better to show the base address when dumping registers to help with debugging. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/csc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c index 9fc6f70adeeb..44b8465cf101 100644 --- a/drivers/media/platform/ti-vpe/csc.c +++ b/drivers/media/platform/ti-vpe/csc.c @@ -97,6 +97,8 @@ void csc_dump_regs(struct csc_data *csc) #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \ ioread32(csc->base + CSC_##r)) + dev_dbg(dev, "CSC Registers @ %pa:\n", &csc->res->start); + DUMPREG(CSC00); DUMPREG(CSC01); DUMPREG(CSC02); -- cgit v1.2.3 From ed1f47cc69c3f230d394e001012336877d730ea2 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Fri, 18 Nov 2016 21:20:45 -0200 Subject: [media] media: ti-vpe: vpe: Add proper support single and multi-plane buffer The VPE was restricting the number of plane per buffer based on the fact that if a particular format had color separation it was meant to need 2 planes. However NV12/NV16 are color separate format which are meant to be presented in a single contiguous buffer/plane. It could also be presented in a multi-plane as well if need be. So we must support both modes for more flexibility. The number of plane requested by user space was previously ignored and was therefore always overwritten. The driver now use the requested num plane as hint to calculate needed offset when required. Signed-off-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 58 ++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 1e4d614bd3b6..0626593a8b22 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -327,6 +327,7 @@ static struct vpe_fmt vpe_formats[] = { struct vpe_q_data { unsigned int width; /* frame width */ unsigned int height; /* frame height */ + unsigned int nplanes; /* Current number of planes */ unsigned int bytesperline[VPE_MAX_PLANES]; /* bytes per line in memory */ enum v4l2_colorspace colorspace; enum v4l2_field field; /* supported field value */ @@ -1042,6 +1043,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) int mv_buf_selector = !ctx->src_mv_buf_selector; dma_addr_t dma_addr; u32 flags = 0; + u32 offset = 0; if (port == VPE_PORT_MV_OUT) { vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; @@ -1052,13 +1054,27 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) int plane = fmt->coplanar ? p_data->vb_part : 0; vpdma_fmt = fmt->vpdma_fmt[plane]; - dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); + /* + * If we are using a single plane buffer and + * we need to set a separate vpdma chroma channel. + */ + if (q_data->nplanes == 1 && plane) { + dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + /* Compute required offset */ + offset = q_data->bytesperline[0] * q_data->height; + } else { + dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); + /* Use address as is, no offset */ + offset = 0; + } if (!dma_addr) { vpe_err(ctx->dev, "acquiring output buffer(%d) dma_addr failed\n", port); return; } + /* Apply the offset */ + dma_addr += offset; } if (q_data->flags & Q_DATA_FRAME_1D) @@ -1087,6 +1103,7 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port) int frame_width, frame_height; dma_addr_t dma_addr; u32 flags = 0; + u32 offset = 0; if (port == VPE_PORT_MV_IN) { vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; @@ -1096,14 +1113,27 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port) int plane = fmt->coplanar ? p_data->vb_part : 0; vpdma_fmt = fmt->vpdma_fmt[plane]; - - dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); + /* + * If we are using a single plane buffer and + * we need to set a separate vpdma chroma channel. + */ + if (q_data->nplanes == 1 && plane) { + dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + /* Compute required offset */ + offset = q_data->bytesperline[0] * q_data->height; + } else { + dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); + /* Use address as is, no offset */ + offset = 0; + } if (!dma_addr) { vpe_err(ctx->dev, - "acquiring input buffer(%d) dma_addr failed\n", + "acquiring output buffer(%d) dma_addr failed\n", port); return; } + /* Apply the offset */ + dma_addr += offset; if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) { /* @@ -1548,7 +1578,7 @@ static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f) pix->colorspace = s_q_data->colorspace; } - pix->num_planes = q_data->fmt->coplanar ? 2 : 1; + pix->num_planes = q_data->nplanes; for (i = 0; i < pix->num_planes; i++) { pix->plane_fmt[i].bytesperline = q_data->bytesperline[i]; @@ -1604,7 +1634,11 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, &pix->height, MIN_H, MAX_H, H_ALIGN, S_ALIGN); - pix->num_planes = fmt->coplanar ? 2 : 1; + if (!pix->num_planes) + pix->num_planes = fmt->coplanar ? 2 : 1; + else if (pix->num_planes > 1 && !fmt->coplanar) + pix->num_planes = 1; + pix->pixelformat = fmt->fourcc; /* @@ -1640,6 +1674,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, else plane_fmt->bytesperline = pix->width; + if (pix->num_planes == 1 && fmt->coplanar) + depth += fmt->vpdma_fmt[VPE_CHROMA]->depth; plane_fmt->sizeimage = (pix->height * pix->width * depth) >> 3; @@ -1686,6 +1722,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f) q_data->height = pix->height; q_data->colorspace = pix->colorspace; q_data->field = pix->field; + q_data->nplanes = pix->num_planes; for (i = 0; i < pix->num_planes; i++) { plane_fmt = &pix->plane_fmt[i]; @@ -1713,7 +1750,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f) vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d", f->type, q_data->width, q_data->height, q_data->fmt->fourcc, q_data->bytesperline[VPE_LUMA]); - if (q_data->fmt->coplanar) + if (q_data->nplanes == 2) vpe_dbg(ctx->dev, " bpl_uv %d\n", q_data->bytesperline[VPE_CHROMA]); @@ -1965,14 +2002,14 @@ static int vpe_queue_setup(struct vb2_queue *vq, q_data = get_q_data(ctx, vq->type); - *nplanes = q_data->fmt->coplanar ? 2 : 1; + *nplanes = q_data->nplanes; for (i = 0; i < *nplanes; i++) sizes[i] = q_data->sizeimage[i]; vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers, sizes[VPE_LUMA]); - if (q_data->fmt->coplanar) + if (q_data->nplanes == 2) vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]); return 0; @@ -1988,7 +2025,7 @@ static int vpe_buf_prepare(struct vb2_buffer *vb) vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type); q_data = get_q_data(ctx, vb->vb2_queue->type); - num_planes = q_data->fmt->coplanar ? 2 : 1; + num_planes = q_data->nplanes; if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (!(q_data->flags & Q_IS_INTERLACED)) { @@ -2248,6 +2285,7 @@ static int vpe_open(struct file *file) s_q_data->fmt = &vpe_formats[2]; s_q_data->width = 1920; s_q_data->height = 1080; + s_q_data->nplanes = 1; s_q_data->bytesperline[VPE_LUMA] = (s_q_data->width * s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; s_q_data->sizeimage[VPE_LUMA] = (s_q_data->bytesperline[VPE_LUMA] * -- cgit v1.2.3 From 1827bdc7b141859a1eb9d2d45bb923ea7252774a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Nov 2016 11:59:20 -0200 Subject: [media] vpfe_capture: fix compiler warning davinci/vpfe_capture.c: In function 'vpfe_probe': davinci/vpfe_capture.c:1992:9: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized] return ret; ^~~ This is indeed correct, so if the kmalloc fails set ret to -ENOMEM. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 6c41782b3ba0..bc2c62b95493 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1847,8 +1847,10 @@ static int vpfe_probe(struct platform_device *pdev) /* Allocate memory for ccdc configuration */ ccdc_cfg = kmalloc(sizeof(*ccdc_cfg), GFP_KERNEL); - if (!ccdc_cfg) + if (!ccdc_cfg) { + ret = -ENOMEM; goto probe_free_dev_mem; + } mutex_lock(&ccdc_lock); -- cgit v1.2.3 From 427da406bcaf4f51b561ed19de89f2401df85d05 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Nov 2016 08:15:15 -0200 Subject: [media] vpdma: remove vpdma_enable_list_notify_irq() Despite being exported, there's no prototype for it at the headers, as warned by sparse: Fixes this sparse warning: drivers/media/platform/ti-vpe/vpdma.c:1000:6: warning: no previous prototype for 'vpdma_enable_list_notify_irq' [-Wmissing-prototypes] void vpdma_enable_list_notify_irq(struct vpdma_data *vpdma, int irq_num, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ Worse than that, it is not even used, as making it static it would produce: drivers/media/platform/ti-vpe/vpdma.c:1000:13: warning: 'vpdma_enable_list_notify_irq' defined but not used [-Wunused-function] static void vpdma_enable_list_notify_irq(struct vpdma_data *vpdma, int irq_num, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ So, let's just get rid of the dead code. If needed in the future, someone could re-add it. Cc: Benoit Parrot Cc: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpdma.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index c8f842fd7f75..13bfd7184160 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -996,22 +996,6 @@ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num, } EXPORT_SYMBOL(vpdma_enable_list_complete_irq); -/* set or clear the mask for list complete interrupt */ -void vpdma_enable_list_notify_irq(struct vpdma_data *vpdma, int irq_num, - int list_num, bool enable) -{ - u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num; - u32 val; - - val = read_reg(vpdma, reg_addr); - if (enable) - val |= (1 << ((list_num * 2) + 1)); - else - val &= ~(1 << ((list_num * 2) + 1)); - write_reg(vpdma, reg_addr, val); -} -EXPORT_SYMBOL(vpdma_enable_list_notify_irq); - /* get the LIST_STAT register */ unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num) { -- cgit v1.2.3 From af93189d4ebc7851eb387145d0ea8db52698308e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Nov 2016 09:05:59 -0200 Subject: [media] ti-vpe: get rid of some smatch warnings When compiled on i386, it produces several warnings: ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue ./arch/x86/include/asm/bitops.h:457:22: warning: asm output is not an lvalue I suspect that some gcc optimization could be causing the asm code to be incorrectly generated. Splitting it into two macro calls fix the issues and gets us rid of 6 smatch warnings, with is a good thing. As it should not cause any troubles, as we're basically doing the same thing, let's apply such change to vpe.c. Cc: Benoit Parrot Cc: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 0626593a8b22..f0156b7759e9 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -1615,20 +1615,32 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, */ depth_bytes = depth >> 3; - if (depth_bytes == 3) + if (depth_bytes == 3) { /* * if bpp is 3(as in some RGB formats), the pixel width doesn't * really help in ensuring line stride is 16 byte aligned */ w_align = 4; - else + } else { /* * for the remainder bpp(4, 2 and 1), the pixel width alignment * can ensure a line stride alignment of 16 bytes. For example, * if bpp is 2, then the line stride can be 16 byte aligned if * the width is 8 byte aligned */ - w_align = order_base_2(VPDMA_DESC_ALIGN / depth_bytes); + + /* + * HACK: using order_base_2() here causes lots of asm output + * errors with smatch, on i386: + * ./arch/x86/include/asm/bitops.h:457:22: + * warning: asm output is not an lvalue + * Perhaps some gcc optimization is doing the wrong thing + * there. + * Let's get rid of them by doing the calculus on two steps + */ + w_align = roundup_pow_of_two(VPDMA_DESC_ALIGN / depth_bytes); + w_align = ilog2(w_align); + } v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align, &pix->height, MIN_H, MAX_H, H_ALIGN, -- cgit v1.2.3 From a56bc171598c788fd43168b5c81df8ac3c7fbde4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Nov 2016 14:06:44 -0200 Subject: [media] v4l: compat: Prevent allocating excessive amounts of memory get_v4l2_ext_controls32() is used to convert the 32-bit compat struct into native 64-bit representation. The function multiplies the array length by the entry length before validating size. Perform the size validation first. Also use unsigned values for size computation. Make similar changes to get_v4l2_buffer32() for multi-plane buffers. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index bacecbd68a6d..eac9565dc3d8 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -409,7 +409,6 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user struct v4l2_plane32 __user *uplane32; struct v4l2_plane __user *uplane; compat_caddr_t p; - int num_planes; int ret; if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) || @@ -429,12 +428,15 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user return -EFAULT; if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) { - num_planes = kp->length; - if (num_planes == 0) { + unsigned int num_planes; + + if (kp->length == 0) { kp->m.planes = NULL; /* num_planes == 0 is legal, e.g. when userspace doesn't * need planes array on DQBUF*/ return 0; + } else if (kp->length > VIDEO_MAX_PLANES) { + return -EINVAL; } if (get_user(p, &up->m.planes)) @@ -442,16 +444,16 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user uplane32 = compat_ptr(p); if (!access_ok(VERIFY_READ, uplane32, - num_planes * sizeof(struct v4l2_plane32))) + kp->length * sizeof(struct v4l2_plane32))) return -EFAULT; /* We don't really care if userspace decides to kill itself * by passing a very big num_planes value */ - uplane = compat_alloc_user_space(num_planes * - sizeof(struct v4l2_plane)); + uplane = compat_alloc_user_space(kp->length * + sizeof(struct v4l2_plane)); kp->m.planes = (__force struct v4l2_plane *)uplane; - while (--num_planes >= 0) { + for (num_planes = 0; num_planes < kp->length; num_planes++) { ret = get_v4l2_plane32(uplane, uplane32, kp->memory); if (ret) return ret; @@ -665,7 +667,7 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext { struct v4l2_ext_control32 __user *ucontrols; struct v4l2_ext_control __user *kcontrols; - int n; + unsigned int n; compat_caddr_t p; if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) || @@ -675,20 +677,22 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved))) return -EFAULT; - n = kp->count; - if (n == 0) { + if (kp->count == 0) { kp->controls = NULL; return 0; + } else if (kp->count > V4L2_CID_MAX_CTRLS) { + return -EINVAL; } if (get_user(p, &up->controls)) return -EFAULT; ucontrols = compat_ptr(p); if (!access_ok(VERIFY_READ, ucontrols, - n * sizeof(struct v4l2_ext_control32))) + kp->count * sizeof(struct v4l2_ext_control32))) return -EFAULT; - kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); + kcontrols = compat_alloc_user_space(kp->count * + sizeof(struct v4l2_ext_control)); kp->controls = (__force struct v4l2_ext_control *)kcontrols; - while (--n >= 0) { + for (n = 0; n < kp->count; n++) { u32 id; if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols))) -- cgit v1.2.3 From 2bfc04d64db66fa62021a988740e8028f018b9c3 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 9 Nov 2016 14:13:34 -0200 Subject: [media] sanyo decoder: address was being truncated The address is 13 bits but it was stuffed in an u8, so 5 bits are missing from the scancode. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-sanyo-decoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index 7331e5e7c497..b07d9caebeb1 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -56,7 +56,8 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sanyo_dec *data = &dev->raw->sanyo; u32 scancode; - u8 address, command, not_command; + u16 address; + u8 command, not_command; if (!is_timing_event(ev)) { if (ev.reset) { -- cgit v1.2.3 From 30f88a42b65858d777b8dfb40bb222fa31d5f0d9 Mon Sep 17 00:00:00 2001 From: Shailendra Verma Date: Thu, 10 Nov 2016 07:52:38 -0200 Subject: [media] staging: lirc: Improvement in code readability There is no need to call kfree() if memdup_user() fails, as no memory was allocated and the error in the error-valued pointer should be returned. Signed-off-by: Shailendra Verma Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_imon.c | 5 ++--- drivers/staging/media/lirc/lirc_sasem.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 00e00b0be275..1e650fba4a92 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -408,9 +408,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, data_buf = memdup_user(buf, n_bytes); if (IS_ERR(data_buf)) { - retval = PTR_ERR(data_buf); - data_buf = NULL; - goto exit; + mutex_unlock(&context->ctx_lock); + return PTR_ERR(data_buf); } memcpy(context->tx.data_buf, data_buf, n_bytes); diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index 4678ae10b030..4fd810bc46de 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -384,9 +384,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, data_buf = memdup_user(buf, n_bytes); if (IS_ERR(data_buf)) { - retval = PTR_ERR(data_buf); - data_buf = NULL; - goto exit; + mutex_unlock(&context->ctx_lock); + return PTR_ERR(data_buf); } memcpy(context->tx.data_buf, data_buf, n_bytes); -- cgit v1.2.3 From 61393b0732fadc1efb2682c92062a54ff9f8fe0b Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 24 Sep 2016 19:40:19 -0300 Subject: [media] mn88473: add DVBv5 statistics support Implement DVBv5 statistics support for DVB-T, DVB-T2 and DVB-C. All information was taken from the LinuxTV wiki, where Benjamin Larsson has documented all registers: https://www.linuxtv.org/wiki/index.php/Panasonic_MN88472 Signed-off-by: Martin Blumenstingl Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 485 ++++++++++++++++++++++++++--- drivers/media/dvb-frontends/mn88473_priv.h | 1 + 2 files changed, 445 insertions(+), 41 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index 451974a1d7ed..c8dc9d381201 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -234,13 +234,388 @@ err: return ret; } +static int mn88473_update_ber_stat_t_c(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + u64 total; + unsigned int uitmp, value, errors; + + if (*status & FE_HAS_LOCK) { + ret = regmap_read(dev->regmap[0], 0x5b, &value); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[0], 0xdf, &uitmp); + if (ret) + goto err; + + value &= uitmp; + ret = regmap_write(dev->regmap[0], 0x5b, value); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[0], 0x60, &value); + if (ret) + goto err; + + value &= 0xf0; + value |= 0x5; + ret = regmap_write(dev->regmap[0], 0x60, value); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[0], 0x92, &uitmp); + if (ret) + goto err; + + errors = uitmp << 16; + + ret = regmap_read(dev->regmap[0], 0x93, &uitmp); + if (ret) + goto err; + + errors |= uitmp << 8; + + ret = regmap_read(dev->regmap[0], 0x94, &uitmp); + if (ret) + goto err; + + errors |= uitmp; + + ret = regmap_read(dev->regmap[0], 0x95, &uitmp); + if (ret) + goto err; + + total = uitmp << 8; + + ret = regmap_read(dev->regmap[0], 0x96, &uitmp); + if (ret) + goto err; + + total |= uitmp; + + /* probably: (bytes -> bit) * (sizeof(TS packet) - 1) */ + total *= 8 * 203; + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += errors; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue += total; + } else { + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + return 0; + +err: + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_update_ber_stat_t2(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + u64 total; + unsigned int uitmp, value, berlen, fec_type_m, errors; + static u16 fec_type_m_tbl0[] = { + 32400, 38880, 43200, 48600, 51840, 54000, 0 + }; + static u16 fec_type_m_tbl1[] = { + 28800, 38880, 43200, 47520, 50400, 53280, 0 + }; + + if (*status & FE_HAS_LOCK) { + ret = regmap_read(dev->regmap[2], 0x82, &value); + if (ret) + goto err; + + value |= 0x20; + value &= 0xef; + ret = regmap_write(dev->regmap[2], 0x82, value); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[2], 0xba, &uitmp); + if (ret) + goto err; + + errors = uitmp << 16; + + ret = regmap_read(dev->regmap[2], 0xbb, &uitmp); + if (ret) + goto err; + + errors |= uitmp << 8; + + ret = regmap_read(dev->regmap[2], 0xbc, &uitmp); + if (ret) + goto err; + + errors |= uitmp; + + ret = regmap_read(dev->regmap[2], 0x83, &berlen); + if (ret) + goto err; + + ret = regmap_write(dev->regmap[2], 0xc0, 0x3); + if (ret) + goto err; + + /* berlen[4:2] are the index in fec_type_m_tbl */ + uitmp = (berlen >> 2) & 0x7; + + if (BIT(0) & berlen) + fec_type_m = fec_type_m_tbl0[uitmp]; + else + fec_type_m = fec_type_m_tbl1[uitmp]; + + total = ((berlen & 0xff) << 1) * fec_type_m; + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += errors; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue += total; + } else { + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + return 0; + +err: + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + return ret; +} + +static inline u32 log10times1000(u32 value) +{ + return (1000L * intlog10(value)) >> 24; +} + +static int mn88473_read_status_t(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + s32 cnr; + unsigned int uitmp, tmp_upper, tmp_lower; + + ret = regmap_read(dev->regmap[0], 0x62, &uitmp); + if (ret) + goto err; + + if (!(uitmp & 0xa0)) { + if ((uitmp & 0x0f) >= 0x09) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + else if ((uitmp & 0x0f) >= 0x03) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; + } + + /* CNR */ + if (*status & FE_HAS_VITERBI) { + ret = regmap_read(dev->regmap[0], 0x8f, &tmp_upper); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[0], 0x90, &tmp_lower); + if (ret) + goto err; + + uitmp = (tmp_upper << 8) | tmp_lower; + if (uitmp) { + cnr = log10times1000(65536); + cnr -= log10times1000(uitmp); + cnr += 200; + } else + cnr = 0; + + if (cnr < 0) + cnr = 0; + + c->cnr.stat[0].svalue = cnr * 10; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* BER */ + ret = mn88473_update_ber_stat_t_c(fe, status); + if (ret) + goto err; + + return 0; + +err: + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_read_status_t2(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + s32 cnr; + unsigned int uitmp, tmp_upper, tmp_lower, flag; + + ret = regmap_read(dev->regmap[2], 0x8b, &uitmp); + if (ret) + goto err; + + if (!(uitmp & 0x40)) { + if ((uitmp & 0x0f) >= 0x0d) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + else if ((uitmp & 0x0f) >= 0x0a) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI; + else if ((uitmp & 0x0f) >= 0x07) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; + } + + /* CNR */ + if (*status & FE_HAS_VITERBI) { + ret = regmap_read(dev->regmap[2], 0xb7, &flag); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[2], 0xb8, &tmp_upper); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[2], 0xb9, &tmp_lower); + if (ret) + goto err; + + uitmp = (tmp_upper << 8) | tmp_lower; + if (uitmp) { + if (flag & BIT(2)) { + /* MISO */ + cnr = log10times1000(16384); + cnr -= log10times1000(uitmp); + cnr -= 600; + } else { + /* SISO */ + cnr = log10times1000(65536); + cnr -= log10times1000(uitmp); + cnr += 200; + } + } else + cnr = 0; + + if (cnr < 0) + cnr = 0; + + c->cnr.stat[0].svalue = cnr * 10; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* BER */ + ret = mn88473_update_ber_stat_t2(fe, status); + if (ret) + goto err; + + return 0; + +err: + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_read_status_c(struct dvb_frontend *fe, + enum fe_status *status) +{ + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + unsigned int uitmp, tmp_upper, tmp_lower, signal, noise; + + ret = regmap_read(dev->regmap[1], 0x85, &uitmp); + if (ret) + goto err; + + if (!(uitmp & 0x40)) { + ret = regmap_read(dev->regmap[1], 0x89, &uitmp); + if (ret) + goto err; + + if (uitmp & 0x01) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + } + + /* CNR */ + if (*status & FE_HAS_VITERBI) { + ret = regmap_read(dev->regmap[1], 0xa1, &tmp_upper); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[1], 0xa2, &tmp_lower); + if (ret) + goto err; + + signal = (tmp_upper << 8) | tmp_lower; + + ret = regmap_read(dev->regmap[1], 0xa3, &tmp_upper); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[1], 0xa4, &tmp_lower); + if (ret) + goto err; + + noise = (tmp_upper << 8) | tmp_lower; + if (noise) + uitmp = log10times1000(signal * 8 / noise); + else + uitmp = 0; + + c->cnr.stat[0].svalue = uitmp * 10; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* BER */ + ret = mn88473_update_ber_stat_t_c(fe, status); + if (ret) + goto err; + + return 0; + +err: + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + return ret; +} + static int mn88473_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct mn88473_dev *dev = i2c_get_clientdata(client); struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - unsigned int uitmp; + u16 errors, per_len; + unsigned int upper, lower; if (!dev->active) { ret = -EAGAIN; @@ -251,60 +626,73 @@ static int mn88473_read_status(struct dvb_frontend *fe, enum fe_status *status) switch (c->delivery_system) { case SYS_DVBT: - ret = regmap_read(dev->regmap[0], 0x62, &uitmp); + ret = mn88473_read_status_t(fe, status); + break; + case SYS_DVBT2: + ret = mn88473_read_status_t2(fe, status); + break; + case SYS_DVBC_ANNEX_A: + ret = mn88473_read_status_c(fe, status); + break; + default: + ret = -EINVAL; + break; + } + + if (ret) + goto err; + + /* signal strength, derived from AGC */ + if (*status & FE_HAS_SIGNAL) { + ret = regmap_read(dev->regmap[2], 0x86, &upper); if (ret) goto err; - if (!(uitmp & 0xa0)) { - if ((uitmp & 0x0f) >= 0x09) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - else if ((uitmp & 0x0f) >= 0x03) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; - } - break; - case SYS_DVBT2: - ret = regmap_read(dev->regmap[2], 0x8b, &uitmp); + ret = regmap_read(dev->regmap[2], 0x87, &lower); if (ret) goto err; - if (!(uitmp & 0x40)) { - if ((uitmp & 0x0f) >= 0x0d) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - else if ((uitmp & 0x0f) >= 0x0a) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI; - else if ((uitmp & 0x0f) >= 0x07) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; - } - break; - case SYS_DVBC_ANNEX_A: - ret = regmap_read(dev->regmap[1], 0x85, &uitmp); + /* AGCRD[15:6] gives us a 10bit value ([5:0] are always 0) */ + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = (upper << 8) | lower; + } else { + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* PER */ + if (*status & FE_HAS_LOCK) { + ret = regmap_read(dev->regmap[0], 0xdd, &upper); if (ret) goto err; - if (!(uitmp & 0x40)) { - ret = regmap_read(dev->regmap[1], 0x89, &uitmp); - if (ret) - goto err; + ret = regmap_read(dev->regmap[0], 0xde, &lower); + if (ret) + goto err; - if (uitmp & 0x01) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - } - break; - default: - ret = -EINVAL; - goto err; + errors = (upper << 8) | lower; + + ret = regmap_read(dev->regmap[0], 0xdf, &upper); + if (ret) + goto err; + + ret = regmap_read(dev->regmap[0], 0xe0, &lower); + if (ret) + goto err; + + per_len = (upper << 8) | lower; + + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += errors; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].uvalue += per_len; + } else { + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; } return 0; err: - dev_dbg(&client->dev, "failed=%d\n", ret); + dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); return ret; } @@ -312,6 +700,7 @@ static int mn88473_init(struct dvb_frontend *fe) { struct i2c_client *client = fe->demodulator_priv; struct mn88473_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remain; unsigned int uitmp; const struct firmware *fw; @@ -378,6 +767,20 @@ warm: dev->active = true; + /* init stats here to indicate which stats are supported */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.len = 1; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.len = 1; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.len = 1; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return 0; err_release_firmware: release_firmware(fw); diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h index e6c65893e451..7cbef7b7fb39 100644 --- a/drivers/media/dvb-frontends/mn88473_priv.h +++ b/drivers/media/dvb-frontends/mn88473_priv.h @@ -18,6 +18,7 @@ #define MN88473_PRIV_H #include "dvb_frontend.h" +#include "dvb_math.h" #include "mn88473.h" #include #include -- cgit v1.2.3 From 69ace6ee3e3d088c6c8bd4aab42001fc6ba9d701 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2016 05:25:54 -0200 Subject: [media] mn88473: refactor and fix statistics Remove DVB-T2 BER as it does not work at all and I didn't find how to fix. Fix DVB-T and DVB-C BER. It seems to return new some realistic looking values. Use (1 << 24) base for CNR calculations to keep it in line with dvb logarithm functions. Move all statistic logic to mn88473_read_status() function. Use regmap_bulk_read() for reading multiple registers as a one go. Many more and less minor changes. Cc: Martin Blumenstingl Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 560 +++++++++-------------------- drivers/media/dvb-frontends/mn88473_priv.h | 1 + 2 files changed, 161 insertions(+), 400 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index c8dc9d381201..f3b59a5827d9 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -234,465 +234,225 @@ err: return ret; } -static int mn88473_update_ber_stat_t_c(struct dvb_frontend *fe, - enum fe_status *status) +static int mn88473_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct mn88473_dev *dev = i2c_get_clientdata(client); struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - u64 total; - unsigned int uitmp, value, errors; - - if (*status & FE_HAS_LOCK) { - ret = regmap_read(dev->regmap[0], 0x5b, &value); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0xdf, &uitmp); - if (ret) - goto err; - - value &= uitmp; - ret = regmap_write(dev->regmap[0], 0x5b, value); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0x60, &value); - if (ret) - goto err; - - value &= 0xf0; - value |= 0x5; - ret = regmap_write(dev->regmap[0], 0x60, value); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0x92, &uitmp); - if (ret) - goto err; - - errors = uitmp << 16; - - ret = regmap_read(dev->regmap[0], 0x93, &uitmp); - if (ret) - goto err; - - errors |= uitmp << 8; - - ret = regmap_read(dev->regmap[0], 0x94, &uitmp); - if (ret) - goto err; - - errors |= uitmp; - - ret = regmap_read(dev->regmap[0], 0x95, &uitmp); - if (ret) - goto err; - - total = uitmp << 8; + int ret, i, stmp; + unsigned int utmp, utmp1, utmp2; + u8 buf[5]; - ret = regmap_read(dev->regmap[0], 0x96, &uitmp); - if (ret) - goto err; - - total |= uitmp; - - /* probably: (bytes -> bit) * (sizeof(TS packet) - 1) */ - total *= 8 * 203; - - c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[0].uvalue += errors; - c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[0].uvalue += total; - } else { - c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + if (!dev->active) { + ret = -EAGAIN; + goto err; } - return 0; - -err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); - return ret; -} - -static int mn88473_update_ber_stat_t2(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct i2c_client *client = fe->demodulator_priv; - struct mn88473_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - u64 total; - unsigned int uitmp, value, berlen, fec_type_m, errors; - static u16 fec_type_m_tbl0[] = { - 32400, 38880, 43200, 48600, 51840, 54000, 0 - }; - static u16 fec_type_m_tbl1[] = { - 28800, 38880, 43200, 47520, 50400, 53280, 0 - }; - - if (*status & FE_HAS_LOCK) { - ret = regmap_read(dev->regmap[2], 0x82, &value); - if (ret) - goto err; - - value |= 0x20; - value &= 0xef; - ret = regmap_write(dev->regmap[2], 0x82, value); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[2], 0xba, &uitmp); - if (ret) - goto err; - - errors = uitmp << 16; - - ret = regmap_read(dev->regmap[2], 0xbb, &uitmp); - if (ret) - goto err; - - errors |= uitmp << 8; - - ret = regmap_read(dev->regmap[2], 0xbc, &uitmp); - if (ret) - goto err; - - errors |= uitmp; - - ret = regmap_read(dev->regmap[2], 0x83, &berlen); + /* Lock detection */ + switch (c->delivery_system) { + case SYS_DVBT: + ret = regmap_read(dev->regmap[0], 0x62, &utmp); if (ret) goto err; - ret = regmap_write(dev->regmap[2], 0xc0, 0x3); + if (!(utmp & 0xa0)) { + if ((utmp & 0x0f) >= 0x09) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + else if ((utmp & 0x0f) >= 0x03) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; + } else { + *status = 0; + } + break; + case SYS_DVBT2: + ret = regmap_read(dev->regmap[2], 0x8b, &utmp); + if (ret) + goto err; + + if (!(utmp & 0x40)) { + if ((utmp & 0x0f) >= 0x0d) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + else if ((utmp & 0x0f) >= 0x0a) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI; + else if ((utmp & 0x0f) >= 0x07) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; + } else { + *status = 0; + } + break; + case SYS_DVBC_ANNEX_A: + ret = regmap_read(dev->regmap[1], 0x85, &utmp); if (ret) goto err; - /* berlen[4:2] are the index in fec_type_m_tbl */ - uitmp = (berlen >> 2) & 0x7; - - if (BIT(0) & berlen) - fec_type_m = fec_type_m_tbl0[uitmp]; - else - fec_type_m = fec_type_m_tbl1[uitmp]; - - total = ((berlen & 0xff) << 1) * fec_type_m; - - c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[0].uvalue += errors; - c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[0].uvalue += total; - } else { - c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - } - - return 0; - -err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); - return ret; -} - -static inline u32 log10times1000(u32 value) -{ - return (1000L * intlog10(value)) >> 24; -} - -static int mn88473_read_status_t(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct i2c_client *client = fe->demodulator_priv; - struct mn88473_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - s32 cnr; - unsigned int uitmp, tmp_upper, tmp_lower; + if (!(utmp & 0x40)) { + ret = regmap_read(dev->regmap[1], 0x89, &utmp); + if (ret) + goto err; - ret = regmap_read(dev->regmap[0], 0x62, &uitmp); - if (ret) + if (utmp & 0x01) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + } else { + *status = 0; + } + break; + default: + ret = -EINVAL; goto err; - - if (!(uitmp & 0xa0)) { - if ((uitmp & 0x0f) >= 0x09) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - else if ((uitmp & 0x0f) >= 0x03) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; } - /* CNR */ - if (*status & FE_HAS_VITERBI) { - ret = regmap_read(dev->regmap[0], 0x8f, &tmp_upper); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0x90, &tmp_lower); - if (ret) - goto err; - - uitmp = (tmp_upper << 8) | tmp_lower; - if (uitmp) { - cnr = log10times1000(65536); - cnr -= log10times1000(uitmp); - cnr += 200; - } else - cnr = 0; + /* Signal strength */ + if (*status & FE_HAS_SIGNAL) { + for (i = 0; i < 2; i++) { + ret = regmap_bulk_read(dev->regmap[2], 0x86 + i, + &buf[i], 1); + if (ret) + goto err; + } - if (cnr < 0) - cnr = 0; + /* AGCRD[15:6] gives us a 10bit value ([5:0] are always 0) */ + utmp1 = buf[0] << 8 | buf[1] << 0 | buf[0] >> 2; + dev_dbg(&client->dev, "strength=%u\n", utmp1); - c->cnr.stat[0].svalue = cnr * 10; - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = utmp1; } else { - c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - } - - /* BER */ - ret = mn88473_update_ber_stat_t_c(fe, status); - if (ret) - goto err; - - return 0; - -err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); - return ret; -} - -static int mn88473_read_status_t2(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct i2c_client *client = fe->demodulator_priv; - struct mn88473_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - s32 cnr; - unsigned int uitmp, tmp_upper, tmp_lower, flag; - - ret = regmap_read(dev->regmap[2], 0x8b, &uitmp); - if (ret) - goto err; - - if (!(uitmp & 0x40)) { - if ((uitmp & 0x0f) >= 0x0d) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - else if ((uitmp & 0x0f) >= 0x0a) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI; - else if ((uitmp & 0x0f) >= 0x07) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } /* CNR */ - if (*status & FE_HAS_VITERBI) { - ret = regmap_read(dev->regmap[2], 0xb7, &flag); + if (*status & FE_HAS_VITERBI && c->delivery_system == SYS_DVBT) { + /* DVB-T CNR */ + ret = regmap_bulk_read(dev->regmap[0], 0x8f, buf, 2); if (ret) goto err; - ret = regmap_read(dev->regmap[2], 0xb8, &tmp_upper); - if (ret) - goto err; + utmp = buf[0] << 8 | buf[1] << 0; + if (utmp) { + /* CNR[dB]: 10 * (log10(65536 / value) + 0.2) */ + /* log10(65536) = 80807124, 0.2 = 3355443 */ + stmp = div_u64(((u64)80807124 - intlog10(utmp) + + 3355443) * 10000, 1 << 24); + dev_dbg(&client->dev, "cnr=%d value=%u\n", stmp, utmp); + } else { + stmp = 0; + } - ret = regmap_read(dev->regmap[2], 0xb9, &tmp_lower); - if (ret) - goto err; + c->cnr.stat[0].svalue = stmp; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + } else if (*status & FE_HAS_VITERBI && + c->delivery_system == SYS_DVBT2) { + /* DVB-T2 CNR */ + for (i = 0; i < 3; i++) { + ret = regmap_bulk_read(dev->regmap[2], 0xb7 + i, + &buf[i], 1); + if (ret) + goto err; + } - uitmp = (tmp_upper << 8) | tmp_lower; - if (uitmp) { - if (flag & BIT(2)) { - /* MISO */ - cnr = log10times1000(16384); - cnr -= log10times1000(uitmp); - cnr -= 600; + utmp = buf[1] << 8 | buf[2] << 0; + utmp1 = (buf[0] >> 2) & 0x01; /* 0=SISO, 1=MISO */ + if (utmp) { + if (utmp1) { + /* CNR[dB]: 10 * (log10(16384 / value) - 0.6) */ + /* log10(16384) = 70706234, 0.6 = 10066330 */ + stmp = div_u64(((u64)70706234 - intlog10(utmp) + - 10066330) * 10000, 1 << 24); + dev_dbg(&client->dev, "cnr=%d value=%u MISO\n", + stmp, utmp); } else { - /* SISO */ - cnr = log10times1000(65536); - cnr -= log10times1000(uitmp); - cnr += 200; + /* CNR[dB]: 10 * (log10(65536 / value) + 0.2) */ + /* log10(65536) = 80807124, 0.2 = 3355443 */ + stmp = div_u64(((u64)80807124 - intlog10(utmp) + + 3355443) * 10000, 1 << 24); + dev_dbg(&client->dev, "cnr=%d value=%u SISO\n", + stmp, utmp); } - } else - cnr = 0; - - if (cnr < 0) - cnr = 0; + } else { + stmp = 0; + } - c->cnr.stat[0].svalue = cnr * 10; + c->cnr.stat[0].svalue = stmp; c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - } else { - c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - } - - /* BER */ - ret = mn88473_update_ber_stat_t2(fe, status); - if (ret) - goto err; - - return 0; - -err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); - return ret; -} - -static int mn88473_read_status_c(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct i2c_client *client = fe->demodulator_priv; - struct mn88473_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - unsigned int uitmp, tmp_upper, tmp_lower, signal, noise; - - ret = regmap_read(dev->regmap[1], 0x85, &uitmp); - if (ret) - goto err; - - if (!(uitmp & 0x40)) { - ret = regmap_read(dev->regmap[1], 0x89, &uitmp); - if (ret) - goto err; - - if (uitmp & 0x01) - *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - } - - /* CNR */ - if (*status & FE_HAS_VITERBI) { - ret = regmap_read(dev->regmap[1], 0xa1, &tmp_upper); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[1], 0xa2, &tmp_lower); - if (ret) - goto err; - - signal = (tmp_upper << 8) | tmp_lower; - - ret = regmap_read(dev->regmap[1], 0xa3, &tmp_upper); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[1], 0xa4, &tmp_lower); - if (ret) - goto err; - - noise = (tmp_upper << 8) | tmp_lower; - if (noise) - uitmp = log10times1000(signal * 8 / noise); - else - uitmp = 0; + } else if (*status & FE_HAS_VITERBI && + c->delivery_system == SYS_DVBC_ANNEX_A) { + /* DVB-C CNR */ + ret = regmap_bulk_read(dev->regmap[1], 0xa1, buf, 4); + if (ret) + goto err; + + utmp1 = buf[0] << 8 | buf[1] << 0; /* signal */ + utmp2 = buf[2] << 8 | buf[3] << 0; /* noise */ + if (utmp1 && utmp2) { + /* CNR[dB]: 10 * log10(8 * (signal / noise)) */ + /* log10(8) = 15151336 */ + stmp = div_u64(((u64)15151336 + intlog10(utmp1) + - intlog10(utmp2)) * 10000, 1 << 24); + dev_dbg(&client->dev, "cnr=%d signal=%u noise=%u\n", + stmp, utmp1, utmp2); + } else { + stmp = 0; + } - c->cnr.stat[0].svalue = uitmp * 10; + c->cnr.stat[0].svalue = stmp; c->cnr.stat[0].scale = FE_SCALE_DECIBEL; } else { c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } /* BER */ - ret = mn88473_update_ber_stat_t_c(fe, status); - if (ret) - goto err; - - return 0; - -err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); - return ret; -} - -static int mn88473_read_status(struct dvb_frontend *fe, enum fe_status *status) -{ - struct i2c_client *client = fe->demodulator_priv; - struct mn88473_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - u16 errors, per_len; - unsigned int upper, lower; - - if (!dev->active) { - ret = -EAGAIN; - goto err; - } - - *status = 0; - - switch (c->delivery_system) { - case SYS_DVBT: - ret = mn88473_read_status_t(fe, status); - break; - case SYS_DVBT2: - ret = mn88473_read_status_t2(fe, status); - break; - case SYS_DVBC_ANNEX_A: - ret = mn88473_read_status_c(fe, status); - break; - default: - ret = -EINVAL; - break; - } - - if (ret) - goto err; - - /* signal strength, derived from AGC */ - if (*status & FE_HAS_SIGNAL) { - ret = regmap_read(dev->regmap[2], 0x86, &upper); + if (*status & FE_HAS_LOCK && (c->delivery_system == SYS_DVBT || + c->delivery_system == SYS_DVBC_ANNEX_A)) { + /* DVB-T & DVB-C BER */ + ret = regmap_bulk_read(dev->regmap[0], 0x92, buf, 5); if (ret) goto err; - ret = regmap_read(dev->regmap[2], 0x87, &lower); - if (ret) - goto err; + utmp1 = buf[0] << 16 | buf[1] << 8 | buf[2] << 0; + utmp2 = buf[3] << 8 | buf[4] << 0; + utmp2 = utmp2 * 8 * 204; + dev_dbg(&client->dev, "post_bit_error=%u post_bit_count=%u\n", + utmp1, utmp2); - /* AGCRD[15:6] gives us a 10bit value ([5:0] are always 0) */ - c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = (upper << 8) | lower; + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += utmp1; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue += utmp2; } else { - c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } /* PER */ if (*status & FE_HAS_LOCK) { - ret = regmap_read(dev->regmap[0], 0xdd, &upper); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0xde, &lower); - if (ret) - goto err; - - errors = (upper << 8) | lower; - - ret = regmap_read(dev->regmap[0], 0xdf, &upper); - if (ret) - goto err; - - ret = regmap_read(dev->regmap[0], 0xe0, &lower); + ret = regmap_bulk_read(dev->regmap[0], 0xdd, buf, 4); if (ret) goto err; - per_len = (upper << 8) | lower; + utmp1 = buf[0] << 8 | buf[1] << 0; + utmp2 = buf[2] << 8 | buf[3] << 0; + dev_dbg(&client->dev, "block_error=%u block_count=%u\n", + utmp1, utmp2); c->block_error.stat[0].scale = FE_SCALE_COUNTER; - c->block_error.stat[0].uvalue += errors; + c->block_error.stat[0].uvalue += utmp1; c->block_count.stat[0].scale = FE_SCALE_COUNTER; - c->block_count.stat[0].uvalue += per_len; + c->block_count.stat[0].uvalue += utmp2; } else { - c->block_error.stat[0].scale = FE_SCALE_COUNTER; - c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } return 0; err: - dev_dbg(&client->dev, "%s failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h index 7cbef7b7fb39..5fc463d147c8 100644 --- a/drivers/media/dvb-frontends/mn88473_priv.h +++ b/drivers/media/dvb-frontends/mn88473_priv.h @@ -20,6 +20,7 @@ #include "dvb_frontend.h" #include "dvb_math.h" #include "mn88473.h" +#include #include #include -- cgit v1.2.3 From 414e72c729534a89017bc19415edc4957ebcc6fa Mon Sep 17 00:00:00 2001 From: Ruqiang Ju Date: Tue, 15 Nov 2016 05:31:32 -0200 Subject: [media] ir-hix5hd2: make hisilicon,power-syscon property deprecated The clock of IR can be provided by the clock provider and controlled by common clock framework APIs. Signed-off-by: Ruqiang Ju Signed-off-by: Jiancheng Xue Acked-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/hix5hd2-ir.txt | 6 +++--- drivers/media/rc/ir-hix5hd2.c | 25 ++++++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/media/hix5hd2-ir.txt b/Documentation/devicetree/bindings/media/hix5hd2-ir.txt index fb5e7606643a..54e1bede6244 100644 --- a/Documentation/devicetree/bindings/media/hix5hd2-ir.txt +++ b/Documentation/devicetree/bindings/media/hix5hd2-ir.txt @@ -8,10 +8,11 @@ Required properties: the device. The interrupt specifier format depends on the interrupt controller parent. - clocks: clock phandle and specifier pair. - - hisilicon,power-syscon: phandle of syscon used to control power. Optional properties: - linux,rc-map-name : Remote control map name. + - hisilicon,power-syscon: DEPRECATED. Don't use this in new dts files. + Provide correct clocks instead. Example node: @@ -19,7 +20,6 @@ Example node: compatible = "hisilicon,hix5hd2-ir"; reg = <0xf8001000 0x1000>; interrupts = <0 47 4>; - clocks = <&clock HIX5HD2_FIXED_24M>; - hisilicon,power-syscon = <&sysctrl>; + clocks = <&clock HIX5HD2_IR_CLOCK>; linux,rc-map-name = "rc-tivo"; }; diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index d0549fba711c..d26907e684dc 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -75,15 +75,22 @@ static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on) { u32 val; - regmap_read(dev->regmap, IR_CLK, &val); - if (on) { - val &= ~IR_CLK_RESET; - val |= IR_CLK_ENABLE; + if (dev->regmap) { + regmap_read(dev->regmap, IR_CLK, &val); + if (on) { + val &= ~IR_CLK_RESET; + val |= IR_CLK_ENABLE; + } else { + val &= ~IR_CLK_ENABLE; + val |= IR_CLK_RESET; + } + regmap_write(dev->regmap, IR_CLK, val); } else { - val &= ~IR_CLK_ENABLE; - val |= IR_CLK_RESET; + if (on) + clk_prepare_enable(dev->clock); + else + clk_disable_unprepare(dev->clock); } - regmap_write(dev->regmap, IR_CLK, val); } static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv) @@ -207,8 +214,8 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) priv->regmap = syscon_regmap_lookup_by_phandle(node, "hisilicon,power-syscon"); if (IS_ERR(priv->regmap)) { - dev_err(dev, "no power-reg\n"); - return -EINVAL; + dev_info(dev, "no power-reg\n"); + priv->regmap = NULL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From d08876f524a605d64c7ca32cb8e9f5be3839e82e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 16 Nov 2016 09:11:54 -0200 Subject: [media] stk-webcam: fix an endian bug in stk_camera_read_reg() We pass an int pointer to stk_camera_read_reg() but only write to the highest byte. It's a bug on big endian systems and generally a nasty thing to do and doesn't match the write function either. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-sensor.c | 6 +++--- drivers/media/usb/stkwebcam/stk-webcam.c | 11 ++++++----- drivers/media/usb/stkwebcam/stk-webcam.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c index 13ad8fdf05bb..fbccbb2eed9f 100644 --- a/drivers/media/usb/stkwebcam/stk-sensor.c +++ b/drivers/media/usb/stkwebcam/stk-sensor.c @@ -228,7 +228,7 @@ static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) { int i = 0; - int tmpval = 0; + u8 tmpval = 0; if (stk_camera_write_reg(dev, STK_IIC_TX_INDEX, reg)) return 1; @@ -253,7 +253,7 @@ static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) { int i = 0; - int tmpval = 0; + u8 tmpval = 0; if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg)) return 1; @@ -274,7 +274,7 @@ static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval)) return 1; - *val = (u8) tmpval; + *val = tmpval; return 0; } diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index e2e7d0f7a43c..a212248bc2a3 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -144,7 +144,7 @@ int stk_camera_write_reg(struct stk_camera *dev, u16 index, u8 value) return 0; } -int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) +int stk_camera_read_reg(struct stk_camera *dev, u16 index, u8 *value) { struct usb_device *udev = dev->udev; unsigned char *buf; @@ -163,7 +163,7 @@ int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) sizeof(u8), 500); if (ret >= 0) - memcpy(value, buf, sizeof(u8)); + *value = *buf; kfree(buf); return ret; @@ -171,9 +171,10 @@ int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) static int stk_start_stream(struct stk_camera *dev) { - int value; + u8 value; int i, ret; - int value_116, value_117; + u8 value_116, value_117; + if (!is_present(dev)) return -ENODEV; @@ -213,7 +214,7 @@ static int stk_start_stream(struct stk_camera *dev) static int stk_stop_stream(struct stk_camera *dev) { - int value; + u8 value; int i; if (is_present(dev)) { stk_camera_read_reg(dev, 0x0100, &value); diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 9bbfa3d9bfdd..92bb48e3c74e 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -129,7 +129,7 @@ struct stk_camera { #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) int stk_camera_write_reg(struct stk_camera *, u16, u8); -int stk_camera_read_reg(struct stk_camera *, u16, int *); +int stk_camera_read_reg(struct stk_camera *, u16, u8 *); int stk_sensor_init(struct stk_camera *); int stk_sensor_configure(struct stk_camera *); -- cgit v1.2.3 From 8ccd22db927995313a9ab3526c1765c7c157f3e9 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 16 Nov 2016 11:00:56 -0200 Subject: [media] netup_unidvb: use module_pci_driver Use module_pci_driver() helper to simplify the code. Signed-off-by: Geliang Tang Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index b078ac2a682c..191bd8299dc3 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -1030,15 +1030,4 @@ static struct pci_driver netup_unidvb_pci_driver = { .resume = NULL, }; -static int __init netup_unidvb_init(void) -{ - return pci_register_driver(&netup_unidvb_pci_driver); -} - -static void __exit netup_unidvb_fini(void) -{ - pci_unregister_driver(&netup_unidvb_pci_driver); -} - -module_init(netup_unidvb_init); -module_exit(netup_unidvb_fini); +module_pci_driver(netup_unidvb_pci_driver); -- cgit v1.2.3 From 386701892b4821c4d127710fa35b1309c4355bbf Mon Sep 17 00:00:00 2001 From: Joerg Riechardt Date: Sat, 29 Aug 2015 12:02:57 -0300 Subject: [media] stv090x: use lookup tables for carrier/noise ratio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stv090x driver uses the lookup table for signal strength already, with this patch we use the lookup tables for carrier/noise ratio as well. This has the advantage, that values for DVB-S and DVB-S2 are now corresponding, while before they were way off. The values are now proportional to real carrier/noise ratio, while before they were corresponding to register values. So now applications are able to give the user real carrier/noise ratio. Because the output has to be within 0x0000...0xFFFF the three negative values for DVB-S2 are omitted. This is no significant loss, because reception is lost at 7.5 dB already (TT S2-1600, Cine S2), so the negative values are not really important, and also for DVB-S they don´t exist. Signed-off-by: Joerg Riechardt Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv090x.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index b586d2a49737..7ef469c0c866 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -3692,9 +3692,12 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) } val /= 16; last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; - div = stv090x_s2cn_tab[0].read - - stv090x_s2cn_tab[last].read; - *cnr = 0xFFFF - ((val * 0xFFFF) / div); + div = stv090x_s2cn_tab[last].real - + stv090x_s2cn_tab[3].real; + val = stv090x_table_lookup(stv090x_s2cn_tab, last, val); + if (val < 0) + val = 0; + *cnr = val * 0xFFFF / div; } break; @@ -3714,9 +3717,10 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) } val /= 16; last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; - div = stv090x_s1cn_tab[0].read - - stv090x_s1cn_tab[last].read; - *cnr = 0xFFFF - ((val * 0xFFFF) / div); + div = stv090x_s1cn_tab[last].real - + stv090x_s1cn_tab[0].real; + val = stv090x_table_lookup(stv090x_s1cn_tab, last, val); + *cnr = val * 0xFFFF / div; } break; default: -- cgit v1.2.3 From a19e160d108a80953e4404be39e03b9bc8417376 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 17 Sep 2015 18:19:33 -0300 Subject: [media] dvb: remove unused systime() function The systime function uses struct timespec, which we want to stop using in the kernel because it overflows in 2038. Fortunately, this use in dibx000_common is in a function that is never called, so we can just remove it. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dibx000_common.c | 10 ---------- drivers/media/dvb-frontends/dibx000_common.h | 2 -- 2 files changed, 12 deletions(-) diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c index 7db908ed87f6..bc28184c7fb0 100644 --- a/drivers/media/dvb-frontends/dibx000_common.c +++ b/drivers/media/dvb-frontends/dibx000_common.c @@ -502,16 +502,6 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) } EXPORT_SYMBOL(dibx000_exit_i2c_master); - -u32 systime(void) -{ - struct timespec t; - - t = current_kernel_time(); - return (t.tv_sec * 10000) + (t.tv_nsec / 100000); -} -EXPORT_SYMBOL(systime); - MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h index b538e0555c95..61f4152f24ee 100644 --- a/drivers/media/dvb-frontends/dibx000_common.h +++ b/drivers/media/dvb-frontends/dibx000_common.h @@ -47,8 +47,6 @@ extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed); -extern u32 systime(void); - #define BAND_LBAND 0x01 #define BAND_UHF 0x02 #define BAND_VHF 0x04 -- cgit v1.2.3 From fa6317eedd6341f2144ed1097706d8c34f18b6e4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 26 Jan 2016 12:10:01 -0200 Subject: [media] go7007: add MEDIA_CAMERA_SUPPORT dependency If MEDIA_SUBDRV_AUTOSELECT and VIDEO_GO7007 are both set, we automatically select VIDEO_OV7640, but that depends on MEDIA_CAMERA_SUPPORT, so we get a Kconfig warning if that is disabled: warning: (VIDEO_GO7007) selects VIDEO_OV7640 which has unmet direct dependencies (MEDIA_SUPPORT && I2C && VIDEO_V4L2 && MEDIA_CAMERA_SUPPORT) This adds another dependency so we don't accidentally select it when it is unavailable. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/go7007/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/go7007/Kconfig b/drivers/media/usb/go7007/Kconfig index 95a3af644a92..af1d02430931 100644 --- a/drivers/media/usb/go7007/Kconfig +++ b/drivers/media/usb/go7007/Kconfig @@ -11,7 +11,7 @@ config VIDEO_GO7007 select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT ---help--- This is a video4linux driver for the WIS GO7007 MPEG -- cgit v1.2.3 From 190b23b4eb997767afad186bd8c96badceabf39e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 26 Jan 2016 12:09:59 -0200 Subject: [media] em28xx: only use mt9v011 if camera support is enabled In randconfig builds that select VIDEO_EM28XX_V4L2 and MEDIA_SUBDRV_AUTOSELECT, but not MEDIA_CAMERA_SUPPORT, we get a Kconfig warning: warning: (VIDEO_EM28XX_V4L2) selects VIDEO_MT9V011 which has unmet direct dependencies (MEDIA_SUPPORT && I2C && VIDEO_V4L2 && MEDIA_CAMERA_SUPPORT) This avoids the warning by making that 'select' conditional on MEDIA_CAMERA_SUPPORT. Alternatively we could mark EM28XX as 'depends on MEDIA_CAMERA_SUPPORT', but it does not seem to have any real dependency on that itself. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index d917b0a2beb1..aa131cf9989b 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig @@ -11,7 +11,7 @@ config VIDEO_EM28XX_V4L2 select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT ---help--- This is a video4linux driver for Empia 28xx based TV cards. -- cgit v1.2.3 From 90866b3a8011703d87d9ea263ef29a194453a898 Mon Sep 17 00:00:00 2001 From: "Буди Романто, AreMa Inc" Date: Tue, 5 Apr 2016 13:14:10 -0300 Subject: [media] Raise adapter number limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current limit is too low for latest cards with 8+ tuners on a single slot. IMHO, the most appropriate minimum default is 16. Signed-off-by: Буди Романто, AreMa Inc Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/Kconfig | 4 ++-- drivers/media/dvb-core/dvbdev.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig index 8964f1d3cf57..eeef94a0c84e 100644 --- a/drivers/media/dvb-core/Kconfig +++ b/drivers/media/dvb-core/Kconfig @@ -5,7 +5,7 @@ config DVB_MAX_ADAPTERS int "maximum number of DVB/ATSC adapters" depends on DVB_CORE - default 8 + default 16 range 1 255 help Maximum number of DVB/ATSC adapters. Increasing this number @@ -13,7 +13,7 @@ config DVB_MAX_ADAPTERS if a much lower number of DVB/ATSC adapters is present. Only values in the range 4-32 are tested. - If you are unsure about this, use the default value 8 + If you are unsure about this, use the default value 16 config DVB_DYNAMIC_MINORS bool "Dynamic DVB minor allocation" diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 576bbd4445b5..8c0a7b51555e 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -34,7 +34,7 @@ #if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0 #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS #else - #define DVB_MAX_ADAPTERS 8 + #define DVB_MAX_ADAPTERS 16 #endif #define DVB_UNSET (-1) -- cgit v1.2.3 From fc641261e1227ed7d083d55c8b47f3e9cd173681 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Mon, 14 Mar 2016 19:24:25 -0300 Subject: [media] media: Update documentation for media_entity_notify Update documentation for media_entity_notify to clearly state the usage restrictions. This handler is intended for creating links between exiting entities and should not used to create and register entities. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/media/media-device.h b/include/media/media-device.h index ef93e21335df..a267f9ceee8f 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -39,8 +39,10 @@ struct device; * @notify_data: Input data to invoke the callback * @notify: Callback function pointer * - * Drivers may register a callback to take action when - * new entities get registered with the media device. + * Drivers may register a callback to take action when new entities get + * registered with the media device. This handler is intended for creating + * links between existing entities and should not create entities and register + * them. */ struct media_entity_notify { struct list_head list; -- cgit v1.2.3 From d26cec2268bcb5521b8b7a0edd44b8129bb978ec Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 14 Apr 2016 17:42:49 -0300 Subject: [media] mceusb: remove useless debug message Such debug message has a logic to track the IR status, but it doesn't provide much info. So, get rid of it. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index f813b77c595d..517d218a6179 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -153,12 +153,6 @@ #define MCE_COMMAND_IRDATA 0x80 #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ -/* general constants */ -#define SEND_FLAG_IN_PROGRESS 1 -#define SEND_FLAG_COMPLETE 2 -#define RECV_FLAG_IN_PROGRESS 3 -#define RECV_FLAG_COMPLETE 4 - #define MCEUSB_RX 1 #define MCEUSB_TX 2 @@ -422,7 +416,6 @@ struct mceusb_dev { struct rc_dev *rc; /* optional features we can enable */ - bool carrier_report_enabled; bool learning_enabled; /* core device bits */ @@ -455,7 +448,6 @@ struct mceusb_dev { } flags; /* transmit support */ - int send_flags; u32 carrier; unsigned char tx_mask; @@ -778,8 +770,6 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, } else if (urb_type == MCEUSB_RX) { /* standard request */ async_urb = ir->urb_in; - ir->send_flags = RECV_FLAG_IN_PROGRESS; - } else { dev_err(dev, "Error! Unknown urb type %d\n", urb_type); return; @@ -1060,7 +1050,6 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) static void mceusb_dev_recv(struct urb *urb) { struct mceusb_dev *ir; - int buf_len; if (!urb) return; @@ -1071,18 +1060,10 @@ static void mceusb_dev_recv(struct urb *urb) return; } - buf_len = urb->actual_length; - - if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { - ir->send_flags = SEND_FLAG_COMPLETE; - dev_dbg(ir->dev, "setup answer received %d bytes\n", - buf_len); - } - switch (urb->status) { /* success */ case 0: - mceusb_process_ir_data(ir, buf_len); + mceusb_process_ir_data(ir, urb->actual_length); break; case -ECONNRESET: -- cgit v1.2.3 From e1159cb35712bc708f444f167b6954a5afeebbdf Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 14 Apr 2016 17:42:50 -0300 Subject: [media] mceusb: remove pointless mce_flush_rx_buffer function This function just submits the urb much like mceusb_dev_resume; removing it simplifies mce_request_packet. Also add missing usb_kill_urb to mce_dev_probe. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 77 +++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 517d218a6179..9bf69179eee0 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -153,9 +153,6 @@ #define MCE_COMMAND_IRDATA 0x80 #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ -#define MCEUSB_RX 1 -#define MCEUSB_TX 2 - #define VENDOR_PHILIPS 0x0471 #define VENDOR_SMK 0x0609 #define VENDOR_TATUNG 0x1460 @@ -730,50 +727,40 @@ static void mce_async_callback(struct urb *urb) /* request incoming or send outgoing usb packet - used to initialize remote */ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, - int size, int urb_type) + int size) { int res, pipe; struct urb *async_urb; struct device *dev = ir->dev; unsigned char *async_buf; - if (urb_type == MCEUSB_TX) { - async_urb = usb_alloc_urb(0, GFP_KERNEL); - if (unlikely(!async_urb)) { - dev_err(dev, "Error, couldn't allocate urb!\n"); - return; - } - - async_buf = kzalloc(size, GFP_KERNEL); - if (!async_buf) { - dev_err(dev, "Error, couldn't allocate buf!\n"); - usb_free_urb(async_urb); - return; - } + async_urb = usb_alloc_urb(0, GFP_KERNEL); + if (unlikely(!async_urb)) { + dev_err(dev, "Error, couldn't allocate urb!\n"); + return; + } - /* outbound data */ - if (usb_endpoint_xfer_int(ir->usb_ep_out)) { - pipe = usb_sndintpipe(ir->usbdev, - ir->usb_ep_out->bEndpointAddress); - usb_fill_int_urb(async_urb, ir->usbdev, pipe, async_buf, - size, mce_async_callback, ir, - ir->usb_ep_out->bInterval); - } else { - pipe = usb_sndbulkpipe(ir->usbdev, - ir->usb_ep_out->bEndpointAddress); - usb_fill_bulk_urb(async_urb, ir->usbdev, pipe, - async_buf, size, mce_async_callback, - ir); - } - memcpy(async_buf, data, size); + async_buf = kmalloc(size, GFP_KERNEL); + if (!async_buf) { + usb_free_urb(async_urb); + return; + } - } else if (urb_type == MCEUSB_RX) { - /* standard request */ - async_urb = ir->urb_in; + /* outbound data */ + if (usb_endpoint_xfer_int(ir->usb_ep_out)) { + pipe = usb_sndintpipe(ir->usbdev, + ir->usb_ep_out->bEndpointAddress); + usb_fill_int_urb(async_urb, ir->usbdev, pipe, async_buf, + size, mce_async_callback, ir, + ir->usb_ep_out->bInterval); } else { - dev_err(dev, "Error! Unknown urb type %d\n", urb_type); - return; + pipe = usb_sndbulkpipe(ir->usbdev, + ir->usb_ep_out->bEndpointAddress); + usb_fill_bulk_urb(async_urb, ir->usbdev, pipe, + async_buf, size, mce_async_callback, + ir); } + memcpy(async_buf, data, size); dev_dbg(dev, "receive request called (size=%#x)", size); @@ -794,19 +781,14 @@ static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) if (ir->need_reset) { ir->need_reset = false; - mce_request_packet(ir, DEVICE_RESUME, rsize, MCEUSB_TX); + mce_request_packet(ir, DEVICE_RESUME, rsize); msleep(10); } - mce_request_packet(ir, data, size, MCEUSB_TX); + mce_request_packet(ir, data, size); msleep(10); } -static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size) -{ - mce_request_packet(ir, NULL, size, MCEUSB_RX); -} - /* Send data out the IR blaster port(s) */ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count) { @@ -1264,7 +1246,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *ep_in = NULL; struct usb_endpoint_descriptor *ep_out = NULL; struct mceusb_dev *ir = NULL; - int pipe, maxp, i; + int pipe, maxp, i, res; char buf[63], name[128] = ""; enum mceusb_model_type model = id->driver_info; bool is_gen3; @@ -1367,7 +1349,9 @@ static int mceusb_dev_probe(struct usb_interface *intf, /* flush buffers on the device */ dev_dbg(&intf->dev, "Flushing receive buffers\n"); - mce_flush_rx_buffer(ir, maxp); + res = usb_submit_urb(ir->urb_in, GFP_KERNEL); + if (res) + dev_err(&intf->dev, "failed to flush buffers: %d\n", res); /* figure out which firmware/emulator version this hardware has */ mceusb_get_emulator_version(ir); @@ -1402,6 +1386,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, /* Error-handling path */ rc_dev_fail: usb_put_dev(ir->usbdev); + usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); urb_in_alloc_fail: usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); -- cgit v1.2.3 From f1c002f262fb8f1a8064341a185ca9413a4b96d7 Mon Sep 17 00:00:00 2001 From: Saatvik Arya Date: Wed, 3 Feb 2016 00:26:42 -0200 Subject: [media] staging: media: davinci_vpfe: dm365_resizer: Fix some spelling mistakes Fix spelling mistakes which referred to OUTPUT as OUPUT. Signed-off-by: Saatvik Arya Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 22 +++++++++++----------- drivers/staging/media/davinci_vpfe/dm365_resizer.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 128662623ea8..544f13206b83 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -490,7 +490,7 @@ resizer_configure_in_continious_mode(struct vpfe_resizer_device *resizer) int line_len; int ret; - if (resizer->resizer_a.output != RESIZER_OUPUT_MEMORY) { + if (resizer->resizer_a.output != RESIZER_OUTPUT_MEMORY) { dev_err(dev, "enable resizer - Resizer-A\n"); return -EINVAL; } @@ -502,7 +502,7 @@ resizer_configure_in_continious_mode(struct vpfe_resizer_device *resizer) param->rsz_en[RSZ_B] = DISABLE; param->oper_mode = RESIZER_MODE_CONTINIOUS; - if (resizer->resizer_b.output == RESIZER_OUPUT_MEMORY) { + if (resizer->resizer_b.output == RESIZER_OUTPUT_MEMORY) { struct v4l2_mbus_framefmt *outformat2; param->rsz_en[RSZ_B] = ENABLE; @@ -1043,13 +1043,13 @@ static void resizer_ss_isr(struct vpfe_resizer_device *resizer) if (ipipeif_sink != IPIPEIF_INPUT_MEMORY) return; - if (resizer->resizer_a.output == RESIZER_OUPUT_MEMORY) { + if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) { val = vpss_dma_complete_interrupt(); if (val != 0 && val != 2) return; } - if (resizer->resizer_a.output == RESIZER_OUPUT_MEMORY) { + if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) { spin_lock(&video_out->dma_queue_lock); vpfe_video_process_buffer_complete(video_out); video_out->state = VPFE_VIDEO_BUFFER_NOT_QUEUED; @@ -1059,7 +1059,7 @@ static void resizer_ss_isr(struct vpfe_resizer_device *resizer) /* If resizer B is enabled */ if (pipe->output_num > 1 && resizer->resizer_b.output == - RESIZER_OUPUT_MEMORY) { + RESIZER_OUTPUT_MEMORY) { spin_lock(&video_out->dma_queue_lock); vpfe_video_process_buffer_complete(video_out2); video_out2->state = VPFE_VIDEO_BUFFER_NOT_QUEUED; @@ -1069,7 +1069,7 @@ static void resizer_ss_isr(struct vpfe_resizer_device *resizer) /* start HW if buffers are queued */ if (vpfe_video_is_pipe_ready(pipe) && - resizer->resizer_a.output == RESIZER_OUPUT_MEMORY) { + resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) { resizer_enable(resizer, 1); vpfe_ipipe_enable(vpfe_dev, 1); vpfe_ipipeif_enable(vpfe_dev); @@ -1237,8 +1237,8 @@ static int resizer_do_hw_setup(struct vpfe_resizer_device *resizer) struct resizer_params *param = &resizer->config; int ret = 0; - if (resizer->resizer_a.output == RESIZER_OUPUT_MEMORY || - resizer->resizer_b.output == RESIZER_OUPUT_MEMORY) { + if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY || + resizer->resizer_b.output == RESIZER_OUTPUT_MEMORY) { if (ipipeif_sink == IPIPEIF_INPUT_MEMORY && ipipeif_source == IPIPEIF_OUTPUT_RESIZER) ret = resizer_configure_in_single_shot_mode(resizer); @@ -1263,7 +1263,7 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable) if (&resizer->crop_resizer.subdev != sd) return 0; - if (resizer->resizer_a.output != RESIZER_OUPUT_MEMORY) + if (resizer->resizer_a.output != RESIZER_OUTPUT_MEMORY) return 0; switch (enable) { @@ -1724,7 +1724,7 @@ static int resizer_link_setup(struct media_entity *entity, } if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE) return -EBUSY; - resizer->resizer_a.output = RESIZER_OUPUT_MEMORY; + resizer->resizer_a.output = RESIZER_OUTPUT_MEMORY; break; default: @@ -1749,7 +1749,7 @@ static int resizer_link_setup(struct media_entity *entity, } if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE) return -EBUSY; - resizer->resizer_b.output = RESIZER_OUPUT_MEMORY; + resizer->resizer_b.output = RESIZER_OUTPUT_MEMORY; break; default: diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.h b/drivers/staging/media/davinci_vpfe/dm365_resizer.h index 93b0f44030aa..00e64b0d0295 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.h +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.h @@ -210,7 +210,7 @@ enum resizer_input_entity { enum resizer_output_entity { RESIZER_OUTPUT_NONE = 0, - RESIZER_OUPUT_MEMORY = 1, + RESIZER_OUTPUT_MEMORY = 1, }; struct dm365_resizer_device { -- cgit v1.2.3 From 7809c97622a257abf1c3ee3cd18141035e498af8 Mon Sep 17 00:00:00 2001 From: Manuel Rodriguez Date: Tue, 8 Mar 2016 04:16:06 -0300 Subject: [media] staging: media: davinci_vpfe: Fix spelling error on a comment Fix spelling error on a comment, change 'wether' to 'whether' Signed-off-by: Manuel Rodriguez Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 8be9f854510f..117b6be2f3c4 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -198,7 +198,7 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video) return 0; } -/* checks wether pipeline is ready for enabling */ +/* checks whether pipeline is ready for enabling */ int vpfe_video_is_pipe_ready(struct vpfe_pipeline *pipe) { int i; -- cgit v1.2.3 From 5f87406663d48ed54fe1767f35734e11b971da12 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 11 May 2016 10:29:44 -0300 Subject: [media] staging: media: davinci_vfpe: allow modular build It has never been possible to actually build this driver as a loadable module, only built-in because the Makefile attempts to build each file into its own module and fails: ERROR: "mbus_to_pix" [drivers/staging/media/davinci_vpfe/vpfe_video.ko] undefined! ERROR: "vpfe_resizer_register_entities" [drivers/staging/media/davinci_vpfe/vpfe_mc_capture.ko] undefined! ERROR: "rsz_enable" [drivers/staging/media/davinci_vpfe/dm365_resizer.ko] undefined! ERROR: "config_ipipe_hw" [drivers/staging/media/davinci_vpfe/dm365_ipipe.ko] undefined! ERROR: "ipipe_set_lutdpc_regs" [drivers/staging/media/davinci_vpfe/dm365_ipipe.ko] undefined! It took a long time to catch this bug with randconfig builds because at least 14 other Kconfig symbols have to be enabled in order to configure this one, and it was clearly only ever tested as built-in with mainline kernels, if at all. The solution is really easy: this patch changes the Makefile to link all files into one module. As discussed previously, the driver has never before used successfully as a loadable module, but there is no reason to prevent that configuration. Link: http://lkml.iu.edu/hypermail/linux/kernel/1512.1/02383.html Signed-off-by: Arnd Bergmann Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/davinci_vpfe/Makefile b/drivers/staging/media/davinci_vpfe/Makefile index c64515c644cd..3019c9ecd548 100644 --- a/drivers/staging/media/davinci_vpfe/Makefile +++ b/drivers/staging/media/davinci_vpfe/Makefile @@ -1,3 +1,5 @@ -obj-$(CONFIG_VIDEO_DM365_VPFE) += \ +obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci-vfpe.o + +davinci-vfpe-objs := \ dm365_isif.o dm365_ipipe_hw.o dm365_ipipe.o \ dm365_resizer.o dm365_ipipeif.o vpfe_mc_capture.o vpfe_video.o -- cgit v1.2.3 From a3283fb2165fdfd71a894332284ed59239a27872 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Jun 2016 12:47:56 -0300 Subject: [media] staging: media: davinci_vpfe: fix W=1 build warnings When building with "make W=1", we get multiple harmless build warnings for the vpfe driver: drivers/staging/media/davinci_vpfe/dm365_resizer.c:241:1: error: 'static' is not at beginning of declaration [-Werror=old-style-declaration] drivers/staging/media/davinci_vpfe/dm365_resizer.c: In function 'resizer_set_defualt_configuration': drivers/staging/media/davinci_vpfe/dm365_resizer.c:831:16: error: initialized field overwritten [-Werror=override-init] drivers/staging/media/davinci_vpfe/dm365_resizer.c:831:16: note: (near initialization for 'rsz_default_config.rsz_rsc_param[0].h_typ_c') drivers/staging/media/davinci_vpfe/dm365_resizer.c:849:16: error: initialized field overwritten [-Werror=override-init] drivers/staging/media/davinci_vpfe/dm365_resizer.c:849:16: note: (near initialization for 'rsz_default_config.rsz_rsc_param[1].h_typ_c') All of them are trivial to fix without changing the behavior of the driver, as "static const" is interpreted the same as "const static", and VPFE_RSZ_INTP_CUBIC is defined as zero, so the initializations are not really needed. Signed-off-by: Arnd Bergmann Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 544f13206b83..5fbc2d447ff2 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -237,9 +237,8 @@ resizer_calculate_resize_ratios(struct vpfe_resizer_device *resizer, int index) ((informat->width) * 256) / (outformat->width); } -void -static resizer_enable_422_420_conversion(struct resizer_params *param, - int index, bool en) +static void resizer_enable_422_420_conversion(struct resizer_params *param, + int index, bool en) { param->rsz_rsc_param[index].cen = en; param->rsz_rsc_param[index].yen = en; @@ -825,7 +824,7 @@ resizer_set_defualt_configuration(struct vpfe_resizer_device *resizer) .o_hsz = WIDTH_O - 1, .v_dif = 256, .v_typ_y = VPFE_RSZ_INTP_CUBIC, - .h_typ_c = VPFE_RSZ_INTP_CUBIC, + .v_typ_c = VPFE_RSZ_INTP_CUBIC, .h_dif = 256, .h_typ_y = VPFE_RSZ_INTP_CUBIC, .h_typ_c = VPFE_RSZ_INTP_CUBIC, @@ -843,7 +842,7 @@ resizer_set_defualt_configuration(struct vpfe_resizer_device *resizer) .o_hsz = WIDTH_O - 1, .v_dif = 256, .v_typ_y = VPFE_RSZ_INTP_CUBIC, - .h_typ_c = VPFE_RSZ_INTP_CUBIC, + .v_typ_c = VPFE_RSZ_INTP_CUBIC, .h_dif = 256, .h_typ_y = VPFE_RSZ_INTP_CUBIC, .h_typ_c = VPFE_RSZ_INTP_CUBIC, -- cgit v1.2.3 From eb02cadc5ca0d9753510cded8b9afc57c37be4e0 Mon Sep 17 00:00:00 2001 From: Leo Sperling Date: Sun, 23 Oct 2016 10:02:23 -0200 Subject: [media] staging: media: davinci_vpfe: Fix indentation issue in vpfe_video.c This is a patch to the vpfe_video.c file that fixes an indentation warning reported by checkpatch.pl Signed-off-by: Leo Sperling Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 117b6be2f3c4..8fd3f7cd40d6 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1143,8 +1143,8 @@ static int vpfe_buffer_prepare(struct vb2_buffer *vb) /* Initialize buffer */ vb2_set_plane_payload(vb, 0, video->fmt.fmt.pix.sizeimage); if (vb2_plane_vaddr(vb, 0) && - vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) - return -EINVAL; + vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) + return -EINVAL; addr = vb2_dma_contig_plane_dma_addr(vb, 0); /* Make sure user addresses are aligned to 32 bytes */ -- cgit v1.2.3 From c4a407b91f4b644145492e28723f9f880efb1da0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 18 Nov 2016 09:30:24 -0200 Subject: [media] staging: media: davinci_vpfe: unlock on error in vpfe_reqbufs() We should unlock before returning this error code in vpfe_reqbufs(). Fixes: 622897da67b3 ("[media] davinci: vpfe: add v4l2 video driver support") Signed-off-by: Dan Carpenter Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 8fd3f7cd40d6..c27d7e9a1bdb 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1362,7 +1362,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, ret = vb2_queue_init(q); if (ret) { v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n"); - return ret; + goto unlock_out; } fh->io_allowed = 1; -- cgit v1.2.3 From 1a9164a98eaf2eb4c82683a258dc0ec71dcc7813 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 08:35:26 -0300 Subject: [media] extended-controls.rst: fix typo Fix a typo on a word inside it. Signed-off-by: Andrea Gelmini Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/extended-controls.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 40071ea5d90e..abb105724c05 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -2846,7 +2846,7 @@ JPEG Control IDs input image is sampled, in respect to maximum sample rate in each spatial dimension. See :ref:`itu-t81`, clause A.1.1. for more details. The ``V4L2_CID_JPEG_CHROMA_SUBSAMPLING`` control determines - how Cb and Cr components are downsampled after coverting an input + how Cb and Cr components are downsampled after converting an input image from RGB to Y'CbCr color space. .. tabularcolumns:: |p{7.0cm}|p{10.5cm}| -- cgit v1.2.3 From 59eba2d1ec0272ea9cb472b5805e179242df226d Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Mon, 17 Oct 2016 17:25:59 -0200 Subject: [media] saa7146: Fix for while releasing video buffers Fix this bug: "[BUG] process stuck when closing saa7146 [dvb_ttpci]" Release queued DMA buffers when ending streaming, so that videobuf_waiton() doesn't block forever. As reported, this fixes avoids occasional lockup of process reading from video device, which manifests in such log: INFO: task ffmpeg:9864 blocked for more than 120 seconds. Tainted: P O 4.6.7 #3 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. ffmpeg D ffff880177cc7b00 0 9864 1 0x00000000 ffff880177cc7b00 0000000000000202 0000000000000202 ffffffff8180b4c0 ffff88019d79e4c0 ffffffff81064050 ffff880177cc7ae0 ffff880177cc8000 ffff880177cc7b18 ffff8801fd41d648 ffff8802307acca0 ffff8802307acc70 Call Trace: [] ? preempt_count_add+0x89/0xab [] schedule+0x86/0x9e [] ? schedule+0x86/0x9e [] videobuf_waiton+0x131/0x15e [videobuf_core] [] ? wait_woken+0x6d/0x6d [] saa7146_dma_free+0x39/0x5b [saa7146_vv] [] buffer_release+0x2a/0x3e [saa7146_vv] [] videobuf_vm_close+0xd8/0x103 [videobuf_dma_sg] [] remove_vma+0x25/0x4d [] exit_mmap+0xce/0xf7 [] mmput+0x4e/0xe2 [] do_exit+0x372/0x920 [] do_group_exit+0x3c/0x98 [] get_signal+0x4e8/0x56e [] ? task_dead_fair+0xd/0xf [] do_signal+0x23/0x521 [] ? _raw_spin_unlock_irqrestore+0x13/0x25 [] ? hrtimer_try_to_cancel+0xd7/0x104 [] ? ktime_get+0x4c/0xa1 [] ? update_rmtp+0x46/0x5b [] ? hrtimer_nanosleep+0xe4/0x10e [] ? hrtimer_init+0xeb/0xeb [] exit_to_usermode_loop+0x4f/0x93 [] syscall_return_slowpath+0x3b/0x46 [] entry_SYSCALL_64_fastpath+0x8d/0x8f Reported-by: Philipp Matthias Hahn Tested-by: Philipp Matthias Hahn Signed-off-by: Andrey Utkin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146/saa7146_video.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c index ea2f3bf7368b..e034bcfcf757 100644 --- a/drivers/media/common/saa7146/saa7146_video.c +++ b/drivers/media/common/saa7146/saa7146_video.c @@ -390,6 +390,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; + struct saa7146_dmaqueue *q = &vv->video_dmaq; struct saa7146_format *fmt = NULL; unsigned long flags; unsigned int resource; @@ -428,6 +429,9 @@ static int video_end(struct saa7146_fh *fh, struct file *file) /* shut down all used video dma transfers */ saa7146_write(dev, MC1, dmas); + if (q->curr) + saa7146_buffer_finish(dev, q, VIDEOBUF_DONE); + spin_unlock_irqrestore(&dev->slock, flags); vv->video_fh = NULL; -- cgit v1.2.3 From b9a4b13c770a84599dc706b78cd70ad5761fc30b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 27 Jun 2016 10:46:16 -0300 Subject: [media] v4l: Add 16-bit raw bayer pixel formats The formats added by this patch are: V4L2_PIX_FMT_SBGGR16 V4L2_PIX_FMT_SGBRG16 V4L2_PIX_FMT_SGRBG16 V4L2_PIX_FMT_SRGGB16 already existed before the patch. Rework the documentation to match that of the other sample depths. Also align the description of V4L2_PIX_FMT_SRGGB16 to match with other similar formats. Signed-off-by: Sakari Ailus Acked-by: Lad, Prabhakar Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-rgb.rst | 2 +- Documentation/media/uapi/v4l/pixfmt-sbggr16.rst | 62 ---------------------- Documentation/media/uapi/v4l/pixfmt-srggb16.rst | 69 +++++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 5 +- include/uapi/linux/videodev2.h | 3 ++ 5 files changed, 77 insertions(+), 64 deletions(-) delete mode 100644 Documentation/media/uapi/v4l/pixfmt-sbggr16.rst create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb16.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index 9cc980882e80..b0f35136021e 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -12,9 +12,9 @@ RGB Formats pixfmt-packed-rgb pixfmt-srggb8 - pixfmt-sbggr16 pixfmt-srggb10 pixfmt-srggb10p pixfmt-srggb10alaw8 pixfmt-srggb10dpcm8 pixfmt-srggb12 + pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-sbggr16.rst b/Documentation/media/uapi/v4l/pixfmt-sbggr16.rst deleted file mode 100644 index 6f7f327db85c..000000000000 --- a/Documentation/media/uapi/v4l/pixfmt-sbggr16.rst +++ /dev/null @@ -1,62 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _V4L2-PIX-FMT-SBGGR16: - -***************************** -V4L2_PIX_FMT_SBGGR16 ('BYR2') -***************************** - -Bayer RGB format - - -Description -=========== - -This format is similar to -:ref:`V4L2_PIX_FMT_SBGGR8 `, except each pixel -has a depth of 16 bits. The least significant byte is stored at lower -memory addresses (little-endian). - -**Byte Order.** -Each cell is one byte. - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - - * - start + 0: - - B\ :sub:`00low` - - B\ :sub:`00high` - - G\ :sub:`01low` - - G\ :sub:`01high` - - B\ :sub:`02low` - - B\ :sub:`02high` - - G\ :sub:`03low` - - G\ :sub:`03high` - * - start + 8: - - G\ :sub:`10low` - - G\ :sub:`10high` - - R\ :sub:`11low` - - R\ :sub:`11high` - - G\ :sub:`12low` - - G\ :sub:`12high` - - R\ :sub:`13low` - - R\ :sub:`13high` - * - start + 16: - - B\ :sub:`20low` - - B\ :sub:`20high` - - G\ :sub:`21low` - - G\ :sub:`21high` - - B\ :sub:`22low` - - B\ :sub:`22high` - - G\ :sub:`23low` - - G\ :sub:`23high` - * - start + 24: - - G\ :sub:`30low` - - G\ :sub:`30high` - - R\ :sub:`31low` - - R\ :sub:`31high` - - G\ :sub:`32low` - - G\ :sub:`32high` - - R\ :sub:`33low` - - R\ :sub:`33high` diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb16.rst b/Documentation/media/uapi/v4l/pixfmt-srggb16.rst new file mode 100644 index 000000000000..06facc9cd539 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb16.rst @@ -0,0 +1,69 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB16: +.. _v4l2-pix-fmt-sbggr16: +.. _v4l2-pix-fmt-sgbrg16: +.. _v4l2-pix-fmt-sgrbg16: + + +*************************************************************************************************************************** +V4L2_PIX_FMT_SRGGB16 ('RG16'), V4L2_PIX_FMT_SGRBG16 ('GR16'), V4L2_PIX_FMT_SGBRG16 ('GB16'), V4L2_PIX_FMT_SBGGR16 ('BYR2'), +*************************************************************************************************************************** + + +16-bit Bayer formats + + +Description +=========== + +These four pixel formats are raw sRGB / Bayer formats with 16 bits per +sample. Each sample is stored in a 16-bit word. Each n-pixel row contains +n/2 green samples and n/2 blue or red samples, with alternating red and blue +rows. Bytes are stored in memory in little endian order. They are +conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is +an example of one of these formats: + +**Byte Order.** +Each cell is one byte. + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + * - start + 0: + - B\ :sub:`00low` + - B\ :sub:`00high` + - G\ :sub:`01low` + - G\ :sub:`01high` + - B\ :sub:`02low` + - B\ :sub:`02high` + - G\ :sub:`03low` + - G\ :sub:`03high` + * - start + 8: + - G\ :sub:`10low` + - G\ :sub:`10high` + - R\ :sub:`11low` + - R\ :sub:`11high` + - G\ :sub:`12low` + - G\ :sub:`12high` + - R\ :sub:`13low` + - R\ :sub:`13high` + * - start + 16: + - B\ :sub:`20low` + - B\ :sub:`20high` + - G\ :sub:`21low` + - G\ :sub:`21high` + - B\ :sub:`22low` + - B\ :sub:`22high` + - G\ :sub:`23low` + - G\ :sub:`23high` + * - start + 24: + - G\ :sub:`30low` + - G\ :sub:`30high` + - R\ :sub:`31low` + - R\ :sub:`31high` + - G\ :sub:`32low` + - G\ :sub:`32high` + - R\ :sub:`33low` + - R\ :sub:`33high` diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 181381d1dc77..61d2d65318c5 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1191,7 +1191,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; - case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break; + case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break; case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index d3f613e2c54a..46e8a2e369f9 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -605,6 +605,9 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16 RGRG.. GBGB.. */ /* HSV formats */ #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') -- cgit v1.2.3 From 5b382290ffe1561b6eba7b0e8d4b7abbf63f0c1a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 15 Nov 2016 14:44:01 -0200 Subject: [media] v4l: Add description of the Y8I, Y12I and Z16 formats The formats have been added without a description, fix that. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 61d2d65318c5..0c3f238a2e76 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1128,6 +1128,9 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; + case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; -- cgit v1.2.3 From 5bbced125ac50f181a2a88728c540b97b4c3af7a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 15 Nov 2016 19:49:43 -0200 Subject: [media] doc-rst: Specify raw bayer format variant used in the examples The documentation simply mentioned that one of the four pixel orders was used in the example. Now specify the exact pixelformat instead. Signed-off-by: Sakari Ailus Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-srggb10p.rst | 2 +- Documentation/media/uapi/v4l/pixfmt-srggb12.rst | 2 +- Documentation/media/uapi/v4l/pixfmt-srggb16.rst | 2 +- Documentation/media/uapi/v4l/pixfmt-srggb8.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst index 9a41c8d811d0..b6d426c70ccd 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst @@ -28,7 +28,7 @@ bits of each pixel, in the same order. Each n-pixel row contains n/2 green samples and n/2 blue or red samples, with alternating green-red and green-blue rows. They are conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example -of one of these formats: +of a small V4L2_PIX_FMT_SBGGR10P image: **Byte Order.** Each cell is one byte. diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12.rst index a50ee143cb08..15041e568a0a 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb12.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb12.rst @@ -26,7 +26,7 @@ high bits filled with zeros. Each n-pixel row contains n/2 green samples and n/2 blue or red samples, with alternating red and blue rows. Bytes are stored in memory in little endian order. They are conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example -of one of these formats: +of a small V4L2_PIX_FMT_SBGGR12 image: **Byte Order.** Each cell is one byte, the 4 most significant bits in the high bytes are diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb16.rst b/Documentation/media/uapi/v4l/pixfmt-srggb16.rst index 06facc9cd539..d407b2b2050f 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb16.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb16.rst @@ -22,7 +22,7 @@ sample. Each sample is stored in a 16-bit word. Each n-pixel row contains n/2 green samples and n/2 blue or red samples, with alternating red and blue rows. Bytes are stored in memory in little endian order. They are conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is -an example of one of these formats: +an example of a small V4L2_PIX_FMT_SBGGR16 image: **Byte Order.** Each cell is one byte. diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb8.rst b/Documentation/media/uapi/v4l/pixfmt-srggb8.rst index a3987d2e97fd..5ac25a634d30 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb8.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb8.rst @@ -20,7 +20,7 @@ These four pixel formats are raw sRGB / Bayer formats with 8 bits per sample. Each sample is stored in a byte. Each n-pixel row contains n/2 green samples and n/2 blue or red samples, with alternating red and blue rows. They are conventionally described as GRGR... BGBG..., -RGRG... GBGB..., etc. Below is an example of one of these formats: +RGRG... GBGB..., etc. Below is an example of a small V4L2_PIX_FMT_SBGGR8 image: **Byte Order.** Each cell is one byte. -- cgit v1.2.3 From eb165a20dfbe8b82e82b671e9941c4ad9f34388d Mon Sep 17 00:00:00 2001 From: Edgar Thier Date: Tue, 15 Nov 2016 03:33:10 -0200 Subject: [media] uvcvideo: Add bayer 16-bit format patterns Those formats are implemented by The DFK 23UP1300, DFK 23UX249 and DFK 23UX250 USB 3.0 industrial cameras from The Imaging Source. Signed-off-by: Edgar Thier Acked-by: Sakari Ailus Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 20 ++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 12 ++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 11744f92097b..04bf35063c4c 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -168,6 +168,26 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_RW10, .fcc = V4L2_PIX_FMT_SRGGB10P, }, + { + .name = "Bayer 16-bit (SBGGR16)", + .guid = UVC_GUID_FORMAT_BG16, + .fcc = V4L2_PIX_FMT_SBGGR16, + }, + { + .name = "Bayer 16-bit (SGBRG16)", + .guid = UVC_GUID_FORMAT_GB16, + .fcc = V4L2_PIX_FMT_SGBRG16, + }, + { + .name = "Bayer 16-bit (SRGGB16)", + .guid = UVC_GUID_FORMAT_RG16, + .fcc = V4L2_PIX_FMT_SRGGB16, + }, + { + .name = "Bayer 16-bit (SGRBG16)", + .guid = UVC_GUID_FORMAT_GR16, + .fcc = V4L2_PIX_FMT_SGRBG16, + }, }; /* ------------------------------------------------------------------------ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 7e4d3eea371b..3d6cc62f3cd2 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -106,6 +106,18 @@ #define UVC_GUID_FORMAT_RGGB \ { 'R', 'G', 'G', 'B', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_BG16 \ + { 'B', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_GB16 \ + { 'G', 'B', '1', '6', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_RG16 \ + { 'R', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_GR16 \ + { 'G', 'R', '1', '6', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_RGBP \ { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -- cgit v1.2.3 From 4cc5bed1caeb6d40f2f41c4c5eb83368691fbffb Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 19 Aug 2016 05:50:05 -0300 Subject: [media] uvcvideo: Use memdup_user() rather than duplicating its implementation Reuse existing functionality from memdup_user() instead of keeping duplicate source code. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_v4l2.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 05eed4be25df..a7e12fd20adc 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -70,14 +70,9 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, } size = xmap->menu_count * sizeof(*map->menu_info); - map->menu_info = kmalloc(size, GFP_KERNEL); - if (map->menu_info == NULL) { - ret = -ENOMEM; - goto done; - } - - if (copy_from_user(map->menu_info, xmap->menu_info, size)) { - ret = -EFAULT; + map->menu_info = memdup_user(xmap->menu_info, size); + if (IS_ERR(map->menu_info)) { + ret = PTR_ERR(map->menu_info); goto done; } -- cgit v1.2.3 From efb9ab67255fc2333293827f8c45d2f51647faf9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 19 Nov 2016 12:56:58 -0200 Subject: [media] dvb_net: prepare to split a very complex function The dvb_net code has a really complex function, meant to handle DVB network packages: it is long, has several loops and ifs inside, and even cause warnings with gcc5. Prepare it to be split into smaller functions by storing all arguments and internal vars inside a struct. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_net.c | 465 +++++++++++++++++++++------------------ 1 file changed, 245 insertions(+), 220 deletions(-) diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index b9a46d5a1bb5..6fef0fc61cd2 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -311,323 +311,348 @@ static inline void reset_ule( struct dvb_net_priv *p ) * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of * TS cells of a single PID. */ -static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - unsigned long skipped = 0L; - const u8 *ts, *ts_end, *from_where = NULL; - u8 ts_remain = 0, how_much = 0, new_ts = 1; - struct ethhdr *ethh = NULL; - bool error = false; +struct dvb_net_ule_handle { + struct net_device *dev; + struct dvb_net_priv *priv; + struct ethhdr *ethh; + const u8 *buf; + size_t buf_len; + unsigned long skipped; + const u8 *ts, *ts_end, *from_where; + u8 ts_remain, how_much, new_ts; + bool error; #ifdef ULE_DEBUG - /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ + /* + * The code inside ULE_DEBUG keeps a history of the + * last 100 TS cells processed. + */ static unsigned char ule_hist[100*TS_SZ]; static unsigned char *ule_where = ule_hist, ule_dump; #endif +}; + +static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) +{ + struct dvb_net_ule_handle h = { + .dev = dev, + .buf = buf, + .buf_len = buf_len, + .skipped = 0L, + .ts = NULL, + .ts_end = NULL, + .from_where = NULL, + .ts_remain = 0, + .how_much = 0, + .new_ts = 1, + .ethh = NULL, + .error = false, +#ifdef ULE_DEBUG + .ule_where = ule_hist, +#endif + }; /* For all TS cells in current buffer. * Appearently, we are called for every single TS cell. */ - for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) { - - if (new_ts) { + for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len; h.ts < h.ts_end; /* no incr. */ ) { + if (h.new_ts) { /* We are about to process a new TS cell. */ #ifdef ULE_DEBUG - if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist; - memcpy( ule_where, ts, TS_SZ ); - if (ule_dump) { - hexdump( ule_where, TS_SZ ); - ule_dump = 0; + if (h.ule_where >= &h.ule_hist[100*TS_SZ]) h.ule_where = h.ule_hist; + memcpy( h.ule_where, h.ts, TS_SZ ); + if (h.ule_dump) { + hexdump( h.ule_where, TS_SZ ); + h.ule_dump = 0; } - ule_where += TS_SZ; + h.ule_where += TS_SZ; #endif - /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */ - if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) { + /* Check TS h.error conditions: sync_byte, transport_error_indicator, scrambling_control . */ + if ((h.ts[0] != TS_SYNC) || (h.ts[1] & TS_TEI) || ((h.ts[3] & TS_SC) != 0)) { pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", - priv->ts_count, ts[0], - (ts[1] & TS_TEI) >> 7, - (ts[3] & TS_SC) >> 6); + h.priv->ts_count, h.ts[0], + (h.ts[1] & TS_TEI) >> 7, + (h.ts[3] & TS_SC) >> 6); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); + if (h.priv->ule_skb) { + dev_kfree_skb( h.priv->ule_skb ); /* Prepare for next SNDU. */ - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; + h.dev->stats.rx_errors++; + h.dev->stats.rx_frame_errors++; } - reset_ule(priv); - priv->need_pusi = 1; + reset_ule(h.priv); + h.priv->need_pusi = 1; /* Continue with next TS cell. */ - ts += TS_SZ; - priv->ts_count++; + h.ts += TS_SZ; + h.priv->ts_count++; continue; } - ts_remain = 184; - from_where = ts + 4; + h.ts_remain = 184; + h.from_where = h.ts + 4; } /* Synchronize on PUSI, if required. */ - if (priv->need_pusi) { - if (ts[1] & TS_PUSI) { + if (h.priv->need_pusi) { + if (h.ts[1] & TS_PUSI) { /* Find beginning of first ULE SNDU in current TS cell. */ /* Synchronize continuity counter. */ - priv->tscc = ts[3] & 0x0F; + h.priv->tscc = h.ts[3] & 0x0F; /* There is a pointer field here. */ - if (ts[4] > ts_remain) { + if (h.ts[4] > h.ts_remain) { pr_err("%lu: Invalid ULE packet (pointer field %d)\n", - priv->ts_count, ts[4]); - ts += TS_SZ; - priv->ts_count++; + h.priv->ts_count, h.ts[4]); + h.ts += TS_SZ; + h.priv->ts_count++; continue; } /* Skip to destination of pointer field. */ - from_where = &ts[5] + ts[4]; - ts_remain -= 1 + ts[4]; - skipped = 0; + h.from_where = &h.ts[5] + h.ts[4]; + h.ts_remain -= 1 + h.ts[4]; + h.skipped = 0; } else { - skipped++; - ts += TS_SZ; - priv->ts_count++; + h.skipped++; + h.ts += TS_SZ; + h.priv->ts_count++; continue; } } - if (new_ts) { + if (h.new_ts) { /* Check continuity counter. */ - if ((ts[3] & 0x0F) == priv->tscc) - priv->tscc = (priv->tscc + 1) & 0x0F; + if ((h.ts[3] & 0x0F) == h.priv->tscc) + h.priv->tscc = (h.priv->tscc + 1) & 0x0F; else { /* TS discontinuity handling: */ pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n", - priv->ts_count, ts[3] & 0x0F, - priv->tscc); + h.priv->ts_count, h.ts[3] & 0x0F, + h.priv->tscc); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); + if (h.priv->ule_skb) { + dev_kfree_skb( h.priv->ule_skb ); /* Prepare for next SNDU. */ - // reset_ule(priv); moved to below. - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; + // reset_ule(h.priv); moved to below. + h.dev->stats.rx_errors++; + h.dev->stats.rx_frame_errors++; } - reset_ule(priv); + reset_ule(h.priv); /* skip to next PUSI. */ - priv->need_pusi = 1; + h.priv->need_pusi = 1; continue; } /* If we still have an incomplete payload, but PUSI is * set; some TS cells are missing. * This is only possible here, if we missed exactly 16 TS * cells (continuity counter wrap). */ - if (ts[1] & TS_PUSI) { - if (! priv->need_pusi) { - if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { + if (h.ts[1] & TS_PUSI) { + if (! h.priv->need_pusi) { + if (!(*h.from_where < (h.ts_remain-1)) || *h.from_where != h.priv->ule_sndu_remain) { /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ pr_warn("%lu: Invalid pointer field: %u.\n", - priv->ts_count, - *from_where); + h.priv->ts_count, + *h.from_where); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - error = true; - dev_kfree_skb(priv->ule_skb); + if (h.priv->ule_skb) { + h.error = true; + dev_kfree_skb(h.priv->ule_skb); } - if (error || priv->ule_sndu_remain) { - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - error = false; + if (h.error || h.priv->ule_sndu_remain) { + h.dev->stats.rx_errors++; + h.dev->stats.rx_frame_errors++; + h.error = false; } - reset_ule(priv); - priv->need_pusi = 1; + reset_ule(h.priv); + h.priv->need_pusi = 1; continue; } /* Skip pointer field (we're processing a * packed payload). */ - from_where += 1; - ts_remain -= 1; + h.from_where += 1; + h.ts_remain -= 1; } else - priv->need_pusi = 0; + h.priv->need_pusi = 0; - if (priv->ule_sndu_remain > 183) { + if (h.priv->ule_sndu_remain > 183) { /* Current SNDU lacks more data than there could be available in the * current TS cell. */ - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", - priv->ts_count, - priv->ule_sndu_remain, - ts[4], ts_remain); - dev_kfree_skb(priv->ule_skb); + h.dev->stats.rx_errors++; + h.dev->stats.rx_length_errors++; + pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h.ts_remain %d). Flushing incomplete payload.\n", + h.priv->ts_count, + h.priv->ule_sndu_remain, + h.ts[4], h.ts_remain); + dev_kfree_skb(h.priv->ule_skb); /* Prepare for next SNDU. */ - reset_ule(priv); + reset_ule(h.priv); /* Resync: go to where pointer field points to: start of next ULE SNDU. */ - from_where += ts[4]; - ts_remain -= ts[4]; + h.from_where += h.ts[4]; + h.ts_remain -= h.ts[4]; } } } /* Check if new payload needs to be started. */ - if (priv->ule_skb == NULL) { + if (h.priv->ule_skb == NULL) { /* Start a new payload with skb. * Find ULE header. It is only guaranteed that the * length field (2 bytes) is contained in the current * TS. - * Check ts_remain has to be >= 2 here. */ - if (ts_remain < 2) { + * Check h.ts_remain has to be >= 2 here. */ + if (h.ts_remain < 2) { pr_warn("Invalid payload packing: only %d bytes left in TS. Resyncing.\n", - ts_remain); - priv->ule_sndu_len = 0; - priv->need_pusi = 1; - ts += TS_SZ; + h.ts_remain); + h.priv->ule_sndu_len = 0; + h.priv->need_pusi = 1; + h.ts += TS_SZ; continue; } - if (! priv->ule_sndu_len) { + if (! h.priv->ule_sndu_len) { /* Got at least two bytes, thus extrace the SNDU length. */ - priv->ule_sndu_len = from_where[0] << 8 | from_where[1]; - if (priv->ule_sndu_len & 0x8000) { + h.priv->ule_sndu_len = h.from_where[0] << 8 | h.from_where[1]; + if (h.priv->ule_sndu_len & 0x8000) { /* D-Bit is set: no dest mac present. */ - priv->ule_sndu_len &= 0x7FFF; - priv->ule_dbit = 1; + h.priv->ule_sndu_len &= 0x7FFF; + h.priv->ule_dbit = 1; } else - priv->ule_dbit = 0; + h.priv->ule_dbit = 0; - if (priv->ule_sndu_len < 5) { + if (h.priv->ule_sndu_len < 5) { pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n", - priv->ts_count, - priv->ule_sndu_len); - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - priv->ule_sndu_len = 0; - priv->need_pusi = 1; - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; + h.priv->ts_count, + h.priv->ule_sndu_len); + h.dev->stats.rx_errors++; + h.dev->stats.rx_length_errors++; + h.priv->ule_sndu_len = 0; + h.priv->need_pusi = 1; + h.new_ts = 1; + h.ts += TS_SZ; + h.priv->ts_count++; continue; } - ts_remain -= 2; /* consume the 2 bytes SNDU length. */ - from_where += 2; + h.ts_remain -= 2; /* consume the 2 bytes SNDU length. */ + h.from_where += 2; } - priv->ule_sndu_remain = priv->ule_sndu_len + 2; + h.priv->ule_sndu_remain = h.priv->ule_sndu_len + 2; /* * State of current TS: - * ts_remain (remaining bytes in the current TS cell) + * h.ts_remain (remaining bytes in the current TS cell) * 0 ule_type is not available now, we need the next TS cell * 1 the first byte of the ule_type is present * >=2 full ULE header present, maybe some payload data as well. */ - switch (ts_remain) { + switch (h.ts_remain) { case 1: - priv->ule_sndu_remain--; - priv->ule_sndu_type = from_where[0] << 8; - priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ - ts_remain -= 1; from_where += 1; + h.priv->ule_sndu_remain--; + h.priv->ule_sndu_type = h.from_where[0] << 8; + h.priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ + h.ts_remain -= 1; h.from_where += 1; /* Continue w/ next TS. */ case 0: - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; + h.new_ts = 1; + h.ts += TS_SZ; + h.priv->ts_count++; continue; default: /* complete ULE header is present in current TS. */ /* Extract ULE type field. */ - if (priv->ule_sndu_type_1) { - priv->ule_sndu_type_1 = 0; - priv->ule_sndu_type |= from_where[0]; - from_where += 1; /* points to payload start. */ - ts_remain -= 1; + if (h.priv->ule_sndu_type_1) { + h.priv->ule_sndu_type_1 = 0; + h.priv->ule_sndu_type |= h.from_where[0]; + h.from_where += 1; /* points to payload start. */ + h.ts_remain -= 1; } else { /* Complete type is present in new TS. */ - priv->ule_sndu_type = from_where[0] << 8 | from_where[1]; - from_where += 2; /* points to payload start. */ - ts_remain -= 2; + h.priv->ule_sndu_type = h.from_where[0] << 8 | h.from_where[1]; + h.from_where += 2; /* points to payload start. */ + h.ts_remain -= 2; } break; } /* Allocate the skb (decoder target buffer) with the correct size, as follows: * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */ - priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN ); - if (priv->ule_skb == NULL) { + h.priv->ule_skb = dev_alloc_skb( h.priv->ule_sndu_len + ETH_HLEN + ETH_ALEN ); + if (h.priv->ule_skb == NULL) { pr_notice("%s: Memory squeeze, dropping packet.\n", - dev->name); - dev->stats.rx_dropped++; + h.dev->name); + h.dev->stats.rx_dropped++; return; } /* This includes the CRC32 _and_ dest mac, if !dbit. */ - priv->ule_sndu_remain = priv->ule_sndu_len; - priv->ule_skb->dev = dev; + h.priv->ule_sndu_remain = h.priv->ule_sndu_len; + h.priv->ule_skb->dev = h.dev; /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */ - skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN ); + skb_reserve( h.priv->ule_skb, ETH_HLEN + ETH_ALEN ); } /* Copy data into our current skb. */ - how_much = min(priv->ule_sndu_remain, (int)ts_remain); - memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much); - priv->ule_sndu_remain -= how_much; - ts_remain -= how_much; - from_where += how_much; + h.how_much = min(h.priv->ule_sndu_remain, (int)h.ts_remain); + memcpy(skb_put(h.priv->ule_skb, h.how_much), h.from_where, h.how_much); + h.priv->ule_sndu_remain -= h.how_much; + h.ts_remain -= h.how_much; + h.from_where += h.how_much; /* Check for complete payload. */ - if (priv->ule_sndu_remain <= 0) { + if (h.priv->ule_sndu_remain <= 0) { /* Check CRC32, we've got it in our skb already. */ - __be16 ulen = htons(priv->ule_sndu_len); - __be16 utype = htons(priv->ule_sndu_type); + __be16 ulen = htons(h.priv->ule_sndu_len); + __be16 utype = htons(h.priv->ule_sndu_type); const u8 *tail; struct kvec iov[3] = { { &ulen, sizeof ulen }, { &utype, sizeof utype }, - { priv->ule_skb->data, priv->ule_skb->len - 4 } + { h.priv->ule_skb->data, h.priv->ule_skb->len - 4 } }; u32 ule_crc = ~0L, expected_crc; - if (priv->ule_dbit) { + if (h.priv->ule_dbit) { /* Set D-bit for CRC32 verification, * if it was set originally. */ ulen |= htons(0x8000); } ule_crc = iov_crc32(ule_crc, iov, 3); - tail = skb_tail_pointer(priv->ule_skb); + tail = skb_tail_pointer(h.priv->ule_skb); expected_crc = *(tail - 4) << 24 | *(tail - 3) << 16 | *(tail - 2) << 8 | *(tail - 1); if (ule_crc != expected_crc) { - pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", - priv->ts_count, ule_crc, expected_crc, - priv->ule_sndu_len, priv->ule_sndu_type, - ts_remain, - ts_remain > 2 ? *(unsigned short *)from_where : 0); + pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, h.ts_remain %d, next 2: %x.\n", + h.priv->ts_count, ule_crc, expected_crc, + h.priv->ule_sndu_len, h.priv->ule_sndu_type, + h.ts_remain, + h.ts_remain > 2 ? *(unsigned short *)h.from_where : 0); #ifdef ULE_DEBUG hexdump( iov[0].iov_base, iov[0].iov_len ); hexdump( iov[1].iov_base, iov[1].iov_len ); hexdump( iov[2].iov_base, iov[2].iov_len ); - if (ule_where == ule_hist) { - hexdump( &ule_hist[98*TS_SZ], TS_SZ ); - hexdump( &ule_hist[99*TS_SZ], TS_SZ ); - } else if (ule_where == &ule_hist[TS_SZ]) { - hexdump( &ule_hist[99*TS_SZ], TS_SZ ); - hexdump( ule_hist, TS_SZ ); + if (h.ule_where == h.ule_hist) { + hexdump( &h.ule_hist[98*TS_SZ], TS_SZ ); + hexdump( &h.ule_hist[99*TS_SZ], TS_SZ ); + } else if (h.ule_where == &h.ule_hist[TS_SZ]) { + hexdump( &h.ule_hist[99*TS_SZ], TS_SZ ); + hexdump( h.ule_hist, TS_SZ ); } else { - hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ ); - hexdump( ule_where - TS_SZ, TS_SZ ); + hexdump( h.ule_where - TS_SZ - TS_SZ, TS_SZ ); + hexdump( h.ule_where - TS_SZ, TS_SZ ); } - ule_dump = 1; + h.ule_dump = 1; #endif - dev->stats.rx_errors++; - dev->stats.rx_crc_errors++; - dev_kfree_skb(priv->ule_skb); + h.dev->stats.rx_errors++; + h.dev->stats.rx_crc_errors++; + dev_kfree_skb(h.priv->ule_skb); } else { /* CRC32 verified OK. */ u8 dest_addr[ETH_ALEN]; @@ -635,10 +660,10 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) { [ 0 ... ETH_ALEN-1] = 0xff }; /* CRC32 was OK. Remove it from skb. */ - priv->ule_skb->tail -= 4; - priv->ule_skb->len -= 4; + h.priv->ule_skb->tail -= 4; + h.priv->ule_skb->len -= 4; - if (!priv->ule_dbit) { + if (!h.priv->ule_dbit) { /* * The destination MAC address is the * next data in the skb. It comes @@ -648,26 +673,26 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * should be passed up the stack. */ register int drop = 0; - if (priv->rx_mode != RX_MODE_PROMISC) { - if (priv->ule_skb->data[0] & 0x01) { + if (h.priv->rx_mode != RX_MODE_PROMISC) { + if (h.priv->ule_skb->data[0] & 0x01) { /* multicast or broadcast */ - if (!ether_addr_equal(priv->ule_skb->data, bc_addr)) { + if (!ether_addr_equal(h.priv->ule_skb->data, bc_addr)) { /* multicast */ - if (priv->rx_mode == RX_MODE_MULTI) { + if (h.priv->rx_mode == RX_MODE_MULTI) { int i; - for(i = 0; i < priv->multi_num && - !ether_addr_equal(priv->ule_skb->data, - priv->multi_macs[i]); i++) + for(i = 0; i < h.priv->multi_num && + !ether_addr_equal(h.priv->ule_skb->data, + h.priv->multi_macs[i]); i++) ; - if (i == priv->multi_num) + if (i == h.priv->multi_num) drop = 1; - } else if (priv->rx_mode != RX_MODE_ALL_MULTI) + } else if (h.priv->rx_mode != RX_MODE_ALL_MULTI) drop = 1; /* no broadcast; */ /* else: all multicast mode: accept all multicast packets */ } /* else: broadcast */ } - else if (!ether_addr_equal(priv->ule_skb->data, dev->dev_addr)) + else if (!ether_addr_equal(h.priv->ule_skb->data, h.dev->dev_addr)) drop = 1; /* else: destination address matches the MAC address of our receiver device */ } @@ -675,94 +700,94 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (drop) { #ifdef ULE_DEBUG - netdev_dbg(dev, "Dropping SNDU: MAC destination address does not match: dest addr: %pM, dev addr: %pM\n", - priv->ule_skb->data, dev->dev_addr); + netdev_dbg(h.dev, "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h.dev addr: %pM\n", + h.priv->ule_skb->data, h.dev->dev_addr); #endif - dev_kfree_skb(priv->ule_skb); + dev_kfree_skb(h.priv->ule_skb); goto sndu_done; } else { - skb_copy_from_linear_data(priv->ule_skb, + skb_copy_from_linear_data(h.priv->ule_skb, dest_addr, ETH_ALEN); - skb_pull(priv->ule_skb, ETH_ALEN); + skb_pull(h.priv->ule_skb, ETH_ALEN); } } /* Handle ULE Extension Headers. */ - if (priv->ule_sndu_type < ETH_P_802_3_MIN) { + if (h.priv->ule_sndu_type < ETH_P_802_3_MIN) { /* There is an extension header. Handle it accordingly. */ - int l = handle_ule_extensions(priv); + int l = handle_ule_extensions(h.priv); if (l < 0) { /* Mandatory extension header unknown or TEST SNDU. Drop it. */ // pr_warn("Dropping SNDU, extension headers.\n" ); - dev_kfree_skb(priv->ule_skb); + dev_kfree_skb(h.priv->ule_skb); goto sndu_done; } - skb_pull(priv->ule_skb, l); + skb_pull(h.priv->ule_skb, l); } /* * Construct/assure correct ethernet header. - * Note: in bridged mode (priv->ule_bridged != + * Note: in bridged mode (h.priv->ule_bridged != * 0) we already have the (original) ethernet * header at the start of the payload (after * optional dest. address and any extension * headers). */ - if (!priv->ule_bridged) { - skb_push(priv->ule_skb, ETH_HLEN); - ethh = (struct ethhdr *)priv->ule_skb->data; - if (!priv->ule_dbit) { - /* dest_addr buffer is only valid if priv->ule_dbit == 0 */ - memcpy(ethh->h_dest, dest_addr, ETH_ALEN); - eth_zero_addr(ethh->h_source); + if (!h.priv->ule_bridged) { + skb_push(h.priv->ule_skb, ETH_HLEN); + h.ethh = (struct ethhdr *)h.priv->ule_skb->data; + if (!h.priv->ule_dbit) { + /* dest_addr buffer is only valid if h.priv->ule_dbit == 0 */ + memcpy(h.ethh->h_dest, dest_addr, ETH_ALEN); + eth_zero_addr(h.ethh->h_source); } else /* zeroize source and dest */ - memset( ethh, 0, ETH_ALEN*2 ); + memset( h.ethh, 0, ETH_ALEN*2 ); - ethh->h_proto = htons(priv->ule_sndu_type); + h.ethh->h_proto = htons(h.priv->ule_sndu_type); } /* else: skb is in correct state; nothing to do. */ - priv->ule_bridged = 0; + h.priv->ule_bridged = 0; /* Stuff into kernel's protocol stack. */ - priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev); + h.priv->ule_skb->protocol = dvb_net_eth_type_trans(h.priv->ule_skb, h.dev); /* If D-bit is set (i.e. destination MAC address not present), * receive the packet anyhow. */ - /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) - priv->ule_skb->pkt_type = PACKET_HOST; */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += priv->ule_skb->len; - netif_rx(priv->ule_skb); + /* if (h.priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) + h.priv->ule_skb->pkt_type = PACKET_HOST; */ + h.dev->stats.rx_packets++; + h.dev->stats.rx_bytes += h.priv->ule_skb->len; + netif_rx(h.priv->ule_skb); } sndu_done: /* Prepare for next SNDU. */ - reset_ule(priv); + reset_ule(h.priv); } /* More data in current TS (look at the bytes following the CRC32)? */ - if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) { + if (h.ts_remain >= 2 && *((unsigned short *)h.from_where) != 0xFFFF) { /* Next ULE SNDU starts right there. */ - new_ts = 0; - priv->ule_skb = NULL; - priv->ule_sndu_type_1 = 0; - priv->ule_sndu_len = 0; + h.new_ts = 0; + h.priv->ule_skb = NULL; + h.priv->ule_sndu_type_1 = 0; + h.priv->ule_sndu_len = 0; // pr_warn("More data in current TS: [%#x %#x %#x %#x]\n", - // *(from_where + 0), *(from_where + 1), - // *(from_where + 2), *(from_where + 3)); - // pr_warn("ts @ %p, stopped @ %p:\n", ts, from_where + 0); - // hexdump(ts, 188); + // *(h.from_where + 0), *(h.from_where + 1), + // *(h.from_where + 2), *(h.from_where + 3)); + // pr_warn("h.ts @ %p, stopped @ %p:\n", h.ts, h.from_where + 0); + // hexdump(h.ts, 188); } else { - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; - if (priv->ule_skb == NULL) { - priv->need_pusi = 1; - priv->ule_sndu_type_1 = 0; - priv->ule_sndu_len = 0; + h.new_ts = 1; + h.ts += TS_SZ; + h.priv->ts_count++; + if (h.priv->ule_skb == NULL) { + h.priv->need_pusi = 1; + h.priv->ule_sndu_type_1 = 0; + h.priv->ule_sndu_len = 0; } } } /* for all available TS cells */ -- cgit v1.2.3 From 8b0041db80ddea91d9be509f0a7817dd09fbdd1d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 19 Nov 2016 12:56:59 -0200 Subject: [media] dvb-net: split the logic at dvb_net_ule() into other functions This function is too big and too complex, making really hard to understand what's there. Split it into sub-routines, in order to make it easier to be understood, and to allow gcc to better parse it. As a bonus, it gets rid of a goto in the middle of a routine. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_net.c | 828 ++++++++++++++++++++++----------------- 1 file changed, 467 insertions(+), 361 deletions(-) diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 6fef0fc61cd2..bd833b0824c6 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -332,8 +332,458 @@ struct dvb_net_ule_handle { #endif }; +static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h) +{ + /* We are about to process a new TS cell. */ + +#ifdef ULE_DEBUG + if (h->ule_where >= &h->ule_hist[100*TS_SZ]) + h->ule_where = h->ule_hist; + memcpy(h->ule_where, h->ts, TS_SZ); + if (h->ule_dump) { + hexdump(h->ule_where, TS_SZ); + h->ule_dump = 0; + } + h->ule_where += TS_SZ; +#endif + + /* + * Check TS h->error conditions: sync_byte, transport_error_indicator, + * scrambling_control . + */ + if ((h->ts[0] != TS_SYNC) || (h->ts[1] & TS_TEI) || + ((h->ts[3] & TS_SC) != 0)) { + pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", + h->priv->ts_count, h->ts[0], + (h->ts[1] & TS_TEI) >> 7, + (h->ts[3] & TS_SC) >> 6); + + /* Drop partly decoded SNDU, reset state, resync on PUSI. */ + if (h->priv->ule_skb) { + dev_kfree_skb(h->priv->ule_skb); + /* Prepare for next SNDU. */ + h->dev->stats.rx_errors++; + h->dev->stats.rx_frame_errors++; + } + reset_ule(h->priv); + h->priv->need_pusi = 1; + + /* Continue with next TS cell. */ + h->ts += TS_SZ; + h->priv->ts_count++; + return 1; + } + + h->ts_remain = 184; + h->from_where = h->ts + 4; + + return 0; +} + +static int dvb_net_ule_ts_pusi(struct dvb_net_ule_handle *h) +{ + if (h->ts[1] & TS_PUSI) { + /* Find beginning of first ULE SNDU in current TS cell. */ + /* Synchronize continuity counter. */ + h->priv->tscc = h->ts[3] & 0x0F; + /* There is a pointer field here. */ + if (h->ts[4] > h->ts_remain) { + pr_err("%lu: Invalid ULE packet (pointer field %d)\n", + h->priv->ts_count, h->ts[4]); + h->ts += TS_SZ; + h->priv->ts_count++; + return 1; + } + /* Skip to destination of pointer field. */ + h->from_where = &h->ts[5] + h->ts[4]; + h->ts_remain -= 1 + h->ts[4]; + h->skipped = 0; + } else { + h->skipped++; + h->ts += TS_SZ; + h->priv->ts_count++; + return 1; + } + + return 0; +} + +static int dvb_net_ule_new_ts(struct dvb_net_ule_handle *h) +{ + /* Check continuity counter. */ + if ((h->ts[3] & 0x0F) == h->priv->tscc) + h->priv->tscc = (h->priv->tscc + 1) & 0x0F; + else { + /* TS discontinuity handling: */ + pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n", + h->priv->ts_count, h->ts[3] & 0x0F, + h->priv->tscc); + /* Drop partly decoded SNDU, reset state, resync on PUSI. */ + if (h->priv->ule_skb) { + dev_kfree_skb(h->priv->ule_skb); + /* Prepare for next SNDU. */ + // reset_ule(h->priv); moved to below. + h->dev->stats.rx_errors++; + h->dev->stats.rx_frame_errors++; + } + reset_ule(h->priv); + /* skip to next PUSI. */ + h->priv->need_pusi = 1; + return 1; + } + /* + * If we still have an incomplete payload, but PUSI is + * set; some TS cells are missing. + * This is only possible here, if we missed exactly 16 TS + * cells (continuity counter wrap). + */ + if (h->ts[1] & TS_PUSI) { + if (!h->priv->need_pusi) { + if (!(*h->from_where < (h->ts_remain-1)) || + *h->from_where != h->priv->ule_sndu_remain) { + /* + * Pointer field is invalid. + * Drop this TS cell and any started ULE SNDU. + */ + pr_warn("%lu: Invalid pointer field: %u.\n", + h->priv->ts_count, + *h->from_where); + + /* + * Drop partly decoded SNDU, reset state, + * resync on PUSI. + */ + if (h->priv->ule_skb) { + h->error = true; + dev_kfree_skb(h->priv->ule_skb); + } + + if (h->error || h->priv->ule_sndu_remain) { + h->dev->stats.rx_errors++; + h->dev->stats.rx_frame_errors++; + h->error = false; + } + + reset_ule(h->priv); + h->priv->need_pusi = 1; + return 1; + } + /* + * Skip pointer field (we're processing a + * packed payload). + */ + h->from_where += 1; + h->ts_remain -= 1; + } else + h->priv->need_pusi = 0; + + if (h->priv->ule_sndu_remain > 183) { + /* + * Current SNDU lacks more data than there + * could be available in the current TS cell. + */ + h->dev->stats.rx_errors++; + h->dev->stats.rx_length_errors++; + pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h->ts_remain %d). Flushing incomplete payload.\n", + h->priv->ts_count, + h->priv->ule_sndu_remain, + h->ts[4], h->ts_remain); + dev_kfree_skb(h->priv->ule_skb); + /* Prepare for next SNDU. */ + reset_ule(h->priv); + /* + * Resync: go to where pointer field points to: + * start of next ULE SNDU. + */ + h->from_where += h->ts[4]; + h->ts_remain -= h->ts[4]; + } + } + return 0; +} + + +/* + * Start a new payload with skb. + * Find ULE header. It is only guaranteed that the + * length field (2 bytes) is contained in the current + * TS. + * Check h.ts_remain has to be >= 2 here. + */ +static int dvb_net_ule_new_payload(struct dvb_net_ule_handle *h) +{ + if (h->ts_remain < 2) { + pr_warn("Invalid payload packing: only %d bytes left in TS. Resyncing.\n", + h->ts_remain); + h->priv->ule_sndu_len = 0; + h->priv->need_pusi = 1; + h->ts += TS_SZ; + return 1; + } + + if (!h->priv->ule_sndu_len) { + /* Got at least two bytes, thus extrace the SNDU length. */ + h->priv->ule_sndu_len = h->from_where[0] << 8 | + h->from_where[1]; + if (h->priv->ule_sndu_len & 0x8000) { + /* D-Bit is set: no dest mac present. */ + h->priv->ule_sndu_len &= 0x7FFF; + h->priv->ule_dbit = 1; + } else + h->priv->ule_dbit = 0; + + if (h->priv->ule_sndu_len < 5) { + pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n", + h->priv->ts_count, + h->priv->ule_sndu_len); + h->dev->stats.rx_errors++; + h->dev->stats.rx_length_errors++; + h->priv->ule_sndu_len = 0; + h->priv->need_pusi = 1; + h->new_ts = 1; + h->ts += TS_SZ; + h->priv->ts_count++; + return 1; + } + h->ts_remain -= 2; /* consume the 2 bytes SNDU length. */ + h->from_where += 2; + } + + h->priv->ule_sndu_remain = h->priv->ule_sndu_len + 2; + /* + * State of current TS: + * h->ts_remain (remaining bytes in the current TS cell) + * 0 ule_type is not available now, we need the next TS cell + * 1 the first byte of the ule_type is present + * >=2 full ULE header present, maybe some payload data as well. + */ + switch (h->ts_remain) { + case 1: + h->priv->ule_sndu_remain--; + h->priv->ule_sndu_type = h->from_where[0] << 8; + + /* first byte of ule_type is set. */ + h->priv->ule_sndu_type_1 = 1; + h->ts_remain -= 1; + h->from_where += 1; + /* fallthrough */ + case 0: + h->new_ts = 1; + h->ts += TS_SZ; + h->priv->ts_count++; + return 1; + + default: /* complete ULE header is present in current TS. */ + /* Extract ULE type field. */ + if (h->priv->ule_sndu_type_1) { + h->priv->ule_sndu_type_1 = 0; + h->priv->ule_sndu_type |= h->from_where[0]; + h->from_where += 1; /* points to payload start. */ + h->ts_remain -= 1; + } else { + /* Complete type is present in new TS. */ + h->priv->ule_sndu_type = h->from_where[0] << 8 | + h->from_where[1]; + h->from_where += 2; /* points to payload start. */ + h->ts_remain -= 2; + } + break; + } + + /* + * Allocate the skb (decoder target buffer) with the correct size, + * as follows: + * + * prepare for the largest case: bridged SNDU with MAC address + * (dbit = 0). + */ + h->priv->ule_skb = dev_alloc_skb(h->priv->ule_sndu_len + + ETH_HLEN + ETH_ALEN); + if (!h->priv->ule_skb) { + pr_notice("%s: Memory squeeze, dropping packet.\n", + h->dev->name); + h->dev->stats.rx_dropped++; + return -1; + } + + /* This includes the CRC32 _and_ dest mac, if !dbit. */ + h->priv->ule_sndu_remain = h->priv->ule_sndu_len; + h->priv->ule_skb->dev = h->dev; + /* + * Leave space for Ethernet or bridged SNDU header + * (eth hdr plus one MAC addr). + */ + skb_reserve(h->priv->ule_skb, ETH_HLEN + ETH_ALEN); + + return 0; +} + + +static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h) +{ + static const u8 bc_addr[ETH_ALEN] = { [0 ... ETH_ALEN - 1] = 0xff }; + + /* + * The destination MAC address is the next data in the skb. It comes + * before any extension headers. + * + * Check if the payload of this SNDU should be passed up the stack. + */ + if (h->priv->rx_mode == RX_MODE_PROMISC) + return 0; + + if (h->priv->ule_skb->data[0] & 0x01) { + /* multicast or broadcast */ + if (!ether_addr_equal(h->priv->ule_skb->data, bc_addr)) { + /* multicast */ + if (h->priv->rx_mode == RX_MODE_MULTI) { + int i; + + for (i = 0; i < h->priv->multi_num && + !ether_addr_equal(h->priv->ule_skb->data, + h->priv->multi_macs[i]); + i++) + ; + if (i == h->priv->multi_num) + return 1; + } else if (h->priv->rx_mode != RX_MODE_ALL_MULTI) + return 1; /* no broadcast; */ + /* + * else: + * all multicast mode: accept all multicast packets + */ + } + /* else: broadcast */ + } else if (!ether_addr_equal(h->priv->ule_skb->data, h->dev->dev_addr)) + return 1; + + return 0; +} + + +static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h, + u32 ule_crc, u32 expected_crc) +{ + u8 dest_addr[ETH_ALEN]; + + if (ule_crc != expected_crc) { + pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", + h->priv->ts_count, ule_crc, expected_crc, + h->priv->ule_sndu_len, h->priv->ule_sndu_type, + h->ts_remain, + h->ts_remain > 2 ? + *(unsigned short *)h->from_where : 0); + + #ifdef ULE_DEBUG + hexdump(iov[0].iov_base, iov[0].iov_len); + hexdump(iov[1].iov_base, iov[1].iov_len); + hexdump(iov[2].iov_base, iov[2].iov_len); + + if (h->ule_where == h->ule_hist) { + hexdump(&h->ule_hist[98*TS_SZ], TS_SZ); + hexdump(&h->ule_hist[99*TS_SZ], TS_SZ); + } else if (h->ule_where == &h->ule_hist[TS_SZ]) { + hexdump(&h->ule_hist[99*TS_SZ], TS_SZ); + hexdump(h->ule_hist, TS_SZ); + } else { + hexdump(h->ule_where - TS_SZ - TS_SZ, TS_SZ); + hexdump(h->ule_where - TS_SZ, TS_SZ); + } + h->ule_dump = 1; + #endif + + h->dev->stats.rx_errors++; + h->dev->stats.rx_crc_errors++; + dev_kfree_skb(h->priv->ule_skb); + + return; + } + + /* CRC32 verified OK. */ + + /* CRC32 was OK, so remove it from skb. */ + h->priv->ule_skb->tail -= 4; + h->priv->ule_skb->len -= 4; + + if (!h->priv->ule_dbit) { + if (dvb_net_ule_should_drop(h)) { +#ifdef ULE_DEBUG + netdev_dbg(h->dev, + "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n", + h->priv->ule_skb->data, h->dev->dev_addr); +#endif + dev_kfree_skb(h->priv->ule_skb); + return; + } + + skb_copy_from_linear_data(h->priv->ule_skb, dest_addr, + ETH_ALEN); + skb_pull(h->priv->ule_skb, ETH_ALEN); + } + + /* Handle ULE Extension Headers. */ + if (h->priv->ule_sndu_type < ETH_P_802_3_MIN) { + /* There is an extension header. Handle it accordingly. */ + int l = handle_ule_extensions(h->priv); + + if (l < 0) { + /* + * Mandatory extension header unknown or TEST SNDU. + * Drop it. + */ + + // pr_warn("Dropping SNDU, extension headers.\n" ); + dev_kfree_skb(h->priv->ule_skb); + return; + } + skb_pull(h->priv->ule_skb, l); + } + + /* + * Construct/assure correct ethernet header. + * Note: in bridged mode (h->priv->ule_bridged != 0) + * we already have the (original) ethernet + * header at the start of the payload (after + * optional dest. address and any extension + * headers). + */ + if (!h->priv->ule_bridged) { + skb_push(h->priv->ule_skb, ETH_HLEN); + h->ethh = (struct ethhdr *)h->priv->ule_skb->data; + if (!h->priv->ule_dbit) { + /* + * dest_addr buffer is only valid if + * h->priv->ule_dbit == 0 + */ + memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN); + eth_zero_addr(h->ethh->h_source); + } else /* zeroize source and dest */ + memset(h->ethh, 0, ETH_ALEN * 2); + + h->ethh->h_proto = htons(h->priv->ule_sndu_type); + } + /* else: skb is in correct state; nothing to do. */ + h->priv->ule_bridged = 0; + + /* Stuff into kernel's protocol stack. */ + h->priv->ule_skb->protocol = dvb_net_eth_type_trans(h->priv->ule_skb, + h->dev); + /* + * If D-bit is set (i.e. destination MAC address not present), + * receive the packet anyhow. + */ +#if 0 + if (h->priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) + h->priv->ule_skb->pkt_type = PACKET_HOST; +#endif + h->dev->stats.rx_packets++; + h->dev->stats.rx_bytes += h->priv->ule_skb->len; + netif_rx(h->priv->ule_skb); +} + static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) { + int ret; struct dvb_net_ule_handle h = { .dev = dev, .buf = buf, @@ -352,251 +802,42 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) #endif }; - /* For all TS cells in current buffer. + /* + * For all TS cells in current buffer. * Appearently, we are called for every single TS cell. */ - for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len; h.ts < h.ts_end; /* no incr. */ ) { + for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len; + h.ts < h.ts_end; /* no incr. */) { if (h.new_ts) { /* We are about to process a new TS cell. */ - -#ifdef ULE_DEBUG - if (h.ule_where >= &h.ule_hist[100*TS_SZ]) h.ule_where = h.ule_hist; - memcpy( h.ule_where, h.ts, TS_SZ ); - if (h.ule_dump) { - hexdump( h.ule_where, TS_SZ ); - h.ule_dump = 0; - } - h.ule_where += TS_SZ; -#endif - - /* Check TS h.error conditions: sync_byte, transport_error_indicator, scrambling_control . */ - if ((h.ts[0] != TS_SYNC) || (h.ts[1] & TS_TEI) || ((h.ts[3] & TS_SC) != 0)) { - pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", - h.priv->ts_count, h.ts[0], - (h.ts[1] & TS_TEI) >> 7, - (h.ts[3] & TS_SC) >> 6); - - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (h.priv->ule_skb) { - dev_kfree_skb( h.priv->ule_skb ); - /* Prepare for next SNDU. */ - h.dev->stats.rx_errors++; - h.dev->stats.rx_frame_errors++; - } - reset_ule(h.priv); - h.priv->need_pusi = 1; - - /* Continue with next TS cell. */ - h.ts += TS_SZ; - h.priv->ts_count++; + if (dvb_net_ule_new_ts_cell(&h)) continue; - } - - h.ts_remain = 184; - h.from_where = h.ts + 4; } + /* Synchronize on PUSI, if required. */ if (h.priv->need_pusi) { - if (h.ts[1] & TS_PUSI) { - /* Find beginning of first ULE SNDU in current TS cell. */ - /* Synchronize continuity counter. */ - h.priv->tscc = h.ts[3] & 0x0F; - /* There is a pointer field here. */ - if (h.ts[4] > h.ts_remain) { - pr_err("%lu: Invalid ULE packet (pointer field %d)\n", - h.priv->ts_count, h.ts[4]); - h.ts += TS_SZ; - h.priv->ts_count++; - continue; - } - /* Skip to destination of pointer field. */ - h.from_where = &h.ts[5] + h.ts[4]; - h.ts_remain -= 1 + h.ts[4]; - h.skipped = 0; - } else { - h.skipped++; - h.ts += TS_SZ; - h.priv->ts_count++; + if (dvb_net_ule_ts_pusi(&h)) continue; - } } if (h.new_ts) { - /* Check continuity counter. */ - if ((h.ts[3] & 0x0F) == h.priv->tscc) - h.priv->tscc = (h.priv->tscc + 1) & 0x0F; - else { - /* TS discontinuity handling: */ - pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n", - h.priv->ts_count, h.ts[3] & 0x0F, - h.priv->tscc); - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (h.priv->ule_skb) { - dev_kfree_skb( h.priv->ule_skb ); - /* Prepare for next SNDU. */ - // reset_ule(h.priv); moved to below. - h.dev->stats.rx_errors++; - h.dev->stats.rx_frame_errors++; - } - reset_ule(h.priv); - /* skip to next PUSI. */ - h.priv->need_pusi = 1; + if (dvb_net_ule_new_ts(&h)) continue; - } - /* If we still have an incomplete payload, but PUSI is - * set; some TS cells are missing. - * This is only possible here, if we missed exactly 16 TS - * cells (continuity counter wrap). */ - if (h.ts[1] & TS_PUSI) { - if (! h.priv->need_pusi) { - if (!(*h.from_where < (h.ts_remain-1)) || *h.from_where != h.priv->ule_sndu_remain) { - /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ - pr_warn("%lu: Invalid pointer field: %u.\n", - h.priv->ts_count, - *h.from_where); - - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (h.priv->ule_skb) { - h.error = true; - dev_kfree_skb(h.priv->ule_skb); - } - - if (h.error || h.priv->ule_sndu_remain) { - h.dev->stats.rx_errors++; - h.dev->stats.rx_frame_errors++; - h.error = false; - } - - reset_ule(h.priv); - h.priv->need_pusi = 1; - continue; - } - /* Skip pointer field (we're processing a - * packed payload). */ - h.from_where += 1; - h.ts_remain -= 1; - } else - h.priv->need_pusi = 0; - - if (h.priv->ule_sndu_remain > 183) { - /* Current SNDU lacks more data than there could be available in the - * current TS cell. */ - h.dev->stats.rx_errors++; - h.dev->stats.rx_length_errors++; - pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h.ts_remain %d). Flushing incomplete payload.\n", - h.priv->ts_count, - h.priv->ule_sndu_remain, - h.ts[4], h.ts_remain); - dev_kfree_skb(h.priv->ule_skb); - /* Prepare for next SNDU. */ - reset_ule(h.priv); - /* Resync: go to where pointer field points to: start of next ULE SNDU. */ - h.from_where += h.ts[4]; - h.ts_remain -= h.ts[4]; - } - } } /* Check if new payload needs to be started. */ if (h.priv->ule_skb == NULL) { - /* Start a new payload with skb. - * Find ULE header. It is only guaranteed that the - * length field (2 bytes) is contained in the current - * TS. - * Check h.ts_remain has to be >= 2 here. */ - if (h.ts_remain < 2) { - pr_warn("Invalid payload packing: only %d bytes left in TS. Resyncing.\n", - h.ts_remain); - h.priv->ule_sndu_len = 0; - h.priv->need_pusi = 1; - h.ts += TS_SZ; - continue; - } - - if (! h.priv->ule_sndu_len) { - /* Got at least two bytes, thus extrace the SNDU length. */ - h.priv->ule_sndu_len = h.from_where[0] << 8 | h.from_where[1]; - if (h.priv->ule_sndu_len & 0x8000) { - /* D-Bit is set: no dest mac present. */ - h.priv->ule_sndu_len &= 0x7FFF; - h.priv->ule_dbit = 1; - } else - h.priv->ule_dbit = 0; - - if (h.priv->ule_sndu_len < 5) { - pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n", - h.priv->ts_count, - h.priv->ule_sndu_len); - h.dev->stats.rx_errors++; - h.dev->stats.rx_length_errors++; - h.priv->ule_sndu_len = 0; - h.priv->need_pusi = 1; - h.new_ts = 1; - h.ts += TS_SZ; - h.priv->ts_count++; - continue; - } - h.ts_remain -= 2; /* consume the 2 bytes SNDU length. */ - h.from_where += 2; - } - - h.priv->ule_sndu_remain = h.priv->ule_sndu_len + 2; - /* - * State of current TS: - * h.ts_remain (remaining bytes in the current TS cell) - * 0 ule_type is not available now, we need the next TS cell - * 1 the first byte of the ule_type is present - * >=2 full ULE header present, maybe some payload data as well. - */ - switch (h.ts_remain) { - case 1: - h.priv->ule_sndu_remain--; - h.priv->ule_sndu_type = h.from_where[0] << 8; - h.priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ - h.ts_remain -= 1; h.from_where += 1; - /* Continue w/ next TS. */ - case 0: - h.new_ts = 1; - h.ts += TS_SZ; - h.priv->ts_count++; - continue; - - default: /* complete ULE header is present in current TS. */ - /* Extract ULE type field. */ - if (h.priv->ule_sndu_type_1) { - h.priv->ule_sndu_type_1 = 0; - h.priv->ule_sndu_type |= h.from_where[0]; - h.from_where += 1; /* points to payload start. */ - h.ts_remain -= 1; - } else { - /* Complete type is present in new TS. */ - h.priv->ule_sndu_type = h.from_where[0] << 8 | h.from_where[1]; - h.from_where += 2; /* points to payload start. */ - h.ts_remain -= 2; - } - break; - } - - /* Allocate the skb (decoder target buffer) with the correct size, as follows: - * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */ - h.priv->ule_skb = dev_alloc_skb( h.priv->ule_sndu_len + ETH_HLEN + ETH_ALEN ); - if (h.priv->ule_skb == NULL) { - pr_notice("%s: Memory squeeze, dropping packet.\n", - h.dev->name); - h.dev->stats.rx_dropped++; + ret = dvb_net_ule_new_payload(&h); + if (ret < 0) return; - } - - /* This includes the CRC32 _and_ dest mac, if !dbit. */ - h.priv->ule_sndu_remain = h.priv->ule_sndu_len; - h.priv->ule_skb->dev = h.dev; - /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */ - skb_reserve( h.priv->ule_skb, ETH_HLEN + ETH_ALEN ); + if (ret) + continue; } /* Copy data into our current skb. */ h.how_much = min(h.priv->ule_sndu_remain, (int)h.ts_remain); - memcpy(skb_put(h.priv->ule_skb, h.how_much), h.from_where, h.how_much); + memcpy(skb_put(h.priv->ule_skb, h.how_much), + h.from_where, h.how_much); h.priv->ule_sndu_remain -= h.how_much; h.ts_remain -= h.how_much; h.from_where += h.how_much; @@ -610,7 +851,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) struct kvec iov[3] = { { &ulen, sizeof ulen }, { &utype, sizeof utype }, - { h.priv->ule_skb->data, h.priv->ule_skb->len - 4 } + { h.priv->ule_skb->data, + h.priv->ule_skb->len - 4 } }; u32 ule_crc = ~0L, expected_crc; if (h.priv->ule_dbit) { @@ -625,145 +867,9 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) *(tail - 3) << 16 | *(tail - 2) << 8 | *(tail - 1); - if (ule_crc != expected_crc) { - pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, h.ts_remain %d, next 2: %x.\n", - h.priv->ts_count, ule_crc, expected_crc, - h.priv->ule_sndu_len, h.priv->ule_sndu_type, - h.ts_remain, - h.ts_remain > 2 ? *(unsigned short *)h.from_where : 0); -#ifdef ULE_DEBUG - hexdump( iov[0].iov_base, iov[0].iov_len ); - hexdump( iov[1].iov_base, iov[1].iov_len ); - hexdump( iov[2].iov_base, iov[2].iov_len ); - - if (h.ule_where == h.ule_hist) { - hexdump( &h.ule_hist[98*TS_SZ], TS_SZ ); - hexdump( &h.ule_hist[99*TS_SZ], TS_SZ ); - } else if (h.ule_where == &h.ule_hist[TS_SZ]) { - hexdump( &h.ule_hist[99*TS_SZ], TS_SZ ); - hexdump( h.ule_hist, TS_SZ ); - } else { - hexdump( h.ule_where - TS_SZ - TS_SZ, TS_SZ ); - hexdump( h.ule_where - TS_SZ, TS_SZ ); - } - h.ule_dump = 1; -#endif + dvb_net_ule_check_crc(&h, ule_crc, expected_crc); - h.dev->stats.rx_errors++; - h.dev->stats.rx_crc_errors++; - dev_kfree_skb(h.priv->ule_skb); - } else { - /* CRC32 verified OK. */ - u8 dest_addr[ETH_ALEN]; - static const u8 bc_addr[ETH_ALEN] = - { [ 0 ... ETH_ALEN-1] = 0xff }; - - /* CRC32 was OK. Remove it from skb. */ - h.priv->ule_skb->tail -= 4; - h.priv->ule_skb->len -= 4; - - if (!h.priv->ule_dbit) { - /* - * The destination MAC address is the - * next data in the skb. It comes - * before any extension headers. - * - * Check if the payload of this SNDU - * should be passed up the stack. - */ - register int drop = 0; - if (h.priv->rx_mode != RX_MODE_PROMISC) { - if (h.priv->ule_skb->data[0] & 0x01) { - /* multicast or broadcast */ - if (!ether_addr_equal(h.priv->ule_skb->data, bc_addr)) { - /* multicast */ - if (h.priv->rx_mode == RX_MODE_MULTI) { - int i; - for(i = 0; i < h.priv->multi_num && - !ether_addr_equal(h.priv->ule_skb->data, - h.priv->multi_macs[i]); i++) - ; - if (i == h.priv->multi_num) - drop = 1; - } else if (h.priv->rx_mode != RX_MODE_ALL_MULTI) - drop = 1; /* no broadcast; */ - /* else: all multicast mode: accept all multicast packets */ - } - /* else: broadcast */ - } - else if (!ether_addr_equal(h.priv->ule_skb->data, h.dev->dev_addr)) - drop = 1; - /* else: destination address matches the MAC address of our receiver device */ - } - /* else: promiscuous mode; pass everything up the stack */ - - if (drop) { -#ifdef ULE_DEBUG - netdev_dbg(h.dev, "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h.dev addr: %pM\n", - h.priv->ule_skb->data, h.dev->dev_addr); -#endif - dev_kfree_skb(h.priv->ule_skb); - goto sndu_done; - } - else - { - skb_copy_from_linear_data(h.priv->ule_skb, - dest_addr, - ETH_ALEN); - skb_pull(h.priv->ule_skb, ETH_ALEN); - } - } - - /* Handle ULE Extension Headers. */ - if (h.priv->ule_sndu_type < ETH_P_802_3_MIN) { - /* There is an extension header. Handle it accordingly. */ - int l = handle_ule_extensions(h.priv); - if (l < 0) { - /* Mandatory extension header unknown or TEST SNDU. Drop it. */ - // pr_warn("Dropping SNDU, extension headers.\n" ); - dev_kfree_skb(h.priv->ule_skb); - goto sndu_done; - } - skb_pull(h.priv->ule_skb, l); - } - - /* - * Construct/assure correct ethernet header. - * Note: in bridged mode (h.priv->ule_bridged != - * 0) we already have the (original) ethernet - * header at the start of the payload (after - * optional dest. address and any extension - * headers). - */ - - if (!h.priv->ule_bridged) { - skb_push(h.priv->ule_skb, ETH_HLEN); - h.ethh = (struct ethhdr *)h.priv->ule_skb->data; - if (!h.priv->ule_dbit) { - /* dest_addr buffer is only valid if h.priv->ule_dbit == 0 */ - memcpy(h.ethh->h_dest, dest_addr, ETH_ALEN); - eth_zero_addr(h.ethh->h_source); - } - else /* zeroize source and dest */ - memset( h.ethh, 0, ETH_ALEN*2 ); - - h.ethh->h_proto = htons(h.priv->ule_sndu_type); - } - /* else: skb is in correct state; nothing to do. */ - h.priv->ule_bridged = 0; - - /* Stuff into kernel's protocol stack. */ - h.priv->ule_skb->protocol = dvb_net_eth_type_trans(h.priv->ule_skb, h.dev); - /* If D-bit is set (i.e. destination MAC address not present), - * receive the packet anyhow. */ - /* if (h.priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) - h.priv->ule_skb->pkt_type = PACKET_HOST; */ - h.dev->stats.rx_packets++; - h.dev->stats.rx_bytes += h.priv->ule_skb->len; - netif_rx(h.priv->ule_skb); - } - sndu_done: /* Prepare for next SNDU. */ reset_ule(h.priv); } -- cgit v1.2.3 From 8c2ebcf103b106bd8b9c5517bf72885d126d3d27 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 16 Nov 2016 18:49:50 -0200 Subject: [media] media: remove obsolete Media Device Managed resource interfaces Remove obsolete media_device_get_devres(), media_device_find_devres(), and media_device_release_devres() interfaces. These interfaces are now obsolete. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 26 -------------------------- include/media/media-device.h | 32 -------------------------------- 2 files changed, 58 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 219ab5fc8b4c..8756275e9fc4 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -821,32 +821,6 @@ void media_device_unregister(struct media_device *mdev) } EXPORT_SYMBOL_GPL(media_device_unregister); -static void media_device_release_devres(struct device *dev, void *res) -{ -} - -struct media_device *media_device_get_devres(struct device *dev) -{ - struct media_device *mdev; - - mdev = devres_find(dev, media_device_release_devres, NULL, NULL); - if (mdev) - return mdev; - - mdev = devres_alloc(media_device_release_devres, - sizeof(struct media_device), GFP_KERNEL); - if (!mdev) - return NULL; - return devres_get(dev, mdev, NULL, NULL); -} -EXPORT_SYMBOL_GPL(media_device_get_devres); - -struct media_device *media_device_find_devres(struct device *dev) -{ - return devres_find(dev, media_device_release_devres, NULL, NULL); -} -EXPORT_SYMBOL_GPL(media_device_find_devres); - #if IS_ENABLED(CONFIG_PCI) void media_device_pci_init(struct media_device *mdev, struct pci_dev *pci_dev, diff --git a/include/media/media-device.h b/include/media/media-device.h index a267f9ceee8f..c21b4c5f5871 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -375,30 +375,6 @@ int __must_check media_device_register_entity_notify(struct media_device *mdev, void media_device_unregister_entity_notify(struct media_device *mdev, struct media_entity_notify *nptr); -/** - * media_device_get_devres() - get media device as device resource - * creates if one doesn't exist - * - * @dev: pointer to struct &device. - * - * Sometimes, the media controller &media_device needs to be shared by more - * than one driver. This function adds support for that, by dynamically - * allocating the &media_device and allowing it to be obtained from the - * struct &device associated with the common device where all sub-device - * components belong. So, for example, on an USB device with multiple - * interfaces, each interface may be handled by a separate per-interface - * drivers. While each interface have its own &device, they all share a - * common &device associated with the hole USB device. - */ -struct media_device *media_device_get_devres(struct device *dev); - -/** - * media_device_find_devres() - find media device as device resource - * - * @dev: pointer to struct &device. - */ -struct media_device *media_device_find_devres(struct device *dev); - /* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, graph_obj.list) @@ -476,14 +452,6 @@ static inline void media_device_unregister_entity_notify( struct media_entity_notify *nptr) { } -static inline struct media_device *media_device_get_devres(struct device *dev) -{ - return NULL; -} -static inline struct media_device *media_device_find_devres(struct device *dev) -{ - return NULL; -} static inline void media_device_pci_init(struct media_device *mdev, struct pci_dev *pci_dev, -- cgit v1.2.3 From fa4a2fd17dc5d2d1fbad7ace78d39d7fea20d78e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Nov 2016 14:16:04 -0200 Subject: [media] v4l: rcar_fdp1: mark PM functions as __maybe_unused The new driver produces a warning when CONFIG_PM is disabled: platform/rcar_fdp1.c:2408:12: error: 'fdp1_pm_runtime_resume' defined but not used [-Werror=unused-function] platform/rcar_fdp1.c:2399:12: error: 'fdp1_pm_runtime_suspend' defined but not used [-Werror=unused-function] This marks the two functions as __maybe_unused. Fixes: 4710b752e029 ("[media] v4l: Add Renesas R-Car FDP1 Driver") Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_fdp1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index dd1a6ea17f22..674cc1309b43 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2396,7 +2396,7 @@ static int fdp1_remove(struct platform_device *pdev) return 0; } -static int fdp1_pm_runtime_suspend(struct device *dev) +static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev) { struct fdp1_dev *fdp1 = dev_get_drvdata(dev); @@ -2405,7 +2405,7 @@ static int fdp1_pm_runtime_suspend(struct device *dev) return 0; } -static int fdp1_pm_runtime_resume(struct device *dev) +static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev) { struct fdp1_dev *fdp1 = dev_get_drvdata(dev); -- cgit v1.2.3 From 1d38971438157dc57f0a4be89abf23b472458633 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Nov 2016 14:16:05 -0200 Subject: [media] v4l: rcar_fdp1: add FCP dependency Commit 4710b752e029 ("[media] v4l: Add Renesas R-Car FDP1 Driver") in the v4l-dvb tree adds CONFIG_VIDEO_RENESAS_FDP1. It calls into the FCP driver, but when there is no dependency, FCP might be a module while FDP1 is built-in. We have the same logic in VIDEO_RENESAS_VSP1, which also depends on FCP not being a module when it is built-in itself. drivers/media/platform/rcar_fdp1.o: In function `fdp1_pm_runtime_resume': rcar_fdp1.c:(.text.fdp1_pm_runtime_resume+0x78): undefined reference to `rcar_fcp_enable' drivers/media/platform/rcar_fdp1.o: In function `fdp1_pm_runtime_suspend': rcar_fdp1.c:(.text.fdp1_pm_runtime_suspend+0x14): undefined reference to `rcar_fcp_disable' drivers/media/platform/rcar_fdp1.o: In function `fdp1_probe': rcar_fdp1.c:(.text.fdp1_probe+0x15c): undefined reference to `rcar_fcp_get' Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 60e20e5f4282..d944421e392d 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -311,6 +311,7 @@ config VIDEO_RENESAS_FDP1 tristate "Renesas Fine Display Processor" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA depends on ARCH_SHMOBILE || COMPILE_TEST + depends on (!ARCH_RENESAS && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV ---help--- -- cgit v1.2.3 From 399426cadf5b0539a5b2a4d805257ce8acc6aba2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 19 Nov 2016 19:27:30 -0200 Subject: [media] cx88: make checkpatch.pl happy Usually, I don't like fixing coding style issues on non-staging drivers, as it could be a mess pretty easy, and could become like a snow ball. That's the case of recent changes on two changesets: they disalign some statements. Yet, a care a lot with cx88 driver, as it was the first driver I touched at the Kernel, and I've been maintaining it since 2005. So, several of the coding style issues were due to my code. Per Andrey's suggestion, I ran checkpatch.pl in strict mode, with fixed several other issues, did some function alinments, but broke other alinments. So, I had to manually apply another round of manual fixes to make sure that everything is ok, and to make checkpatch happy with this patch. With this patch, checkpatch.pl is now happy when called with: ./scripts/checkpatch.pl -f --max-line-length=998 --ignore PREFER_PR_LEVEL Also, the 80-cols violations that made sense were fixed. Checkpatch would be happier if we convert it to use dev_foo(), but this is a more complex change. NOTE: there are some places with msleep(1). As this driver was written at the time that the default was to sleep at least 10ms on such calls (e. g. CONFIG_HZ=100), I replaced those calls by usleep_range(10000, 20000), with should be safe to avoid breakages. Fixes: 65bc2fe86e66 ("[media] cx88: convert it to use pr_foo() macros") Fixes: 7b61ba8ff838 ("[media] cx88: make checkpatch happier") Suggested-by: Andrey Utkin Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Andrey Utkin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 206 ++++++++++---------- drivers/media/pci/cx88/cx88-blackbird.c | 169 ++++++++++------- drivers/media/pci/cx88/cx88-cards.c | 313 +++++++++++++++++-------------- drivers/media/pci/cx88/cx88-core.c | 205 ++++++++++---------- drivers/media/pci/cx88/cx88-dsp.c | 50 +++-- drivers/media/pci/cx88/cx88-dvb.c | 154 +++++++-------- drivers/media/pci/cx88/cx88-i2c.c | 25 ++- drivers/media/pci/cx88/cx88-input.c | 45 +++-- drivers/media/pci/cx88/cx88-mpeg.c | 114 +++++------ drivers/media/pci/cx88/cx88-reg.h | 110 +++++------ drivers/media/pci/cx88/cx88-tvaudio.c | 63 ++++--- drivers/media/pci/cx88/cx88-vbi.c | 19 +- drivers/media/pci/cx88/cx88-video.c | 155 ++++++++------- drivers/media/pci/cx88/cx88-vp3054-i2c.c | 10 +- drivers/media/pci/cx88/cx88-vp3054-i2c.h | 38 ++-- drivers/media/pci/cx88/cx88.h | 171 ++++++++--------- 16 files changed, 975 insertions(+), 872 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 56770e84b3d5..c81fe4681d14 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,6 @@ #include #include -#include #include #include #include @@ -46,9 +46,9 @@ chip->core->name, ##arg); \ } while (0) -/**************************************************************************** - Data type declarations - Can be moded to a header file later - ****************************************************************************/ +/* + * Data type declarations - Can be moded to a header file later + */ struct cx88_audio_buffer { unsigned int bpl; @@ -82,13 +82,10 @@ struct cx88_audio_dev { struct snd_pcm_substream *substream; }; -typedef struct cx88_audio_dev snd_cx88_card_t; - - -/**************************************************************************** - Module global static vars - ****************************************************************************/ +/* + * Module global static vars + */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -100,10 +97,9 @@ MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); - -/**************************************************************************** - Module macros - ****************************************************************************/ +/* + * Module macros + */ MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); MODULE_AUTHOR("Ricardo Cerqueira"); @@ -116,15 +112,15 @@ static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); -/**************************************************************************** - Module specific funtions - ****************************************************************************/ +/* + * Module specific functions + */ /* * BOARD Specific: Sets audio DMA */ -static int _cx88_start_audio_dma(snd_cx88_card_t *chip) +static int _cx88_start_audio_dma(struct cx88_audio_dev *chip) { struct cx88_audio_buffer *buf = chip->buf; struct cx88_core *core = chip->core; @@ -143,8 +139,9 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET); atomic_set(&chip->count, 0); - dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n", - buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1, + dprintk(1, + "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n", + buf->bpl, cx_read(audio_ch->cmds_start + 8) >> 1, chip->num_periods, buf->bpl * chip->num_periods); /* Enables corresponding bits at AUD_INT_STAT */ @@ -158,8 +155,11 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */ - cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */ + + /* Enables Risc Processor */ + cx_set(MO_DEV_CNTRL2, (1 << 5)); + /* audio downstream FIFO and RISC enable */ + cx_set(MO_AUD_DMACNTRL, 0x11); if (debug) cx88_sram_channel_dump(chip->core, audio_ch); @@ -170,7 +170,7 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip) /* * BOARD Specific: Resets audio DMA */ -static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) +static int _cx88_stop_audio_dma(struct cx88_audio_dev *chip) { struct cx88_core *core = chip->core; @@ -185,7 +185,8 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); if (debug) - cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]); + cx88_sram_channel_dump(chip->core, + &cx88_sram_channels[SRAM_CH25]); return 0; } @@ -211,7 +212,7 @@ static const char *cx88_aud_irqs[32] = { /* * BOARD Specific: Threats IRQ audio specific calls */ -static void cx8801_aud_irq(snd_cx88_card_t *chip) +static void cx8801_aud_irq(struct cx88_audio_dev *chip) { struct cx88_core *core = chip->core; u32 status, mask; @@ -249,7 +250,7 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip) */ static irqreturn_t cx8801_irq(int irq, void *dev_id) { - snd_cx88_card_t *chip = dev_id; + struct cx88_audio_dev *chip = dev_id; struct cx88_core *core = chip->core; u32 status; int loop, handled = 0; @@ -286,26 +287,25 @@ static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) int i; buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); - if (buf->vaddr == NULL) { + if (!buf->vaddr) { dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); return -ENOMEM; } dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n", - (unsigned long)buf->vaddr, - nr_pages << PAGE_SHIFT); + (unsigned long)buf->vaddr, nr_pages << PAGE_SHIFT); memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); buf->nr_pages = nr_pages; buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); - if (buf->sglist == NULL) + if (!buf->sglist) goto vzalloc_err; sg_init_table(buf->sglist, buf->nr_pages); for (i = 0; i < buf->nr_pages; i++) { pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); - if (pg == NULL) + if (!pg) goto vmalloc_to_page_err; sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); } @@ -341,7 +341,8 @@ static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, + PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; } @@ -355,18 +356,18 @@ static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf) return 0; } - -static int dsp_buffer_free(snd_cx88_card_t *chip) +static int dsp_buffer_free(struct cx88_audio_dev *chip) { struct cx88_riscmem *risc = &chip->buf->risc; - BUG_ON(!chip->dma_size); + WARN_ON(!chip->dma_size); dprintk(2, "Freeing buffer\n"); cx88_alsa_dma_unmap(chip); cx88_alsa_dma_free(chip->buf); if (risc->cpu) - pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma); + pci_free_consistent(chip->pci, risc->size, + risc->cpu, risc->dma); kfree(chip->buf); chip->buf = NULL; @@ -374,9 +375,9 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) return 0; } -/**************************************************************************** - ALSA PCM Interface - ****************************************************************************/ +/* + * ALSA PCM Interface + */ /* * Digital hardware definition @@ -394,13 +395,15 @@ static const struct snd_pcm_hardware snd_cx88_digital_hw = { .rate_max = 48000, .channels_min = 2, .channels_max = 2, - /* Analog audio output will be full of clicks and pops if there - are not exactly four lines in the SRAM FIFO buffer. */ - .period_bytes_min = DEFAULT_FIFO_SIZE/4, - .period_bytes_max = DEFAULT_FIFO_SIZE/4, + /* + * Analog audio output will be full of clicks and pops if there + * are not exactly four lines in the SRAM FIFO buffer. + */ + .period_bytes_min = DEFAULT_FIFO_SIZE / 4, + .period_bytes_max = DEFAULT_FIFO_SIZE / 4, .periods_min = 1, .periods_max = 1024, - .buffer_bytes_max = (1024*1024), + .buffer_bytes_max = (1024 * 1024), }; /* @@ -408,7 +411,7 @@ static const struct snd_pcm_hardware snd_cx88_digital_hw = { */ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) { - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); + struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int err; @@ -417,7 +420,8 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) return -ENODEV; } - err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS); + err = snd_pcm_hw_constraint_pow2(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) goto _error; @@ -453,7 +457,7 @@ static int snd_cx88_close(struct snd_pcm_substream *substream) static int snd_cx88_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); + struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); struct cx88_audio_buffer *buf; int ret; @@ -467,18 +471,18 @@ static int snd_cx88_hw_params(struct snd_pcm_substream *substream, chip->num_periods = params_periods(hw_params); chip->dma_size = chip->period_size * params_periods(hw_params); - BUG_ON(!chip->dma_size); - BUG_ON(chip->num_periods & (chip->num_periods-1)); + WARN_ON(!chip->dma_size); + WARN_ON(chip->num_periods & (chip->num_periods - 1)); buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (buf == NULL) + if (!buf) return -ENOMEM; chip->buf = buf; buf->bpl = chip->period_size; ret = cx88_alsa_dma_init(chip, - (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); + (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); if (ret < 0) goto error; @@ -492,7 +496,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream *substream, goto error; /* Loop back to start of program */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); + buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); substream->runtime->dma_area = chip->buf->vaddr; @@ -510,8 +514,7 @@ error: */ static int snd_cx88_hw_free(struct snd_pcm_substream *substream) { - - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); + struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); if (substream->runtime->dma_area) { dsp_buffer_free(chip); @@ -534,7 +537,7 @@ static int snd_cx88_prepare(struct snd_pcm_substream *substream) */ static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) { - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); + struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); int err; /* Local interrupts are already disabled by ALSA */ @@ -562,7 +565,7 @@ static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) */ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) { - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); + struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; u16 count; @@ -571,14 +574,14 @@ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) // dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__, // count, new, count & (runtime->periods-1), // runtime->period_size * (count & (runtime->periods-1))); - return runtime->period_size * (count & (runtime->periods-1)); + return runtime->period_size * (count & (runtime->periods - 1)); } /* * page callback (needed for mmap) */ static struct page *snd_cx88_page(struct snd_pcm_substream *substream, - unsigned long offset) + unsigned long offset) { void *pageptr = substream->runtime->dma_area + offset; @@ -603,7 +606,8 @@ static const struct snd_pcm_ops snd_cx88_pcm_ops = { /* * create a PCM device */ -static int snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name) +static int snd_cx88_pcm(struct cx88_audio_dev *chip, int device, + const char *name) { int err; struct snd_pcm *pcm; @@ -618,9 +622,9 @@ static int snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name) return 0; } -/**************************************************************************** - CONTROL INTERFACE - ****************************************************************************/ +/* + * CONTROL INTERFACE + */ static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) { @@ -635,7 +639,7 @@ static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol, static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f), bal = cx_read(AUD_BAL_CTL); @@ -648,9 +652,9 @@ static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol, } static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; int left = value->value.integer.value[0]; int right = value->value.integer.value[1]; @@ -672,7 +676,7 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; int left, right, v, b; int changed = 0; @@ -722,7 +726,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = { static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; u32 bit = kcontrol->private_value; @@ -731,9 +735,9 @@ static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol, } static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; u32 bit = kcontrol->private_value; int ret = 0; @@ -745,8 +749,9 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, vol ^= bit; cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); /* Pass mute onto any WM8775 */ - if (core->sd_wm8775 && ((1<<6) == bit)) - wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); + if (core->sd_wm8775 && ((1 << 6) == bit)) + wm8775_s_ctrl(core, + V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); ret = 1; } spin_unlock_irq(&chip->reg_lock); @@ -759,7 +764,7 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = { .info = snd_ctl_boolean_mono_info, .get = snd_cx88_switch_get, .put = snd_cx88_switch_put, - .private_value = (1<<8), + .private_value = (1 << 8), }; static const struct snd_kcontrol_new snd_cx88_source_switch = { @@ -768,13 +773,13 @@ static const struct snd_kcontrol_new snd_cx88_source_switch = { .info = snd_ctl_boolean_mono_info, .get = snd_cx88_switch_get, .put = snd_cx88_switch_put, - .private_value = (1<<6), + .private_value = (1 << 6), }; static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; s32 val; @@ -784,9 +789,9 @@ static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, } static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); + struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; wm8775_s_ctrl(core, V4L2_CID_AUDIO_LOUDNESS, @@ -802,9 +807,9 @@ static struct snd_kcontrol_new snd_cx88_alc_switch = { .put = snd_cx88_alc_put, }; -/**************************************************************************** - Basic Flow for Sound Devices - ****************************************************************************/ +/* + * Basic Flow for Sound Devices + */ /* * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio @@ -822,9 +827,8 @@ MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl); * Chip-specific destructor */ -static int snd_cx88_free(snd_cx88_card_t *chip) +static int snd_cx88_free(struct cx88_audio_dev *chip) { - if (chip->irq >= 0) free_irq(chip->irq, chip); @@ -839,25 +843,24 @@ static int snd_cx88_free(snd_cx88_card_t *chip) */ static void snd_cx88_dev_free(struct snd_card *card) { - snd_cx88_card_t *chip = card->private_data; + struct cx88_audio_dev *chip = card->private_data; snd_cx88_free(chip); } - /* * Alsa Constructor - Component probe */ static int devno; static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, - snd_cx88_card_t **rchip, + struct cx88_audio_dev **rchip, struct cx88_core **core_ptr) { - snd_cx88_card_t *chip; - struct cx88_core *core; - int err; - unsigned char pci_lat; + struct cx88_audio_dev *chip; + struct cx88_core *core; + int err; + unsigned char pci_lat; *rchip = NULL; @@ -870,7 +873,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, chip = card->private_data; core = cx88_core_get(pci); - if (core == NULL) { + if (!core) { err = -EINVAL; return err; } @@ -882,7 +885,6 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, return err; } - /* pci init */ chip->card = card; chip->pci = pci; @@ -896,17 +898,18 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, IRQF_SHARED, chip->core->name, chip); if (err < 0) { dprintk(0, "%s: can't get IRQ %d\n", - chip->core->name, chip->pci->irq); + chip->core->name, chip->pci->irq); return err; } /* print pci info */ pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat); - dprintk(1, "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", + dprintk(1, + "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", core->name, devno, - pci_name(pci), pci->revision, pci->irq, - pci_lat, (unsigned long long)pci_resource_start(pci, 0)); + pci_name(pci), pci->revision, pci->irq, + pci_lat, (unsigned long long)pci_resource_start(pci, 0)); chip->irq = pci->irq; synchronize_irq(chip->irq); @@ -920,10 +923,10 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, static int cx88_audio_initdev(struct pci_dev *pci, const struct pci_device_id *pci_id) { - struct snd_card *card; - snd_cx88_card_t *chip; - struct cx88_core *core = NULL; - int err; + struct snd_card *card; + struct cx88_audio_dev *chip; + struct cx88_core *core = NULL; + int err; if (devno >= SNDRV_CARDS) return (-ENODEV); @@ -934,7 +937,7 @@ static int cx88_audio_initdev(struct pci_dev *pci, } err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE, - sizeof(snd_cx88_card_t), &card); + sizeof(struct cx88_audio_dev), &card); if (err < 0) return err; @@ -970,7 +973,7 @@ static int cx88_audio_initdev(struct pci_dev *pci, strcpy(card->mixername, "CX88"); dprintk(0, "%s/%i: ALSA support for cx2388x boards\n", - card->driver, devno); + card->driver, devno); err = snd_card_register(card); if (err < 0) @@ -984,6 +987,7 @@ error: snd_card_free(card); return err; } + /* * ALSA destructor */ diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index bffd064daff5..aa49c9597d9c 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -66,6 +66,7 @@ enum blackbird_capture_type { BLACKBIRD_RAW_CAPTURE, BLACKBIRD_RAW_PASSTHRU_CAPTURE }; + enum blackbird_capture_bits { BLACKBIRD_RAW_BITS_NONE = 0x00, BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01, @@ -74,33 +75,40 @@ enum blackbird_capture_bits { BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 }; + enum blackbird_capture_end { BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ BLACKBIRD_END_NOW, /* stop immediately, no irq */ }; + enum blackbird_framerate { BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ }; + enum blackbird_stream_port { BLACKBIRD_OUTPUT_PORT_MEMORY, BLACKBIRD_OUTPUT_PORT_STREAMING, BLACKBIRD_OUTPUT_PORT_SERIAL }; + enum blackbird_data_xfer_status { BLACKBIRD_MORE_BUFFERS_FOLLOW, BLACKBIRD_LAST_BUFFER, }; + enum blackbird_picture_mask { BLACKBIRD_PICTURE_MASK_NONE, BLACKBIRD_PICTURE_MASK_I_FRAMES, BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, }; + enum blackbird_vbi_mode_bits { BLACKBIRD_VBI_BITS_SLICED, BLACKBIRD_VBI_BITS_RAW, }; + enum blackbird_vbi_insertion_bits { BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, @@ -108,56 +116,69 @@ enum blackbird_vbi_insertion_bits { BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, }; + enum blackbird_dma_unit { BLACKBIRD_DMA_BYTES, BLACKBIRD_DMA_FRAMES, }; + enum blackbird_dma_transfer_status_bits { BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, }; + enum blackbird_pause { BLACKBIRD_PAUSE_ENCODING, BLACKBIRD_RESUME_ENCODING, }; + enum blackbird_copyright { BLACKBIRD_COPYRIGHT_OFF, BLACKBIRD_COPYRIGHT_ON, }; + enum blackbird_notification_type { BLACKBIRD_NOTIFICATION_REFRESH, }; + enum blackbird_notification_status { BLACKBIRD_NOTIFICATION_OFF, BLACKBIRD_NOTIFICATION_ON, }; + enum blackbird_notification_mailbox { BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, }; + enum blackbird_field1_lines { BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */ }; + enum blackbird_field2_lines { BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */ BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ }; + enum blackbird_custom_data_type { BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, BLACKBIRD_CUSTOM_PRIVATE_PACKET, }; + enum blackbird_mute { BLACKBIRD_UNMUTE, BLACKBIRD_MUTE, }; + enum blackbird_mute_video_mask { BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00, BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000, BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000, }; + enum blackbird_mute_video_shift { BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8, BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, @@ -281,7 +302,6 @@ static int register_write(struct cx88_core *core, u32 address, u32 value) return wait_ready_gpio0_bit1(core, 1); } - static int register_read(struct cx88_core *core, u32 address, u32 *value) { int retval; @@ -304,7 +324,8 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value) /* ------------------------------------------------------------------ */ -static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) +static int blackbird_mbox_func(void *priv, u32 command, int in, + int out, u32 data[CX2341X_MBOX_MAX_DATA]) { struct cx8802_dev *dev = priv; unsigned long timeout; @@ -313,11 +334,14 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat dprintk(1, "%s: 0x%X\n", __func__, command); - /* this may not be 100% safe if we can't read any memory location - without side effects */ + /* + * this may not be 100% safe if we can't read any memory location + * without side effects + */ memory_read(dev->core, dev->mailbox - 4, &value); if (value != 0x12345678) { - dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n"); + dprintk(0, + "Firmware and/or mailbox pointer not initialized or corrupted\n"); return -EIO; } @@ -332,7 +356,8 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat /* write command + args + fill remaining with zeros */ memory_write(dev->core, dev->mailbox + 1, command); /* command code */ - memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ + /* timeout */ + memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); for (i = 0; i < in; i++) { memory_write(dev->core, dev->mailbox + 4 + i, data[i]); dprintk(1, "API Input %d = %d\n", i, data[i]); @@ -369,9 +394,13 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat memory_write(dev->core, dev->mailbox, flag); return retval; } + /* ------------------------------------------------------------------ */ -/* We don't need to call the API often, so using just one mailbox will probably suffice */ +/* + * We don't need to call the API often, so using just one mailbox + * will probably suffice + */ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, u32 inputcnt, u32 outputcnt, ...) { @@ -381,9 +410,9 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, va_start(vargs, outputcnt); - for (i = 0; i < inputcnt; i++) { + for (i = 0; i < inputcnt; i++) data[i] = va_arg(vargs, int); - } + err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data); for (i = 0; i < outputcnt; i++) { int *vptr = va_arg(vargs, int *); @@ -408,7 +437,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev) signaturecnt = 0; if (signaturecnt == 4) { dprintk(1, "Mailbox signature found\n"); - return i+1; + return i + 1; } } dprintk(0, "Mailbox signature values not found!\n"); @@ -427,10 +456,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) __le32 *dataptr; retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); - retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); - retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); - retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); - msleep(1); + retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, + IVTV_CMD_HW_BLOCKS_RST); + retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, + 0x80000640); + retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, + 0x1A); + usleep_range(10000, 20000); retval |= register_write(dev->core, IVTV_REG_APU, 0); if (retval < 0) @@ -439,7 +471,6 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, &dev->pci->dev); - if (retval != 0) { pr_err("Hotplug firmware request failed (%s).\n", CX2341X_FIRM_ENC_FILENAME); @@ -482,10 +513,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) } dprintk(0, "Firmware upload successful.\n"); - retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); + retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, + IVTV_CMD_HW_BLOCKS_RST); retval |= register_read(dev->core, IVTV_REG_SPU, &value); retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); - msleep(1); + usleep_range(10000, 20000); retval |= register_read(dev->core, IVTV_REG_VPU, &value); retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); @@ -495,19 +527,19 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) return 0; } -/** - Settings used by the windows tv app for PVR2000: -================================================================================================================= -Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode ------------------------------------------------------------------------------------------------------------------ -MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo -MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo -VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo -DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo -DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo -================================================================================================================= -*DB: "DirectBurn" -*/ +/* + * Settings used by the windows tv app for PVR2000: + * ================================================================================================================= + * Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode + * ----------------------------------------------------------------------------------------------------------------- + * MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo + * MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo + * VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo + * DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo + * DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo + * ================================================================================================================= + * [*] DB: "DirectBurn" + */ static void blackbird_codec_settings(struct cx8802_dev *dev) { @@ -515,11 +547,12 @@ static void blackbird_codec_settings(struct cx8802_dev *dev) /* assign frame size */ blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - core->height, core->width); + core->height, core->width); dev->cxhdl.width = core->width; dev->cxhdl.height = core->height; - cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50); + cx2341x_handler_set_50hz(&dev->cxhdl, + dev->core->tvnorm & V4L2_STD_625_50); cx2341x_handler_setup(&dev->cxhdl); } @@ -545,15 +578,18 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) dev->mailbox = retval; - retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ + /* ping */ + retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { dprintk(0, "ERROR: Firmware ping failed!\n"); return -1; } - retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); + retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, + 0, 1, &version); if (retval < 0) { - dprintk(0, "ERROR: Firmware get encoder version failed!\n"); + dprintk(0, + "ERROR: Firmware get encoder version failed!\n"); return -1; } dprintk(0, "Firmware version is 0x%08x\n", version); @@ -567,13 +603,11 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) blackbird_codec_settings(dev); blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, - BLACKBIRD_FIELD1_SAA7115, - BLACKBIRD_FIELD2_SAA7115 - ); + BLACKBIRD_FIELD1_SAA7115, BLACKBIRD_FIELD2_SAA7115); blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, - BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); return 0; } @@ -611,9 +645,7 @@ static int blackbird_start_codec(struct cx8802_dev *dev) /* start capturing to the host interface */ blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, - BLACKBIRD_MPEG_CAPTURE, - BLACKBIRD_RAW_BITS_NONE - ); + BLACKBIRD_MPEG_CAPTURE, BLACKBIRD_RAW_BITS_NONE); return 0; } @@ -621,10 +653,9 @@ static int blackbird_start_codec(struct cx8802_dev *dev) static int blackbird_stop_codec(struct cx8802_dev *dev) { blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - BLACKBIRD_END_NOW, - BLACKBIRD_MPEG_CAPTURE, - BLACKBIRD_RAW_BITS_NONE - ); + BLACKBIRD_END_NOW, + BLACKBIRD_MPEG_CAPTURE, + BLACKBIRD_RAW_BITS_NONE); cx2341x_handler_set_busy(&dev->cxhdl, 0); @@ -634,8 +665,8 @@ static int blackbird_stop_codec(struct cx8802_dev *dev) /* ------------------------------------------------------------------ */ static int queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) { struct cx8802_dev *dev = q->drv_priv; @@ -695,7 +726,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) err = drv->request_acquire(drv); if (err != 0) { - dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__, err); + dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__, + err); goto fail; } @@ -766,7 +798,7 @@ static const struct vb2_ops blackbird_qops = { /* ------------------------------------------------------------------ */ static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -778,7 +810,7 @@ static int vidioc_querycap(struct file *file, void *priv, } static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) + struct v4l2_fmtdesc *f) { if (f->index != 0) return -EINVAL; @@ -790,7 +822,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -806,7 +838,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -846,7 +878,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -860,14 +892,15 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, core->width = f->fmt.pix.width; core->height = f->fmt.pix.height; core->field = f->fmt.pix.field; - cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); + cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, + f->fmt.pix.field); blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - f->fmt.pix.height, f->fmt.pix.width); + f->fmt.pix.height, f->fmt.pix.width); return 0; } static int vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -883,8 +916,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, cx88_set_freq(core, f); blackbird_initialize_codec(dev); - cx88_set_scale(core, core->width, core->height, - core->field); + cx88_set_scale(core, core->width, core->height, core->field); if (streaming) blackbird_start_codec(dev); return 0; @@ -903,7 +935,7 @@ static int vidioc_log_status(struct file *file, void *priv) } static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) + struct v4l2_input *i) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -912,7 +944,7 @@ static int vidioc_enum_input(struct file *file, void *priv, } static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -944,7 +976,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) if (i >= 4) return -EINVAL; - if (0 == INPUT(i).type) + if (!INPUT(i).type) return -EINVAL; cx88_newstation(core); @@ -953,7 +985,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) } static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) + struct v4l2_tuner *t) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -971,12 +1003,12 @@ static int vidioc_g_tuner(struct file *file, void *priv, cx88_get_stereo(core, t); reg = cx_read(MO_DEVICE_STATUS); - t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; + t->signal = (reg & (1 << 5)) ? 0xffff : 0x0000; return 0; } static int vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) + const struct v4l2_tuner *t) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1008,7 +1040,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) } static const struct v4l2_file_operations mpeg_fops = { - .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, @@ -1061,7 +1092,9 @@ static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv) switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: - /* By default, core setup will leave the cx22702 out of reset, on the bus. + /* + * By default, core setup will leave the cx22702 out of reset, + * on the bus. * We left the hardware on power up with the cx22702 active. * We're being given access to re-arrange the GPIOs. * Take the bus off the cx22702 and put the cx23416 on it. diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 269179142cd8..cdfbde277b8b 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -51,7 +51,6 @@ MODULE_PARM_DESC(disable_ir, "Disable IR support"); __func__, ##arg); \ } while (0) - /* ------------------------------------------------------------------ */ /* board config info */ @@ -278,7 +277,6 @@ static const struct cx88_board cx88_boards[] = { .gpio2 = 0x0035e700, .gpio3 = 0x02000000, }, { - .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0x0035c700, @@ -492,22 +490,22 @@ static const struct cx88_board cx88_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, /* - GPIO[0] resets DT3302 DTV receiver - 0 - reset asserted - 1 - normal operation - GPIO[1] mutes analog audio output connector - 0 - enable selected source - 1 - mute - GPIO[2] selects source for analog audio output connector - 0 - analog audio input connector on tab - 1 - analog DAC output from CX23881 chip - GPIO[3] selects RF input connector on tuner module - 0 - RF connector labeled CABLE - 1 - RF connector labeled ANT - GPIO[4] selects high RF for QAM256 mode - 0 - normal RF - 1 - high RF - */ + * GPIO[0] resets DT3302 DTV receiver + * 0 - reset asserted + * 1 - normal operation + * GPIO[1] mutes analog audio output connector + * 0 - enable selected source + * 1 - mute + * GPIO[2] selects source for analog audio output connector + * 0 - analog audio input connector on tab + * 1 - analog DAC output from CX23881 chip + * GPIO[3] selects RF input connector on tuner module + * 0 - RF connector labeled CABLE + * 1 - RF connector labeled ANT + * GPIO[4] selects high RF for QAM256 mode + * 0 - normal RF + * 1 - high RF + */ .input = { { .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -730,7 +728,10 @@ static const struct cx88_board cx88_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - /* Some variants use a tda9874 and so need the tvaudio module. */ + /* + * Some variants use a tda9874 and so need the + * tvaudio module. + */ .audio_chip = CX88_AUDIO_TVAUDIO, .input = { { .type = CX88_VMUX_TELEVISION, @@ -1196,8 +1197,10 @@ static const struct cx88_board cx88_boards[] = { .mpeg = CX88_MPEG_DVB, }, [CX88_BOARD_KWORLD_MCE200_DELUXE] = { - /* FIXME: tested TV input only, disabled composite, - svideo and radio until they can be tested also. */ + /* + * FIXME: tested TV input only, disabled composite, + * svideo and radio until they can be tested also. + */ .name = "Kworld MCE 200 Deluxe", .tuner_type = TUNER_TENA_9533_DI, .radio_type = UNSET, @@ -1708,16 +1711,24 @@ static const struct cx88_board cx88_boards[] = { }, }, [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { - .name = "PowerColor RA330", /* Long names may confuse LIRC. */ + /* Long names may confuse LIRC. */ + .name = "PowerColor RA330", .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, .input = { { + /* + * Due to the way the cx88 driver is written, + * there is no way to deactivate audio pass- + * through without this entry. Furthermore, if + * the TV mux entry is first, you get audio + * from the tuner on boot for a little while. + */ .type = CX88_VMUX_DEBUG, - .vmux = 3, /* Due to the way the cx88 driver is written, */ - .gpio0 = 0x00ff, /* there is no way to deactivate audio pass- */ - .gpio1 = 0xf39d, /* through without this entry. Furthermore, if */ - .gpio3 = 0x0000, /* the TV mux entry is first, you get audio */ - }, { /* from the tuner on boot for a little while. */ + .vmux = 3, + .gpio0 = 0x00ff, + .gpio1 = 0xf39d, + .gpio3 = 0x0000, + }, { .type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0x00ff, @@ -1870,11 +1881,12 @@ static const struct cx88_board cx88_boards[] = { .gpio2 = 0x0cf7, }, }, - /* Both radio, analog and ATSC work with this board. - However, for analog to work, s5h1409 gate should be open, - otherwise, tuner-xc3028 won't be detected. - A proper fix require using the newer i2c methods to add - tuner-xc3028 without doing an i2c probe. + /* + * Both radio, analog and ATSC work with this board. + * However, for analog to work, s5h1409 gate should be open, + * otherwise, tuner-xc3028 won't be detected. + * A proper fix require using the newer i2c methods to add + * tuner-xc3028 without doing an i2c probe. */ [CX88_BOARD_KWORLD_ATSC_120] = { .name = "Kworld PlusTV HD PCI 120 (ATSC 120)", @@ -2808,9 +2820,9 @@ static const struct cx88_subid cx88_subids[] = { }, }; -/* ----------------------------------------------------------------------- */ -/* some leadtek specific stuff */ - +/* + * some leadtek specific stuff + */ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) { if (eeprom_data[4] != 0x7d || @@ -2849,8 +2861,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) core->model = tv.model; /* Make sure we support the board model */ - switch (tv.model) - { + switch (tv.model) { case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */ case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */ case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */ @@ -2898,8 +2909,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) pr_info("hauppauge eeprom: model=%d\n", tv.model); } -/* ----------------------------------------------------------------------- */ -/* some GDI (was: Modular Technology) specific stuff */ +/* + * some GDI (was: Modular Technology) specific stuff + */ static const struct { int id; @@ -2907,33 +2919,33 @@ static const struct { const char *name; } gdi_tuner[] = { [0x01] = { .id = UNSET, - .name = "NTSC_M" }, + .name = "NTSC_M" }, [0x02] = { .id = UNSET, - .name = "PAL_B" }, + .name = "PAL_B" }, [0x03] = { .id = UNSET, - .name = "PAL_I" }, + .name = "PAL_I" }, [0x04] = { .id = UNSET, - .name = "PAL_D" }, + .name = "PAL_D" }, [0x05] = { .id = UNSET, - .name = "SECAM" }, + .name = "SECAM" }, [0x10] = { .id = UNSET, - .fm = 1, - .name = "TEMIC_4049" }, + .fm = 1, + .name = "TEMIC_4049" }, [0x11] = { .id = TUNER_TEMIC_4136FY5, - .name = "TEMIC_4136" }, + .name = "TEMIC_4136" }, [0x12] = { .id = UNSET, - .name = "TEMIC_4146" }, + .name = "TEMIC_4146" }, [0x20] = { .id = TUNER_PHILIPS_FQ1216ME, - .fm = 1, - .name = "PHILIPS_FQ1216_MK3" }, + .fm = 1, + .name = "PHILIPS_FQ1216_MK3" }, [0x21] = { .id = UNSET, .fm = 1, - .name = "PHILIPS_FQ1236_MK3" }, + .name = "PHILIPS_FQ1236_MK3" }, [0x22] = { .id = UNSET, - .name = "PHILIPS_FI1236_MK3" }, + .name = "PHILIPS_FI1236_MK3" }, [0x23] = { .id = UNSET, - .name = "PHILIPS_FI1216_MK3" }, + .name = "PHILIPS_FI1216_MK3" }, }; static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) @@ -2942,15 +2954,16 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data) ? gdi_tuner[eeprom_data[0x0d]].name : NULL; pr_info("GDI: tuner=%s\n", name ? name : "unknown"); - if (name == NULL) + if (!name) return; core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ? CX88_RADIO : 0; } -/* ------------------------------------------------------------------- */ -/* some Divco specific stuff */ +/* + * some Divco specific stuff + */ static int cx88_dvico_xc2028_callback(struct cx88_core *core, int command, int arg) { @@ -2979,9 +2992,9 @@ static int cx88_dvico_xc2028_callback(struct cx88_core *core, return 0; } - -/* ----------------------------------------------------------------------- */ -/* some Geniatech specific stuff */ +/* + * some Geniatech specific stuff + */ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core, int command, int mode) @@ -3044,8 +3057,9 @@ static int cx88_xc4000_winfast2000h_plus_callback(struct cx88_core *core, return -EINVAL; } -/* ------------------------------------------------------------------- */ -/* some Divco specific stuff */ +/* + * some Divco specific stuff + */ static int cx88_pv_8000gt_callback(struct cx88_core *core, int command, int arg) { @@ -3064,8 +3078,9 @@ static int cx88_pv_8000gt_callback(struct cx88_core *core, return 0; } -/* ----------------------------------------------------------------------- */ -/* some DViCO specific stuff */ +/* + * some DViCO specific stuff + */ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) { @@ -3161,11 +3176,11 @@ static int cx88_xc4000_tuner_callback(struct cx88_core *core, return -EINVAL; } -/* ----------------------------------------------------------------------- */ -/* Tuner callback function. Currently only needed for the Pinnacle * - * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both * - * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */ - +/* + * Tuner callback function. Currently only needed for the Pinnacle + * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both + * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) + */ static int cx88_xc5000_tuner_callback(struct cx88_core *core, int command, int arg) { @@ -3173,38 +3188,38 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core, case CX88_BOARD_PINNACLE_PCTV_HD_800i: if (command == 0) { /* This is the reset command from xc5000 */ - /* djh - According to the engineer at PCTV Systems, - the xc5000 reset pin is supposed to be on GPIO12. - However, despite three nights of effort, pulling - that GPIO low didn't reset the xc5000. While - pulling MO_SRST_IO low does reset the xc5000, this - also resets in the s5h1409 being reset as well. - This causes tuning to always fail since the internal - state of the s5h1409 does not match the driver's - state. Given that the only two conditions in which - the driver performs a reset is during firmware load - and powering down the chip, I am taking out the - reset. We know that the chip is being reset - when the cx88 comes online, and not being able to - do power management for this board is worse than - not having any tuning at all. */ + /* + * djh - According to the engineer at PCTV Systems, + * the xc5000 reset pin is supposed to be on GPIO12. + * However, despite three nights of effort, pulling + * that GPIO low didn't reset the xc5000. While + * pulling MO_SRST_IO low does reset the xc5000, this + * also resets in the s5h1409 being reset as well. + * This causes tuning to always fail since the internal + * state of the s5h1409 does not match the driver's + * state. Given that the only two conditions in which + * the driver performs a reset is during firmware load + * and powering down the chip, I am taking out the + * reset. We know that the chip is being reset + * when the cx88 comes online, and not being able to + * do power management for this board is worse than + * not having any tuning at all. + */ return 0; - } else { - dprintk(1, "xc5000: unknown tuner callback command.\n"); - return -EINVAL; } - break; + + dprintk(1, "xc5000: unknown tuner callback command.\n"); + return -EINVAL; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: if (command == 0) { /* This is the reset command from xc5000 */ cx_clear(MO_GP0_IO, 0x00000010); - msleep(10); + usleep_range(10000, 20000); cx_set(MO_GP0_IO, 0x00000010); return 0; - } else { - dprintk(1, "xc5000: unknown tuner callback command.\n"); - return -EINVAL; } - break; + + dprintk(1, "xc5000: unknown tuner callback command.\n"); + return -EINVAL; } return 0; /* Should never be here */ } @@ -3230,15 +3245,15 @@ int cx88_tuner_callback(void *priv, int component, int command, int arg) return -EINVAL; switch (core->board.tuner_type) { - case TUNER_XC2028: - dprintk(1, "Calling XC2028/3028 callback\n"); - return cx88_xc2028_tuner_callback(core, command, arg); - case TUNER_XC4000: - dprintk(1, "Calling XC4000 callback\n"); - return cx88_xc4000_tuner_callback(core, command, arg); - case TUNER_XC5000: - dprintk(1, "Calling XC5000 callback\n"); - return cx88_xc5000_tuner_callback(core, command, arg); + case TUNER_XC2028: + dprintk(1, "Calling XC2028/3028 callback\n"); + return cx88_xc2028_tuner_callback(core, command, arg); + case TUNER_XC4000: + dprintk(1, "Calling XC4000 callback\n"); + return cx88_xc4000_tuner_callback(core, command, arg); + case TUNER_XC5000: + dprintk(1, "Calling XC5000 callback\n"); + return cx88_xc5000_tuner_callback(core, command, arg); } pr_err("Error: Calling callback for tuner %d\n", core->board.tuner_type); @@ -3252,8 +3267,7 @@ static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) { int i; - if (0 == pci->subsystem_vendor && - 0 == pci->subsystem_device) { + if (!pci->subsystem_vendor && !pci->subsystem_device) { pr_err("Your board has no valid PCI Subsystem ID and thus can't\n"); pr_err("be autodetected. Please pass card= insmod option to\n"); pr_err("workaround that. Redirect complaints to the vendor of\n"); @@ -3274,7 +3288,9 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* - * Bring the 702 demod up before i2c scanning/attach or devices are hidden + * Bring the 702 demod up before i2c scanning/attach or + * devices are hidden. + * * We leave here with the 702 on the bus * * "reset the IR receiver on GPIO[3]" @@ -3295,7 +3311,7 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) cx_write(MO_GP2_IO, 0xef5); mdelay(50); cx_write(MO_GP2_IO, 0xcf7); - msleep(10); + usleep_range(10000, 20000); break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: @@ -3331,7 +3347,7 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) case CX88_BOARD_TWINHAN_VP1027_DVBS: cx_write(MO_GP0_IO, 0x00003230); cx_write(MO_GP0_IO, 0x00003210); - msleep(1); + usleep_range(10000, 20000); cx_write(MO_GP0_IO, 0x00001230); break; } @@ -3362,11 +3378,13 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) ctl->demod = XC3028_FE_OREN538; break; case CX88_BOARD_GENIATECH_X8000_MT: - /* FIXME: For this board, the xc3028 never recovers after being - powered down (the reset GPIO probably is not set properly). - We don't have access to the hardware so we cannot determine - which GPIO is used for xc3028, so just disable power xc3028 - power management for now */ + /* + * FIXME: For this board, the xc3028 never recovers after being + * powered down (the reset GPIO probably is not set properly). + * We don't have access to the hardware so we cannot determine + * which GPIO is used for xc3028, so just disable power xc3028 + * power management for now + */ ctl->disable_power_mgmt = 1; break; case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: @@ -3396,7 +3414,7 @@ static void cx88_card_setup(struct cx88_core *core) memset(&tun_setup, 0, sizeof(tun_setup)); - if (core->i2c_rc == 0) { + if (!core->i2c_rc) { core->i2c_client.addr = 0xa0 >> 1; tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom)); } @@ -3404,17 +3422,17 @@ static void cx88_card_setup(struct cx88_core *core) switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE: case CX88_BOARD_HAUPPAUGE_ROSLYN: - if (core->i2c_rc == 0) - hauppauge_eeprom(core, eeprom+8); + if (!core->i2c_rc) + hauppauge_eeprom(core, eeprom + 8); break; case CX88_BOARD_GDI: - if (core->i2c_rc == 0) + if (!core->i2c_rc) gdi_eeprom(core, eeprom); break; case CX88_BOARD_LEADTEK_PVR2000: case CX88_BOARD_WINFAST_DV2000: case CX88_BOARD_WINFAST2000XP_EXPERT: - if (core->i2c_rc == 0) + if (!core->i2c_rc) leadtek_eeprom(core, eeprom); break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: @@ -3427,7 +3445,7 @@ static void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_HVR4000: case CX88_BOARD_HAUPPAUGE_HVR4000LITE: case CX88_BOARD_HAUPPAUGE_IRONLY: - if (core->i2c_rc == 0) + if (!core->i2c_rc) hauppauge_eeprom(core, eeprom); break; case CX88_BOARD_KWORLD_DVBS_100: @@ -3438,7 +3456,7 @@ static void cx88_card_setup(struct cx88_core *core) /* GPIO0:0 is hooked to demod reset */ /* GPIO0:4 is hooked to xc3028 reset */ cx_write(MO_GP0_IO, 0x00111100); - msleep(1); + usleep_range(10000, 20000); cx_write(MO_GP0_IO, 0x00111111); break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: @@ -3454,9 +3472,9 @@ static void cx88_card_setup(struct cx88_core *core) /* GPIO0:0 is hooked to mt352 reset pin */ cx_set(MO_GP0_IO, 0x00000101); cx_clear(MO_GP0_IO, 0x00000001); - msleep(1); + usleep_range(10000, 20000); cx_set(MO_GP0_IO, 0x00000101); - if (0 == core->i2c_rc && + if (!core->i2c_rc && core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID) dvico_fusionhdtv_hybrid_init(core); break; @@ -3465,7 +3483,7 @@ static void cx88_card_setup(struct cx88_core *core) cx_set(MO_GP0_IO, 0x00000707); cx_set(MO_GP2_IO, 0x00000101); cx_clear(MO_GP2_IO, 0x00000001); - msleep(1); + usleep_range(10000, 20000); cx_clear(MO_GP0_IO, 0x00000007); cx_set(MO_GP2_IO, 0x00000101); break; @@ -3473,7 +3491,7 @@ static void cx88_card_setup(struct cx88_core *core) cx_write(MO_GP0_IO, 0x00080808); break; case CX88_BOARD_ATI_HDTVWONDER: - if (core->i2c_rc == 0) { + if (!core->i2c_rc) { /* enable tuner */ int i; static const u8 buffer[][2] = { @@ -3486,8 +3504,8 @@ static void cx88_card_setup(struct cx88_core *core) core->i2c_client.addr = 0x0a; for (i = 0; i < ARRAY_SIZE(buffer); i++) - if (2 != i2c_master_send(&core->i2c_client, - buffer[i], 2)) + if (i2c_master_send(&core->i2c_client, + buffer[i], 2) != 2) pr_warn("Unable to enable tuner(%i).\n", i); } @@ -3523,7 +3541,7 @@ static void cx88_card_setup(struct cx88_core *core) cx_write(MO_GP0_IO, 0x8000); msleep(100); cx_write(MO_SRST_IO, 0); - msleep(10); + usleep_range(10000, 20000); cx_write(MO_GP0_IO, 0x8080); msleep(100); cx_write(MO_SRST_IO, 1); @@ -3531,9 +3549,8 @@ static void cx88_card_setup(struct cx88_core *core) break; } /*end switch() */ - /* Setup tuners */ - if ((core->board.radio_type != UNSET)) { + if (core->board.radio_type != UNSET) { tun_setup.mode_mask = T_RADIO; tun_setup.type = core->board.radio_type; tun_setup.addr = core->board.radio_addr; @@ -3621,8 +3638,7 @@ static int cx88_pci_quirks(const char *name, struct pci_dev *pci) pci_write_config_byte(pci, CX88X_DEVCTRL, value); } if (lat != UNSET) { - pr_info("setting pci latency timer to %d\n", - latency); + pr_info("setting pci latency timer to %d\n", latency); pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency); } return 0; @@ -3641,15 +3657,17 @@ int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci) return -EBUSY; } -/* Allocate and initialize the cx88 core struct. One should hold the - * devlist mutex before calling this. */ +/* + * Allocate and initialize the cx88 core struct. One should hold the + * devlist mutex before calling this. + */ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) { struct cx88_core *core; int i; core = kzalloc(sizeof(*core), GFP_KERNEL); - if (core == NULL) + if (!core) return NULL; atomic_inc(&core->refcount); @@ -3701,9 +3719,9 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) pci_resource_len(pci, 0)); core->bmmio = (u8 __iomem *)core->lmmio; - if (core->lmmio == NULL) { + if (!core->lmmio) { release_mem_region(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + pci_resource_len(pci, 0)); v4l2_ctrl_handler_free(&core->video_hdl); v4l2_ctrl_handler_free(&core->audio_hdl); v4l2_device_unregister(&core->v4l2_dev); @@ -3715,7 +3733,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) core->boardnr = UNSET; if (card[core->nr] < ARRAY_SIZE(cx88_boards)) core->boardnr = card[core->nr]; - for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++) + for (i = 0; core->boardnr == UNSET && i < ARRAY_SIZE(cx88_subids); i++) if (pci->subsystem_vendor == cx88_subids[i].subvendor && pci->subsystem_device == cx88_subids[i].subdevice) core->boardnr = cx88_subids[i].card; @@ -3750,9 +3768,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) /* load tuner module, if needed */ if (core->board.tuner_type != UNSET) { - /* Ignore 0x6b and 0x6f on cx88 boards. + /* + * Ignore 0x6b and 0x6f on cx88 boards. * FusionHDTV5 RT Gold has an ir receiver at 0x6b - * and an RTC at 0x6f which can get corrupted if probed. */ + * and an RTC at 0x6f which can get corrupted if probed. + */ static const unsigned short tv_addrs[] = { 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, @@ -3761,24 +3781,27 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) }; int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT); - /* I don't trust the radio_type as is stored in the card - definitions, so we just probe for it. - The radio_type is sometimes missing, or set to UNSET but - later code configures a tea5767. + /* + * I don't trust the radio_type as is stored in the card + * definitions, so we just probe for it. + * The radio_type is sometimes missing, or set to UNSET but + * later code configures a tea5767. */ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); + "tuner", 0, + v4l2_i2c_tuner_addrs(ADDRS_RADIO)); if (has_demod) v4l2_i2c_new_subdev(&core->v4l2_dev, - &core->i2c_adap, "tuner", + &core->i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (core->board.tuner_addr == ADDR_UNSET) { v4l2_i2c_new_subdev(&core->v4l2_dev, - &core->i2c_adap, "tuner", + &core->i2c_adap, "tuner", 0, has_demod ? tv_addrs + 4 : tv_addrs); } else { v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - "tuner", core->board.tuner_addr, NULL); + "tuner", core->board.tuner_addr, + NULL); } } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 33719f0b06a5..973a9cd4c635 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -72,12 +72,14 @@ static DEFINE_MUTEX(devlist); #define NO_SYNC_LINE (-1U) -/* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be - generated _after_ lpi lines are transferred. */ +/* + * @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be + * generated _after_ lpi lines are transferred. + */ static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist, - unsigned int offset, u32 sync_line, - unsigned int bpl, unsigned int padding, - unsigned int lines, unsigned int lpi, bool jump) + unsigned int offset, u32 sync_line, + unsigned int bpl, unsigned int padding, + unsigned int lines, unsigned int lpi, bool jump) { struct scatterlist *sg; unsigned int line, todo, sol; @@ -102,28 +104,29 @@ static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist, sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; else sol = RISC_SOL; - if (bpl <= sg_dma_len(sg)-offset) { + if (bpl <= sg_dma_len(sg) - offset) { /* fits into current chunk */ - *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); + *(rp++) = cpu_to_le32(RISC_WRITE | sol | + RISC_EOL | bpl); + *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); offset += bpl; } else { /* scanline needs to be split */ todo = bpl; - *(rp++) = cpu_to_le32(RISC_WRITE|sol| - (sg_dma_len(sg)-offset)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - todo -= (sg_dma_len(sg)-offset); + *(rp++) = cpu_to_le32(RISC_WRITE | sol | + (sg_dma_len(sg) - offset)); + *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); + todo -= (sg_dma_len(sg) - offset); offset = 0; sg = sg_next(sg); while (todo > sg_dma_len(sg)) { - *(rp++) = cpu_to_le32(RISC_WRITE| - sg_dma_len(sg)); + *(rp++) = cpu_to_le32(RISC_WRITE | + sg_dma_len(sg)); *(rp++) = cpu_to_le32(sg_dma_address(sg)); todo -= sg_dma_len(sg); sg = sg_next(sg); } - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); + *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo); *(rp++) = cpu_to_le32(sg_dma_address(sg)); offset += todo; } @@ -147,16 +150,19 @@ int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, if (bottom_offset != UNSET) fields++; - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); + /* + * estimate risc mem: worst case is one write per page border + + * one write per scan line + syncs + jump (all 2 dwords). Padding + * can cause next bpl to start close to a page border. First DMA + * region may be smaller than PAGE_SIZE + */ + instructions = fields * (1 + ((bpl + padding) * lines) / + PAGE_SIZE + lines); instructions += 4; risc->size = instructions * 8; risc->dma = 0; risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); - if (risc->cpu == NULL) + if (!risc->cpu) return -ENOMEM; /* write risc instructions */ @@ -166,13 +172,15 @@ int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, bpl, padding, lines, 0, true); if (bottom_offset != UNSET) rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200, - bpl, padding, lines, 0, top_offset == UNSET); + bpl, padding, lines, 0, + top_offset == UNSET); /* save pointer to jmp instruction address */ risc->jmp = rp; WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); return 0; } +EXPORT_SYMBOL(cx88_risc_buffer); int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, @@ -181,32 +189,38 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, u32 instructions; __le32 *rp; - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Here - there is no padding and no sync. First DMA region may be smaller - than PAGE_SIZE */ + /* + * estimate risc mem: worst case is one write per page border + + * one write per scan line + syncs + jump (all 2 dwords). Here + * there is no padding and no sync. First DMA region may be smaller + * than PAGE_SIZE + */ instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; instructions += 3; risc->size = instructions * 8; risc->dma = 0; risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); - if (risc->cpu == NULL) + if (!risc->cpu) return -ENOMEM; /* write risc instructions */ rp = risc->cpu; - rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi, !lpi); + rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, + lines, lpi, !lpi); /* save pointer to jmp instruction address */ risc->jmp = rp; WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); return 0; } +EXPORT_SYMBOL(cx88_risc_databuffer); -/* ------------------------------------------------------------------ */ -/* our SRAM memory layout */ +/* + * our SRAM memory layout + */ -/* we are going to put all thr risc programs into host memory, so we +/* + * we are going to put all thr risc programs into host memory, so we * can use the whole SDRAM for the DMA fifos. To simplify things, we * use a static memory layout. That surely will waste memory in case * we don't use all DMA channels at the same time (which will be the @@ -330,6 +344,7 @@ const struct sram_channel cx88_sram_channels[] = { .cnt2_reg = MO_DMA27_CNT2, }, }; +EXPORT_SYMBOL(cx88_sram_channels); int cx88_sram_channel_setup(struct cx88_core *core, const struct sram_channel *ch, @@ -347,12 +362,12 @@ int cx88_sram_channel_setup(struct cx88_core *core, /* write CDT */ for (i = 0; i < lines; i++) - cx_write(cdt + 16*i, ch->fifo_start + bpl*i); + cx_write(cdt + 16 * i, ch->fifo_start + bpl * i); /* write CMDS */ cx_write(ch->cmds_start + 0, risc); cx_write(ch->cmds_start + 4, cdt); - cx_write(ch->cmds_start + 8, (lines*16) >> 3); + cx_write(ch->cmds_start + 8, (lines * 16) >> 3); cx_write(ch->cmds_start + 12, ch->ctrl_start); cx_write(ch->cmds_start + 16, 64 >> 2); for (i = 20; i < 64; i += 4) @@ -362,11 +377,12 @@ int cx88_sram_channel_setup(struct cx88_core *core, cx_write(ch->ptr1_reg, ch->fifo_start); cx_write(ch->ptr2_reg, cdt); cx_write(ch->cnt1_reg, (bpl >> 3) - 1); - cx_write(ch->cnt2_reg, (lines*16) >> 3); + cx_write(ch->cnt2_reg, (lines * 16) >> 3); dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines); return 0; } +EXPORT_SYMBOL(cx88_sram_channel_setup); /* ------------------------------------------------------------------ */ /* debug helper code */ @@ -401,15 +417,14 @@ static int cx88_risc_decode(u32 risc) int i; dprintk0("0x%08x [ %s", risc, - instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); - for (i = ARRAY_SIZE(bits)-1; i >= 0; i--) + instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); + for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) if (risc & (1 << (i + 12))) pr_cont(" %s", bits[i]); pr_cont(" count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; } - void cx88_sram_channel_dump(struct cx88_core *core, const struct sram_channel *ch) { @@ -429,14 +444,12 @@ void cx88_sram_channel_dump(struct cx88_core *core, u32 risc; unsigned int i, j, n; - dprintk0("%s - dma channel status dump\n", - ch->name); + dprintk0("%s - dma channel status dump\n", ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) dprintk0(" cmds: %-12s: 0x%08x\n", - name[i], - cx_read(ch->cmds_start + 4*i)); + name[i], cx_read(ch->cmds_start + 4 * i)); for (n = 1, i = 0; i < 4; i++) { - risc = cx_read(ch->cmds_start + 4 * (i+11)); + risc = cx_read(ch->cmds_start + 4 * (i + 11)); pr_cont(" risc%d: ", i); if (--n) pr_cont("0x%08x [ arg #%d ]\n", risc, n); @@ -448,21 +461,22 @@ void cx88_sram_channel_dump(struct cx88_core *core, dprintk0(" iq %x: ", i); n = cx88_risc_decode(risc); for (j = 1; j < n; j++) { - risc = cx_read(ch->ctrl_start + 4 * (i+j)); + risc = cx_read(ch->ctrl_start + 4 * (i + j)); pr_cont(" iq %x: 0x%08x [ arg #%d ]\n", i + j, risc, j); } } dprintk0("fifo: 0x%08x -> 0x%x\n", - ch->fifo_start, ch->fifo_start+ch->fifo_size); + ch->fifo_start, ch->fifo_start + ch->fifo_size); dprintk0("ctrl: 0x%08x -> 0x%x\n", - ch->ctrl_start, ch->ctrl_start + 6 * 16); + ch->ctrl_start, ch->ctrl_start + 6 * 16); dprintk0(" ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg)); dprintk0(" ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg)); dprintk0(" cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg)); dprintk0(" cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg)); } +EXPORT_SYMBOL(cx88_sram_channel_dump); static const char *cx88_pci_irqs[32] = { "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", @@ -490,6 +504,7 @@ void cx88_print_irqbits(const char *tag, const char *strings[], } pr_cont("\n"); } +EXPORT_SYMBOL(cx88_print_irqbits); /* ------------------------------------------------------------------ */ @@ -507,6 +522,7 @@ int cx88_core_irq(struct cx88_core *core, u32 status) status, core->pci_irqmask); return handled; } +EXPORT_SYMBOL(cx88_core_irq); void cx88_wakeup(struct cx88_core *core, struct cx88_dmaqueue *q, u32 count) @@ -521,6 +537,7 @@ void cx88_wakeup(struct cx88_core *core, list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } +EXPORT_SYMBOL(cx88_wakeup); void cx88_shutdown(struct cx88_core *core) { @@ -545,6 +562,7 @@ void cx88_shutdown(struct cx88_core *core) /* stop capturing */ cx_write(VID_CAPTURE_CONTROL, 0); } +EXPORT_SYMBOL(cx88_shutdown); int cx88_reset(struct cx88_core *core) { @@ -560,13 +578,15 @@ int cx88_reset(struct cx88_core *core) msleep(100); /* init sram */ - cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0); + cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], + 720 * 4, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); - cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); + cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], + 188 * 4, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0); /* misc init ... */ @@ -594,11 +614,12 @@ int cx88_reset(struct cx88_core *core) /* Reset on-board parts */ cx_write(MO_SRST_IO, 0); - msleep(10); + usleep_range(10000, 20000); cx_write(MO_SRST_IO, 1); return 0; } +EXPORT_SYMBOL(cx88_reset); /* ------------------------------------------------------------------ */ @@ -628,10 +649,11 @@ static inline unsigned int norm_fsc8(v4l2_std_id norm) if (norm & V4L2_STD_NTSC) // All NTSC/M and variants return 28636360; // 3.57954545 MHz +/- 10 Hz - /* SECAM have also different sub carrier for chroma, - but step_db and step_dr, at cx88_set_tvnorm already handles that. - - The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N + /* + * SECAM have also different sub carrier for chroma, + * but step_db and step_dr, at cx88_set_tvnorm already handles that. + * + * The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N */ return 35468950; // 4.43361875 MHz +/- 5 Hz @@ -639,13 +661,12 @@ static inline unsigned int norm_fsc8(v4l2_std_id norm) static inline unsigned int norm_htotal(v4l2_std_id norm) { - - unsigned int fsc4 = norm_fsc8(norm)/2; + unsigned int fsc4 = norm_fsc8(norm) / 2; /* returns 4*FSC / vtotal / frames per seconds */ return (norm & V4L2_STD_625_50) ? - ((fsc4+312)/625+12)/25 : - ((fsc4+262)/525*1001+15000)/30000; + ((fsc4 + 312) / 625 + 12) / 25 : + ((fsc4 + 262) / 525 * 1001 + 15000) / 30000; } static inline unsigned int norm_vbipack(v4l2_std_id norm) @@ -653,8 +674,8 @@ static inline unsigned int norm_vbipack(v4l2_std_id norm) return (norm & V4L2_STD_625_50) ? 511 : 400; } -int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, - enum v4l2_field field) +int cx88_set_scale(struct cx88_core *core, unsigned int width, + unsigned int height, enum v4l2_field field) { unsigned int swidth = norm_swidth(core->tvnorm); unsigned int sheight = norm_maxh(core->tvnorm); @@ -721,6 +742,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig return 0; } +EXPORT_SYMBOL(cx88_set_scale); static const u32 xtal = 28636363; @@ -749,13 +771,13 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) cx_write(MO_PLL_REG, reg); for (i = 0; i < 100; i++) { reg = cx_read(MO_DEVICE_STATUS); - if (reg & (1<<2)) { + if (reg & (1 << 2)) { dprintk(1, "pll locked [pre=%d,ofreq=%d]\n", prescale, ofreq); return 0; } dprintk(1, "pll not locked yet, waiting ...\n"); - msleep(10); + usleep_range(10000, 20000); } dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq); return -1; @@ -764,9 +786,9 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) int cx88_start_audio_dma(struct cx88_core *core) { /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ - int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; + int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4; - int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES; + int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size / AUD_RDS_LINES; /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ if (cx_read(MO_AUD_DMACNTRL) & 0x10) @@ -803,8 +825,8 @@ static int set_tvaudio(struct cx88_core *core) { v4l2_std_id norm = core->tvnorm; - if (CX88_VMUX_TELEVISION != INPUT(core->input).type && - CX88_VMUX_CABLE != INPUT(core->input).type) + if (INPUT(core->input).type != CX88_VMUX_TELEVISION && + INPUT(core->input).type != CX88_VMUX_CABLE) return 0; if (V4L2_STD_PAL_BG & norm) { @@ -819,7 +841,8 @@ static int set_tvaudio(struct cx88_core *core) } else if (V4L2_STD_SECAM_L & norm) { core->tvaudio = WW_L; - } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) { + } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & + norm) { core->tvaudio = WW_BG; } else if (V4L2_STD_SECAM_DK & norm) { @@ -844,15 +867,13 @@ static int set_tvaudio(struct cx88_core *core) /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */ /* - This should be needed only on cx88-alsa. It seems that some cx88 chips have - bugs and does require DMA enabled for it to work. + * This should be needed only on cx88-alsa. It seems that some cx88 chips have + * bugs and does require DMA enabled for it to work. */ cx88_start_audio_dma(core); return 0; } - - int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) { u32 fsc8; @@ -916,8 +937,10 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) dprintk(1, "set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f); - /* Chroma AGC must be disabled if SECAM is used, we enable it - by default on PAL and NTSC */ + /* + * Chroma AGC must be disabled if SECAM is used, we enable it + * by default on PAL and NTSC + */ cx_andor(MO_INPUT_FORMAT, 0x40f, norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400); @@ -952,7 +975,8 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) agcdelay = vdec_clock * 68 / 20000000 + 15; dprintk(1, "set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n", - (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay); + (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), + bdelay, agcdelay); cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay); // htotal @@ -966,7 +990,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes // the effective vbi offset ~244 samples, the same as the Bt8x8 - cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm)); + cx_write(MO_VBI_PACKET, (10 << 11) | norm_vbipack(norm)); // this is needed as well to set all tvnorm parameter cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED); @@ -977,12 +1001,16 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) // tell i2c chips call_all(core, video, s_std, norm); - /* The chroma_agc control should be inaccessible if the video format is SECAM */ + /* + * The chroma_agc control should be inaccessible + * if the video format is SECAM + */ v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM); // done return 0; } +EXPORT_SYMBOL(cx88_set_tvnorm); /* ------------------------------------------------------------------ */ @@ -1007,6 +1035,7 @@ void cx88_vdev_init(struct cx88_core *core, snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); } +EXPORT_SYMBOL(cx88_vdev_init); struct cx88_core *cx88_core_get(struct pci_dev *pci) { @@ -1029,7 +1058,7 @@ struct cx88_core *cx88_core_get(struct pci_dev *pci) } core = cx88_core_create(pci, cx88_devcount); - if (core != NULL) { + if (core) { cx88_devcount++; list_add_tail(&core->devlist, &cx88_devlist); } @@ -1037,6 +1066,7 @@ struct cx88_core *cx88_core_get(struct pci_dev *pci) mutex_unlock(&devlist); return core; } +EXPORT_SYMBOL(cx88_core_get); void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) { @@ -1062,29 +1092,4 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) v4l2_device_unregister(&core->v4l2_dev); kfree(core); } - -/* ------------------------------------------------------------------ */ - -EXPORT_SYMBOL(cx88_print_irqbits); - -EXPORT_SYMBOL(cx88_core_irq); -EXPORT_SYMBOL(cx88_wakeup); -EXPORT_SYMBOL(cx88_reset); -EXPORT_SYMBOL(cx88_shutdown); - -EXPORT_SYMBOL(cx88_risc_buffer); -EXPORT_SYMBOL(cx88_risc_databuffer); - -EXPORT_SYMBOL(cx88_sram_channels); -EXPORT_SYMBOL(cx88_sram_channel_setup); -EXPORT_SYMBOL(cx88_sram_channel_dump); - -EXPORT_SYMBOL(cx88_set_tvnorm); -EXPORT_SYMBOL(cx88_set_scale); - -EXPORT_SYMBOL(cx88_vdev_init); -EXPORT_SYMBOL(cx88_core_get); EXPORT_SYMBOL(cx88_core_put); - -EXPORT_SYMBOL(cx88_ir_start); -EXPORT_SYMBOL(cx88_ir_stop); diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index 235124e2a763..105029088120 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -31,18 +31,22 @@ #define baseband_freq(carrier, srate, tone) ((s32)( \ (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI)) -/* We calculate the baseband frequencies of the carrier and the pilot tones - * based on the the sampling rate of the audio rds fifo. */ +/* + * We calculate the baseband frequencies of the carrier and the pilot tones + * based on the the sampling rate of the audio rds fifo. + */ #define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0) #define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1) #define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5) -/* The frequencies below are from the reference driver. They probably need +/* + * The frequencies below are from the reference driver. They probably need * further adjustments, because they are not tested at all. You may even need * to play a bit with the registers of the chip to select the proper signal * for the input of the audio rds fifo, and measure it's sampling rate to - * calculate the proper baseband frequencies... */ + * calculate the proper baseband frequencies... + */ #define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0)) #define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0)) @@ -83,8 +87,10 @@ static s32 int_cos(u32 x) x = x % INT_PI; if (x > INT_PI / 2) return -int_cos(INT_PI / 2 - (x % (INT_PI / 2))); - /* Now x is between 0 and INT_PI/2. - * To calculate cos(x) we use it's Taylor polinom. */ + /* + * Now x is between 0 and INT_PI/2. + * To calculate cos(x) we use it's Taylor polinom. + */ t2 = x * x / 32768 / 2; t4 = t2 * x / 32768 * x / 32768 / 3 / 4; t6 = t4 * x / 32768 * x / 32768 / 5 / 6; @@ -95,8 +101,10 @@ static s32 int_cos(u32 x) static u32 int_goertzel(s16 x[], u32 N, u32 freq) { - /* We use the Goertzel algorithm to determine the power of the - * given frequency in the signal */ + /* + * We use the Goertzel algorithm to determine the power of the + * given frequency in the signal + */ s32 s_prev = 0; s32 s_prev2 = 0; s32 coeff = 2 * int_cos(freq); @@ -115,12 +123,14 @@ static u32 int_goertzel(s16 x[], u32 N, u32 freq) tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev - (s64)coeff * s_prev2 * s_prev / 32768; - /* XXX: N must be low enough so that N*N fits in s32. - * Else we need two divisions. */ + /* + * XXX: N must be low enough so that N*N fits in s32. + * Else we need two divisions. + */ divisor = N * N; do_div(tmp, divisor); - return (u32) tmp; + return (u32)tmp; } static u32 freq_magnitude(s16 x[], u32 N, u32 freq) @@ -187,7 +197,8 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) dual = freq_magnitude(x, N, dual_freq); noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END); - dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, noise=%d\n", + dprintk(1, + "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, noise=%d\n", carrier, stereo, dual, noise); if (stereo > dual) @@ -201,8 +212,10 @@ static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) (carrier < max(stereo, dual) * 6) && (carrier > 20 && carrier < 200) && (max(stereo, dual) > min(stereo, dual))) { - /* For EIAJ the carrier is always present, - so we probably don't need noise detection */ + /* + * For EIAJ the carrier is always present, + * so we probably don't need noise detection + */ return ret; } } else { @@ -243,7 +256,8 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) u32 current_address = cx_read(srch->ptr1_reg); u32 offset = (current_address - srch->fifo_start + bpl); - dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), sample_count=%d, aud_intstat=%08x\n", + dprintk(1, + "read RDS samples: current_address=%08x (offset=%08x), sample_count=%d, aud_intstat=%08x\n", current_address, current_address - srch->fifo_start, sample_count, cx_read(MO_AUD_INTSTAT)); @@ -308,9 +322,9 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) if (ret != UNSET) dprintk(1, "stereo/sap detection result:%s%s%s\n", - (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", - (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", - (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : ""); + (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", + (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", + (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : ""); return ret; } diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 5188f8f2d6dd..ddf90678df34 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -82,8 +82,8 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* ------------------------------------------------------------------ */ static int queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) { struct cx8802_dev *dev = q->drv_priv; @@ -445,7 +445,7 @@ static const struct nxt200x_config ati_hdtvwonder = { }; static int cx24123_set_ts_param(struct dvb_frontend *fe, - int is_punctured) + int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; @@ -684,7 +684,7 @@ static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) } static int cx24116_set_ts_param(struct dvb_frontend *fe, - int is_punctured) + int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; @@ -694,7 +694,7 @@ static int cx24116_set_ts_param(struct dvb_frontend *fe, } static int stv0900_set_ts_param(struct dvb_frontend *fe, - int is_punctured) + int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; @@ -711,10 +711,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe) /* Reset the part */ /* Put the cx24116 into reset */ cx_write(MO_SRST_IO, 0); - msleep(10); + usleep_range(10000, 20000); /* Take the cx24116 out of reset */ cx_write(MO_SRST_IO, 1); - msleep(10); + usleep_range(10000, 20000); return 0; } @@ -732,7 +732,7 @@ static const struct cx24116_config tevii_s460_config = { }; static int ds3000_set_ts_param(struct dvb_frontend *fe, - int is_punctured) + int is_punctured) { struct cx8802_dev *dev = fe->dvb->priv; @@ -812,8 +812,6 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev) return 0; } - - static const u8 samsung_smt_7020_inittab[] = { 0x01, 0x15, 0x02, 0x00, @@ -865,7 +863,6 @@ static const u8 samsung_smt_7020_inittab[] = { 0xff, 0xff, }; - static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -898,7 +895,7 @@ static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe) } static int samsung_smt_7020_set_tone(struct dvb_frontend *fe, - enum fe_sec_tone_mode tone) + enum fe_sec_tone_mode tone) { struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; @@ -953,7 +950,7 @@ static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe, } static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe, - u32 srate, u32 ratio) + u32 srate, u32 ratio) { u8 aclk = 0; u8 bclk = 0; @@ -987,7 +984,6 @@ static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe, return 0; } - static const struct stv0299_config samsung_stv0299_config = { .demod_address = 0x68, .inittab = samsung_smt_7020_inittab, @@ -1029,7 +1025,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, &core->i2c_adap, DVB_PLL_THOMSON_DTT759X)) @@ -1043,7 +1039,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_THOMSON_DTT7579)) @@ -1057,10 +1053,10 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3)) + &core->i2c_adap, 0x61, + TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } break; @@ -1068,10 +1064,10 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216MEX_MK3)) + &core->i2c_adap, 0x61, + TUNER_PHILIPS_FMD1216MEX_MK3)) goto frontend_detach; } break; @@ -1081,8 +1077,8 @@ static int dvb_register(struct cx8802_dev *dev) dev->frontends.gate = 2; /* DVB-S init */ fe0->dvb.frontend = dvb_attach(cx24123_attach, - &hauppauge_novas_config, - &dev->core->i2c_adap); + &hauppauge_novas_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, @@ -1096,8 +1092,8 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; /* DVB-T init */ fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); + &hauppauge_hvr_config, + &dev->core->i2c_adap); if (fe1->dvb.frontend) { fe1->dvb.frontend->id = 1; if (!dvb_attach(simple_tuner_attach, @@ -1111,7 +1107,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; @@ -1121,19 +1117,21 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: - /* The tin box says DEE1601, but it seems to be DTT7579 - * compatible, with a slightly different MT352 AGC gain. */ + /* + * The tin box says DEE1601, but it seems to be DTT7579 + * compatible, with a slightly different MT352 AGC gain. + */ fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; @@ -1143,7 +1141,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; @@ -1153,7 +1151,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_LG_Z201)) goto frontend_detach; @@ -1165,7 +1163,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61, NULL, DVB_PLL_UNKNOWN_1)) goto frontend_detach; @@ -1174,9 +1172,10 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) /* MT352 is on a secondary I2C bus made from some GPIO lines */ - fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, + fe0->dvb.frontend = dvb_attach(mt352_attach, + &dntv_live_dvbt_pro_config, &dev->vp3054->adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) @@ -1190,10 +1189,10 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x61, - TUNER_THOMSON_FE6600)) + &core->i2c_adap, 0x61, + TUNER_THOMSON_FE6600)) goto frontend_detach; } break; @@ -1201,7 +1200,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &core->i2c_adap); - if (fe0->dvb.frontend == NULL) + if (!fe0->dvb.frontend) fe0->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, &core->i2c_adap); @@ -1218,7 +1217,7 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_PCHDTV_HD3000: fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) @@ -1239,7 +1238,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_MICROTUNE_4042FI5)) @@ -1257,7 +1256,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) @@ -1275,13 +1274,13 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x43)) + &core->i2c_adap, 0x43)) goto frontend_detach; } break; @@ -1296,13 +1295,13 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x43)) + &core->i2c_adap, 0x43)) goto frontend_detach; } break; @@ -1310,7 +1309,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D)) @@ -1331,8 +1330,8 @@ static int dvb_register(struct cx8802_dev *dev) override_tone = false; if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, - &core->i2c_adap, 0x08, ISL6421_DCL, 0x00, - override_tone)) + &core->i2c_adap, 0x08, ISL6421_DCL, + 0x00, override_tone)) goto frontend_detach; } break; @@ -1358,7 +1357,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, &core->i2c_adap, &pinnacle_pctv_hd_800i_tuner_config)) @@ -1367,9 +1366,9 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &dvico_hdtv5_pci_nano_config, - &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + &dvico_hdtv5_pci_nano_config, + &core->i2c_adap); + if (fe0->dvb.frontend) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, @@ -1383,7 +1382,7 @@ static int dvb_register(struct cx8802_dev *dev) fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) + if (fe && fe->ops.tuner_ops.set_config) fe->ops.tuner_ops.set_config(fe, &ctl); } break; @@ -1436,7 +1435,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, &core->i2c_adap, &dvico_fusionhdtv7_tuner_config)) @@ -1449,8 +1448,8 @@ static int dvb_register(struct cx8802_dev *dev) dev->frontends.gate = 2; /* DVB-S/S2 Init */ fe0->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); + &hauppauge_hvr4000_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, @@ -1464,8 +1463,8 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; /* DVB-T Init */ fe1->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr_config, - &dev->core->i2c_adap); + &hauppauge_hvr_config, + &dev->core->i2c_adap); if (fe1->dvb.frontend) { fe1->dvb.frontend->id = 1; if (!dvb_attach(simple_tuner_attach, @@ -1477,8 +1476,8 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_HAUPPAUGE_HVR4000LITE: fe0->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); + &hauppauge_hvr4000_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, @@ -1493,7 +1492,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(stv0299_attach, &tevii_tuner_sharp_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_OPERA1)) goto frontend_detach; @@ -1504,8 +1503,9 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(stv0288_attach, &tevii_tuner_earda_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61, + if (fe0->dvb.frontend) { + if (!dvb_attach(stb6000_attach, + fe0->dvb.frontend, 0x61, &core->i2c_adap)) goto frontend_detach; core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; @@ -1517,16 +1517,16 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx24116_attach, &tevii_s460_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) + if (fe0->dvb.frontend) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; break; case CX88_BOARD_TEVII_S464: fe0->dvb.frontend = dvb_attach(ds3000_attach, &tevii_ds3000_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) { + if (fe0->dvb.frontend) { dvb_attach(ts2020_attach, fe0->dvb.frontend, - &tevii_ts2020_config, &core->i2c_adap); + &tevii_ts2020_config, &core->i2c_adap); fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; } @@ -1538,7 +1538,7 @@ static int dvb_register(struct cx8802_dev *dev) fe0->dvb.frontend = dvb_attach(cx24116_attach, &hauppauge_hvr4000_config, &core->i2c_adap); - if (fe0->dvb.frontend != NULL) + if (fe0->dvb.frontend) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; break; case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: @@ -1555,9 +1555,9 @@ static int dvb_register(struct cx8802_dev *dev) struct dvb_tuner_ops *tuner_ops = NULL; fe0->dvb.frontend = dvb_attach(stv0900_attach, - &prof_7301_stv0900_config, - &core->i2c_adap, 0); - if (fe0->dvb.frontend != NULL) { + &prof_7301_stv0900_config, + &core->i2c_adap, 0); + if (fe0->dvb.frontend) { if (!dvb_attach(stb6100_attach, fe0->dvb.frontend, &prof_7301_stb6100_config, &core->i2c_adap)) @@ -1587,8 +1587,8 @@ static int dvb_register(struct cx8802_dev *dev) mdelay(200); fe0->dvb.frontend = dvb_attach(stv0299_attach, - &samsung_stv0299_config, - &dev->core->i2c_adap); + &samsung_stv0299_config, + &dev->core->i2c_adap); if (fe0->dvb.frontend) { fe0->dvb.frontend->ops.tuner_ops.set_params = samsung_smt_7020_tuner_set_params; @@ -1604,8 +1604,8 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_TWINHAN_VP1027_DVBS: dev->ts_gen_cntrl = 0x00; fe0->dvb.frontend = dvb_attach(mb86a16_attach, - &twinhan_vp1027, - &core->i2c_adap); + &twinhan_vp1027, + &core->i2c_adap); if (fe0->dvb.frontend) { core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; @@ -1772,7 +1772,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) struct vb2_queue *q; fe = vb2_dvb_get_frontend(&core->dvbdev->frontends, i); - if (fe == NULL) { + if (!fe) { pr_err("%s() failed to get frontend(%d)\n", __func__, i); err = -ENODEV; diff --git a/drivers/media/pci/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c index 99596fe56cd2..f7692775fb5a 100644 --- a/drivers/media/pci/cx88/cx88-i2c.c +++ b/drivers/media/pci/cx88/cx88-i2c.c @@ -24,10 +24,9 @@ #include "cx88.h" -#include #include - -#include +#include +#include #include @@ -41,7 +40,8 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); static unsigned int i2c_udelay = 5; module_param(i2c_udelay, int, 0644); -MODULE_PARM_DESC(i2c_udelay, "i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); +MODULE_PARM_DESC(i2c_udelay, + "i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed."); #define dprintk(level, fmt, arg...) do { \ if (i2c_debug >= level) \ @@ -139,7 +139,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) core->i2c_algo = cx8800_i2c_algo_template; - core->i2c_adap.dev.parent = &pci->dev; strlcpy(core->i2c_adap.name, core->name, sizeof(core->i2c_adap.name)); core->i2c_adap.owner = THIS_MODULE; @@ -166,14 +165,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) dprintk(1, "i2c register ok\n"); switch (core->boardnr) { - case CX88_BOARD_HAUPPAUGE_HVR1300: - case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - pr_info("i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n"); - i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1); - break; - default: - break; + case CX88_BOARD_HAUPPAUGE_HVR1300: + case CX88_BOARD_HAUPPAUGE_HVR3000: + case CX88_BOARD_HAUPPAUGE_HVR4000: + pr_info("i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n"); + i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1); + break; + default: + break; } if (i2c_scan) do_i2c_scan(core->name, &core->i2c_client); diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index c072b7ecc8d6..dcfea3502e42 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -62,11 +62,15 @@ static int ir_debug; module_param(ir_debug, int, 0644); /* debug level [IR] */ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); -#define ir_dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s IR: " fmt, ir->core->name, ##arg) +#define ir_dprintk(fmt, arg...) do { \ + if (ir_debug) \ + printk(KERN_DEBUG "%s IR: " fmt, ir->core->name, ##arg);\ +} while (0) -#define dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "cx88 IR: " fmt, ##arg) +#define dprintk(fmt, arg...) do { \ + if (ir_debug) \ + printk(KERN_DEBUG "cx88 IR: " fmt, ##arg); \ +} while (0) /* ---------------------------------------------------------------------- */ @@ -79,16 +83,17 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) gpio = cx_read(ir->gpio_addr); switch (core->boardnr) { case CX88_BOARD_NPGTECH_REALTV_TOP10FM: - /* This board apparently uses a combination of 2 GPIO - to represent the keys. Additionally, the second GPIO - can be used for parity. - - Example: - - for key "5" - gpio = 0x758, auxgpio = 0xe5 or 0xf5 - for key "Power" - gpio = 0x758, auxgpio = 0xed or 0xfd + /* + * This board apparently uses a combination of 2 GPIO + * to represent the keys. Additionally, the second GPIO + * can be used for parity. + * + * Example: + * + * for key "5" + * gpio = 0x758, auxgpio = 0xe5 or 0xf5 + * for key "Power" + * gpio = 0x758, auxgpio = 0xed or 0xfd */ auxgpio = cx_read(MO_GP1_IO); @@ -142,7 +147,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) if (0 == (gpio & ir->mask_keyup)) rc_keydown_notimeout(ir->dev, RC_TYPE_NECX, scancode, - 0); + 0); else rc_keyup(ir->dev); @@ -231,12 +236,14 @@ int cx88_ir_start(struct cx88_core *core) return 0; } +EXPORT_SYMBOL(cx88_ir_start); void cx88_ir_stop(struct cx88_core *core) { if (core->ir->users) __cx88_ir_stop(core); } +EXPORT_SYMBOL(cx88_ir_stop); static int cx88_ir_open(struct rc_dev *rc) { @@ -508,7 +515,7 @@ int cx88_ir_fini(struct cx88_core *core) struct cx88_IR *ir = core->ir; /* skip detach on non attached boards */ - if (ir == NULL) + if (!ir) return 0; cx88_ir_stop(core); @@ -576,7 +583,7 @@ static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol, } dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", - code & 0xff, flags & 0xff); + code & 0xff, flags & 0xff); *protocol = RC_TYPE_UNKNOWN; *scancode = code & 0xff; @@ -636,8 +643,8 @@ void cx88_i2c_init_ir(struct cx88_core *core) info.platform_data = &core->init_data; } if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0, - I2C_SMBUS_READ, 0, - I2C_SMBUS_QUICK, NULL) >= 0) { + I2C_SMBUS_READ, 0, + I2C_SMBUS_QUICK, NULL) >= 0) { info.addr = *addrp; i2c_new_device(&core->i2c_adap, &info); break; diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 4533e2c6cb9f..52ff00ebd4bd 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -16,10 +16,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cx88.h" @@ -30,7 +26,7 @@ #include #include #include -#include +#include /* ------------------------------------------------------------------ */ @@ -54,7 +50,8 @@ MODULE_PARM_DESC(debug, "enable debug messages [mpeg]"); #if defined(CONFIG_MODULES) && defined(MODULE) static void request_module_async(struct work_struct *work) { - struct cx8802_dev *dev = container_of(work, struct cx8802_dev, request_module_wk); + struct cx8802_dev *dev = container_of(work, struct cx8802_dev, + request_module_wk); if (dev->core->board.mpeg & CX88_MPEG_DVB) request_module("cx88-dvb"); @@ -77,14 +74,13 @@ static void flush_request_modules(struct cx8802_dev *dev) #define flush_request_modules(dev) #endif /* CONFIG_MODULES */ - static LIST_HEAD(cx8802_devlist); static DEFINE_MUTEX(cx8802_mutex); /* ------------------------------------------------------------------ */ int cx8802_start_dma(struct cx8802_dev *dev, - struct cx88_dmaqueue *q, - struct cx88_buffer *buf) + struct cx88_dmaqueue *q, + struct cx88_buffer *buf) { struct cx88_core *core = dev->core; @@ -98,33 +94,35 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* write TS length to chip */ cx_write(MO_TS_LNGTH, dev->ts_packet_size); - /* FIXME: this needs a review. - * also: move to cx88-blackbird + cx88-dvb source files? */ + /* + * FIXME: this needs a review. + * also: move to cx88-blackbird + cx88-dvb source files? + */ dprintk(1, "core->active_type_id = 0x%08x\n", core->active_type_id); if ((core->active_type_id == CX88_MPEG_DVB) && - (core->board.mpeg & CX88_MPEG_DVB)) { - + (core->board.mpeg & CX88_MPEG_DVB)) { dprintk(1, "cx8802_start_dma doing .dvb\n"); /* negedge driven & software reset */ cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl); udelay(100); cx_write(MO_PINMUX_IO, 0x00); - cx_write(TS_HW_SOP_CNTRL, 0x47<<16|188<<4|0x01); + cx_write(TS_HW_SOP_CNTRL, 0x47 << 16 | 188 << 4 | 0x01); switch (core->boardnr) { case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: case CX88_BOARD_PCHDTV_HD5500: - cx_write(TS_SOP_STAT, 1<<13); + cx_write(TS_SOP_STAT, 1 << 13); break; case CX88_BOARD_SAMSUNG_SMT_7020: cx_write(TS_SOP_STAT, 0x00); break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ + /* Enable MPEG parallel IO and video signal pins */ + cx_write(MO_PINMUX_IO, 0x88); udelay(100); break; case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -153,13 +151,15 @@ int cx8802_start_dma(struct cx8802_dev *dev, dprintk(1, "cx8802_start_dma doing .blackbird\n"); cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ - cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ + /* punctured clock TS & posedge driven & software reset */ + cx_write(TS_GEN_CNTRL, 0x46); udelay(100); cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ cx_write(TS_VALERR_CNTRL, 0x2000); - cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ + /* punctured clock TS & posedge driven */ + cx_write(TS_GEN_CNTRL, 0x06); udelay(100); } else { pr_err("%s() Failed. Unsupported value in .mpeg (0x%08x)\n", @@ -177,10 +177,11 @@ int cx8802_start_dma(struct cx8802_dev *dev, cx_set(MO_TS_INTMSK, 0x1f0011); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); + cx_set(MO_DEV_CNTRL2, (1 << 5)); cx_set(MO_TS_DMACNTRL, 0x11); return 0; } +EXPORT_SYMBOL(cx8802_start_dma); static int cx8802_stop_dma(struct cx8802_dev *dev) { @@ -219,7 +220,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, /* ------------------------------------------------------------------ */ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf) + struct cx88_buffer *buf) { int size = dev->ts_packet_size * dev->ts_packet_count; struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0); @@ -231,15 +232,17 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); rc = cx88_risc_databuffer(dev->pci, risc, sgt->sgl, - dev->ts_packet_size, dev->ts_packet_count, 0); + dev->ts_packet_size, dev->ts_packet_count, 0); if (rc) { if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + pci_free_consistent(dev->pci, risc->size, + risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); return rc; } return 0; } +EXPORT_SYMBOL(cx8802_buf_prepare); void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) { @@ -268,6 +271,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) buf, buf->vb.vb2_buf.index, __func__); } } +EXPORT_SYMBOL(cx8802_buf_queue); /* ----------------------------------------------------------- */ @@ -292,6 +296,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev) cx8802_stop_dma(dev); do_cancel_buffers(dev); } +EXPORT_SYMBOL(cx8802_cancel_buffers); static const char *cx88_mpeg_irqs[32] = { "ts_risci1", NULL, NULL, NULL, @@ -324,7 +329,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) if (status & (1 << 16)) { pr_warn("mpeg risc op code error\n"); cx_clear(MO_TS_DMACNTRL, 0x11); - cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); + cx88_sram_channel_dump(dev->core, + &cx88_sram_channels[SRAM_CH28]); } /* risc1 y */ @@ -452,7 +458,8 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(dev->core); pci_save_state(pci_dev); - if (pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)) != 0) { + if (pci_set_power_state(pci_dev, + pci_choose_state(pci_dev, state)) != 0) { pci_disable_device(pci_dev); dev->state.disabled = 1; } @@ -497,7 +504,8 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) return 0; } -struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) +struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, + enum cx88_board_type btype) { struct cx8802_driver *d; @@ -507,6 +515,7 @@ struct cx8802_driver *cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_ return NULL; } +EXPORT_SYMBOL(cx8802_get_driver); /* Driver asked for hardware access. */ static int cx8802_request_acquire(struct cx8802_driver *drv) @@ -524,7 +533,8 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) core->last_analog_input = core->input; core->input = 0; for (i = 0; - i < (sizeof(core->board.input) / sizeof(struct cx88_input)); + i < (sizeof(core->board.input) / + sizeof(struct cx88_input)); i++) { if (core->board.input[i].type == CX88_VMUX_DVB) { core->input = i; @@ -533,8 +543,7 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) } } - if (drv->advise_acquire) - { + if (drv->advise_acquire) { core->active_ref++; if (core->active_type_id == CX88_BOARD_NONE) { core->active_type_id = drv->type_id; @@ -552,11 +561,12 @@ static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; - if (drv->advise_release && --core->active_ref == 0) - { + if (drv->advise_release && --core->active_ref == 0) { if (drv->type_id == CX88_MPEG_DVB) { - /* If the DVB driver is releasing, reset the input - state to the last configured analog input */ + /* + * If the DVB driver is releasing, reset the input + * state to the last configured analog input + */ core->input = core->last_analog_input; } @@ -570,21 +580,21 @@ static int cx8802_request_release(struct cx8802_driver *drv) static int cx8802_check_driver(struct cx8802_driver *drv) { - if (drv == NULL) + if (!drv) return -ENODEV; if ((drv->type_id != CX88_MPEG_DVB) && - (drv->type_id != CX88_MPEG_BLACKBIRD)) + (drv->type_id != CX88_MPEG_BLACKBIRD)) return -EINVAL; if ((drv->hw_access != CX8802_DRVCTL_SHARED) && - (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE)) + (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE)) return -EINVAL; - if ((drv->probe == NULL) || - (drv->remove == NULL) || - (drv->advise_acquire == NULL) || - (drv->advise_release == NULL)) + if ((!drv->probe) || + (!drv->remove) || + (!drv->advise_acquire) || + (!drv->advise_release)) return -EINVAL; return 0; @@ -598,9 +608,11 @@ int cx8802_register_driver(struct cx8802_driver *drv) pr_info("registering cx8802 driver, type: %s access: %s\n", drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", - drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); + drv->hw_access == CX8802_DRVCTL_SHARED ? + "shared" : "exclusive"); - if ((err = cx8802_check_driver(drv)) != 0) { + err = cx8802_check_driver(drv); + if (err) { pr_err("cx8802_driver is invalid\n"); return err; } @@ -615,7 +627,7 @@ int cx8802_register_driver(struct cx8802_driver *drv) /* Bring up a new struct for each driver instance */ driver = kzalloc(sizeof(*drv), GFP_KERNEL); - if (driver == NULL) { + if (!driver) { err = -ENOMEM; goto out; } @@ -644,6 +656,7 @@ out: mutex_unlock(&cx8802_mutex); return err; } +EXPORT_SYMBOL(cx8802_register_driver); int cx8802_unregister_driver(struct cx8802_driver *drv) { @@ -653,7 +666,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) pr_info("unregistering cx8802 driver, type: %s access: %s\n", drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", - drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); + drv->hw_access == CX8802_DRVCTL_SHARED ? + "shared" : "exclusive"); mutex_lock(&cx8802_mutex); @@ -686,6 +700,7 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) return err; } +EXPORT_SYMBOL(cx8802_unregister_driver); /* ----------------------------------------------------------- */ static int cx8802_probe(struct pci_dev *pci_dev, @@ -697,7 +712,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, /* general setup */ core = cx88_core_get(pci_dev); - if (core == NULL) + if (!core) return -EINVAL; pr_info("cx2388x 8802 Driver Manager\n"); @@ -708,7 +723,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, err = -ENOMEM; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) + if (!dev) goto fail_core; dev->pci = pci_dev; dev->core = core; @@ -797,12 +812,3 @@ static struct pci_driver cx8802_pci_driver = { }; module_pci_driver(cx8802_pci_driver); - -EXPORT_SYMBOL(cx8802_buf_prepare); -EXPORT_SYMBOL(cx8802_buf_queue); -EXPORT_SYMBOL(cx8802_cancel_buffers); -EXPORT_SYMBOL(cx8802_start_dma); - -EXPORT_SYMBOL(cx8802_register_driver); -EXPORT_SYMBOL(cx8802_unregister_driver); -EXPORT_SYMBOL(cx8802_get_driver); diff --git a/drivers/media/pci/cx88/cx88-reg.h b/drivers/media/pci/cx88/cx88-reg.h index 88ed8a2e4ee1..f1e1dd634a72 100644 --- a/drivers/media/pci/cx88/cx88-reg.h +++ b/drivers/media/pci/cx88/cx88-reg.h @@ -1,32 +1,28 @@ /* - - cx88x-hw.h - CX2388x register offsets - - Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) - 2001 Michael Eskin - 2002 Yurij Sysoev - 2003 Gerd Knorr - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * cx88x-hw.h - CX2388x register offsets + * + * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + * 2001 Michael Eskin + * 2002 Yurij Sysoev + * 2003 Gerd Knorr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #ifndef _CX88_REG_H_ #define _CX88_REG_H_ -/* ---------------------------------------------------------------------- */ -/* PCI IDs and config space */ +/* + * PCI IDs and config space + */ #ifndef PCI_VENDOR_ID_CONEXANT # define PCI_VENDOR_ID_CONEXANT 0x14F1 @@ -39,8 +35,9 @@ #define CX88X_EN_TBFX 0x02 #define CX88X_EN_VSFX 0x04 -/* ---------------------------------------------------------------------- */ -/* PCI controller registers */ +/* + * PCI controller registers + */ /* Command and Status Register */ #define F0_CMD_STAT_MM 0x2f0004 @@ -63,8 +60,9 @@ #define F3_BAR0_MM 0x2f0310 #define F4_BAR0_MM 0x2f0410 -/* ---------------------------------------------------------------------- */ -/* DMA Controller registers */ +/* + * DMA Controller registers + */ #define MO_PDMA_STHRSH 0x200000 // Source threshold #define MO_PDMA_STADRS 0x200004 // Source target address @@ -157,9 +155,9 @@ #define MO_DMA31_CNT2 0x300168 // {11}RW* DMA Table Size : Ch#31 #define MO_DMA32_CNT2 0x30016C // {11}RW* DMA Table Size : Ch#32 - -/* ---------------------------------------------------------------------- */ -/* Video registers */ +/* + * Video registers + */ #define MO_VIDY_DMA 0x310000 // {64}RWp Video Y #define MO_VIDU_DMA 0x310008 // {64}RWp Video U @@ -217,9 +215,9 @@ #define MO_VID_DMACNTRL 0x31C040 // {8}RW Video DMA control #define MO_VID_XFR_STAT 0x31C044 // {1}RO Video transfer status - -/* ---------------------------------------------------------------------- */ -/* audio registers */ +/* + * audio registers + */ #define MO_AUDD_DMA 0x320000 // {64}RWp Audio downstream #define MO_AUDU_DMA 0x320008 // {64}RWp Audio upstream @@ -437,9 +435,9 @@ #define AUD_PHACC_FREQ_8LSB 0x320d2b #define AUD_QAM_MODE 0x320d04 - -/* ---------------------------------------------------------------------- */ -/* transport stream registers */ +/* + * transport stream registers + */ #define MO_TS_DMA 0x330000 // {64}RWp Transport stream downstream #define MO_TS_GPCNT 0x33C020 // {16}RO TS general purpose counter @@ -455,9 +453,9 @@ #define TS_FIFO_OVFL_STAT 0x33C05C #define TS_VALERR_CNTRL 0x33C060 - -/* ---------------------------------------------------------------------- */ -/* VIP registers */ +/* + * VIP registers + */ #define MO_VIPD_DMA 0x340000 // {64}RWp VIP downstream #define MO_VIPU_DMA 0x340008 // {64}RWp VIP upstream @@ -475,9 +473,9 @@ #define MO_VIP_INTCNTRL 0x34C05C // VIP Interrupt Control #define MO_VIP_XFTERM 0x340060 // VIP transfer terminate - -/* ---------------------------------------------------------------------- */ -/* misc registers */ +/* + * misc registers + */ #define MO_M2M_DMA 0x350000 // {64}RWp Mem2Mem DMA Bfr #define MO_GP0_IO 0x350010 // {32}RW* GPIOoutput enablesdata I/O @@ -509,9 +507,9 @@ #define MO_INT1_STAT 0x35C064 // DMA RISC interrupt status #define MO_INT1_MSTAT 0x35C068 // DMA RISC interrupt masked status - -/* ---------------------------------------------------------------------- */ -/* i2c bus registers */ +/* + * i2c bus registers + */ #define MO_I2C 0x368000 // I2C data/control #define MO_I2C_DIV (0xf<<4) @@ -521,9 +519,11 @@ #define MO_I2C_SDA (1<<0) -/* ---------------------------------------------------------------------- */ -/* general purpose host registers */ -/* FIXME: tyops? s/0x35/0x38/ ?? */ +/* + * general purpose host registers + * + * FIXME: tyops? s/0x35/0x38/ ?? + */ #define MO_GPHSTD_DMA 0x350000 // {64}RWp Host downstream #define MO_GPHSTU_DMA 0x350008 // {64}RWp Host upstream @@ -545,9 +545,9 @@ #define MO_GPHST_XFR_STAT 0x38C044 // Host transfer status #define MO_GPHST_SOFT_RST 0x38C06C // Host software reset - -/* ---------------------------------------------------------------------- */ -/* RISC instructions */ +/* + * RISC instructions + */ #define RISC_SYNC 0x80000000 #define RISC_SYNC_ODD 0x80000000 @@ -578,9 +578,9 @@ #define RISC_CNT_RESET 0x00030000 #define RISC_JMP_SRP 0x01 - -/* ---------------------------------------------------------------------- */ -/* various constants */ +/* + * various constants + */ // DMA /* Interrupt mask/status */ diff --git a/drivers/media/pci/cx88/cx88-tvaudio.c b/drivers/media/pci/cx88/cx88-tvaudio.c index 20f6924abe35..545ad4c4d1c7 100644 --- a/drivers/media/pci/cx88/cx88-tvaudio.c +++ b/drivers/media/pci/cx88/cx88-tvaudio.c @@ -57,7 +57,8 @@ MODULE_PARM_DESC(always_analog, "force analog audio out"); static unsigned int radio_deemphasis; module_param(radio_deemphasis, int, 0644); -MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, 0=None, 1=50us (elsewhere), 2=75us (USA)"); +MODULE_PARM_DESC(radio_deemphasis, + "Radio deemphasis time constant, 0=None, 1=50us (elsewhere), 2=75us (USA)"); #define dprintk(fmt, arg...) do { \ if (audio_debug) \ @@ -141,7 +142,10 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) if (core->board.mpeg & CX88_MPEG_BLACKBIRD) { cx_write(AUD_I2SINPUTCNTL, 4); cx_write(AUD_BAUDRATE, 1); - /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ + /* + * 'pass-thru mode': this enables the i2s + * output to the mpeg encoder + */ cx_set(AUD_CTL, EN_I2SOUT_ENABLE); cx_write(AUD_I2SOUTPUTCNTL, 1); cx_write(AUD_I2SCNTL, 0); @@ -634,7 +638,6 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode) case WW_M: dprintk("%s Warning: wrong value\n", __func__); return; - break; } mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF; @@ -691,13 +694,15 @@ static void set_audio_standard_FM(struct cx88_core *core, { /* end of list */ }, }; - /* It is enough to leave default values? */ - /* No, it's not! The deemphasis registers are reset to the 75us + /* + * It is enough to leave default values? + * + * No, it's not! The deemphasis registers are reset to the 75us * values by default. Analyzing the spectrum of the decoded audio * reveals that "no deemphasis" is the same as 75 us, while the 50 us - * setting results in less deemphasis. */ + * setting results in less deemphasis. + */ static const struct rlist fm_no_deemph[] = { - {AUD_POLYPH80SCALEFAC, 0x0003}, { /* end of list */ }, }; @@ -741,7 +746,7 @@ static int cx88_detect_nicam(struct cx88_core *core) } /* wait a little bit for next reading status */ - msleep(10); + usleep_range(10000, 20000); } dprintk("nicam is not detected.\n"); @@ -762,8 +767,10 @@ void cx88_set_tvaudio(struct cx88_core *core) /* prepare all dsp registers */ set_audio_standard_A2(core, EN_A2_FORCE_MONO1); - /* set nicam mode - otherwise - AUD_NICAM_STATUS2 contains wrong values */ + /* + * set nicam mode - otherwise + * AUD_NICAM_STATUS2 contains wrong values + */ set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO); if (cx88_detect_nicam(core) == 0) { /* fall back to fm / am mono */ @@ -797,19 +804,22 @@ void cx88_set_tvaudio(struct cx88_core *core) pr_info("unknown tv audio mode [%d]\n", core->tvaudio); break; } - return; } +EXPORT_SYMBOL(cx88_set_tvaudio); void cx88_newstation(struct cx88_core *core) { core->audiomode_manual = UNSET; core->last_change = jiffies; } +EXPORT_SYMBOL(cx88_newstation); void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) { - static const char * const m[] = { "stereo", "dual mono", "mono", "sap" }; - static const char * const p[] = { "no pilot", "pilot c1", "pilot c2", "?" }; + static const char * const m[] = { "stereo", "dual mono", + "mono", "sap" }; + static const char * const p[] = { "no pilot", "pilot c1", + "pilot c2", "?" }; u32 reg, mode, pilot; reg = cx_read(AUD_STATUS); @@ -866,13 +876,16 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) /* If software stereo detection is not supported... */ if (t->rxsubchans == UNSET) { t->rxsubchans = V4L2_TUNER_SUB_MONO; - /* If the hardware itself detected stereo, also return - stereo as an available subchannel */ + /* + * If the hardware itself detected stereo, also return + * stereo as an available subchannel + */ if (t->audmode == V4L2_TUNER_MODE_STEREO) t->rxsubchans |= V4L2_TUNER_SUB_STEREO; } - return; } +EXPORT_SYMBOL(cx88_get_stereo); + void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) { @@ -928,7 +941,8 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) break; } } else { - if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) { + if ((core->tvaudio == WW_I) || + (core->tvaudio == WW_L)) { /* fall back to fm / am mono */ set_audio_standard_A2(core, EN_A2_FORCE_MONO1); } else { @@ -976,8 +990,8 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL)); cx_andor(AUD_CTL, mask, ctl); } - return; } +EXPORT_SYMBOL(cx88_set_stereo); int cx88_audio_thread(void *data) { @@ -1027,8 +1041,10 @@ int cx88_audio_thread(void *data) case WW_FM: case WW_I2SADC: hw_autodetect: - /* stereo autodetection is supported by hardware so - we don't need to do it manually. Do nothing. */ + /* + * stereo autodetection is supported by hardware so + * we don't need to do it manually. Do nothing. + */ break; } } @@ -1036,11 +1052,4 @@ hw_autodetect: dprintk("cx88: tvaudio thread exiting\n"); return 0; } - -/* ----------------------------------------------------------- */ - -EXPORT_SYMBOL(cx88_set_tvaudio); -EXPORT_SYMBOL(cx88_newstation); -EXPORT_SYMBOL(cx88_set_stereo); -EXPORT_SYMBOL(cx88_get_stereo); EXPORT_SYMBOL(cx88_audio_thread); diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 9028822f507e..2d0ef19e6d65 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -20,7 +20,7 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); /* ------------------------------------------------------------------ */ int cx8800_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); @@ -48,8 +48,8 @@ int cx8800_vbi_fmt(struct file *file, void *priv, } static int cx8800_start_vbi_dma(struct cx8800_dev *dev, - struct cx88_dmaqueue *q, - struct cx88_buffer *buf) + struct cx88_dmaqueue *q, + struct cx88_buffer *buf) { struct cx88_core *core = dev->core; @@ -57,9 +57,9 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24], VBI_LINE_LENGTH, buf->risc.dma); - cx_write(MO_VBOS_CONTROL, ((1 << 18) | // comb filter delay fixup - (1 << 15) | // enable vbi capture - (1 << 11))); + cx_write(MO_VBOS_CONTROL, (1 << 18) | /* comb filter delay fixup */ + (1 << 15) | /* enable vbi capture */ + (1 << 11)); /* reset counter */ cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET); @@ -73,7 +73,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, cx_set(VID_CAPTURE_CONTROL, 0x18); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); + cx_set(MO_DEV_CNTRL2, (1 << 5)); cx_set(MO_VID_DMACNTRL, 0x88); return 0; @@ -112,8 +112,8 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev, /* ------------------------------------------------------------------ */ static int queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) { struct cx8800_dev *dev = q->drv_priv; @@ -125,7 +125,6 @@ static int queue_setup(struct vb2_queue *q, return 0; } - static int buffer_prepare(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 797d5d0a4060..c7d4e87ccb64 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -73,7 +73,6 @@ MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); __func__, ##arg); \ } while (0) - /* ------------------------------------------------------------------- */ /* static data */ @@ -123,7 +122,8 @@ static const struct cx8800_fmt formats[] = { }, { .name = "32 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB32, - .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | ColorFormatWSWAP, + .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | + ColorFormatWSWAP, .depth = 32, .flags = FORMAT_FLAGS_PACKED, }, { @@ -147,7 +147,7 @@ static const struct cx8800_fmt *format_by_fourcc(unsigned int fourcc) for (i = 0; i < ARRAY_SIZE(formats); i++) if (formats[i].fourcc == fourcc) - return formats+i; + return formats + i; return NULL; } @@ -221,8 +221,10 @@ static const struct cx88_ctrl cx8800_vid_ctls[] = { .step = 1, .default_value = 0x0, .off = 0, - /* NOTE: the value is converted and written to both even - and odd registers in the code */ + /* + * NOTE: the value is converted and written to both even + * and odd registers in the code + */ .reg = MO_FILTER_ODD, .mask = 7 << 7, .shift = 7, @@ -326,19 +328,25 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) break; } - /* if there are audioroutes defined, we have an external - ADC to deal with audio */ + /* + * if there are audioroutes defined, we have an external + * ADC to deal with audio + */ if (INPUT(input).audioroute) { - /* The wm8775 module has the "2" route hardwired into - the initialization. Some boards may use different - routes for different inputs. HVR-1300 surely does */ + /* + * The wm8775 module has the "2" route hardwired into + * the initialization. Some boards may use different + * routes for different inputs. HVR-1300 surely does + */ if (core->sd_wm8775) { call_all(core, audio, s_routing, INPUT(input).audioroute, 0, 0); } - /* cx2388's C-ADC is connected to the tuner only. - When used with S-Video, that ADC is busy dealing with - chroma, so an external must be used for baseband audio */ + /* + * cx2388's C-ADC is connected to the tuner only. + * When used with S-Video, that ADC is busy dealing with + * chroma, so an external must be used for baseband audio + */ if (INPUT(input).type != CX88_VMUX_TELEVISION && INPUT(input).type != CX88_VMUX_CABLE) { /* "I2S ADC mode" */ @@ -376,12 +384,13 @@ static int start_video_dma(struct cx8800_dev *dev, /* enable irqs */ cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT); - /* Enables corresponding bits at PCI_INT_STAT: - bits 0 to 4: video, audio, transport stream, VIP, Host - bit 7: timer - bits 8 and 9: DMA complete for: SRC, DST - bits 10 and 11: BERR signal asserted for RISC: RD, WR - bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB + /* + * Enables corresponding bits at PCI_INT_STAT: + * bits 0 to 4: video, audio, transport stream, VIP, Host + * bit 7: timer + * bits 8 and 9: DMA complete for: SRC, DST + * bits 10 and 11: BERR signal asserted for RISC: RD, WR + * bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB */ cx_set(MO_VID_INTMSK, 0x0f0011); @@ -389,7 +398,7 @@ static int start_video_dma(struct cx8800_dev *dev, cx_set(VID_CAPTURE_CONTROL, 0x06); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); + cx_set(MO_DEV_CNTRL2, (1 << 5)); cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */ return 0; @@ -430,8 +439,8 @@ static int restart_video_queue(struct cx8800_dev *dev, /* ------------------------------------------------------------------ */ static int queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) { struct cx8800_dev *dev = q->drv_priv; struct cx88_core *core = dev->core; @@ -488,7 +497,8 @@ static int buffer_prepare(struct vb2_buffer *vb) core->height >> 1); break; } - dprintk(2, "[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", + dprintk(2, + "[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", buf, buf->vb.vb2_buf.index, core->width, core->height, dev->fmt->depth, dev->fmt->name, (unsigned long)buf->risc.dma); @@ -595,7 +605,7 @@ static int radio_open(struct file *file) if (core->board.radio.audioroute) { if (core->sd_wm8775) { call_all(core, audio, s_routing, - core->board.radio.audioroute, 0, 0); + core->board.radio.audioroute, 0, 0); } /* "I2S ADC mode" */ core->tvaudio = WW_I2SADC; @@ -649,9 +659,10 @@ static int cx8800_s_vid_ctrl(struct v4l2_ctrl *ctrl) value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; break; } - dprintk(1, "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctrl->id, ctrl->name, ctrl->val, cc->reg, value, - mask, cc->sreg ? " [shadowed]" : ""); + dprintk(1, + "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + ctrl->id, ctrl->name, ctrl->val, cc->reg, value, + mask, cc->sreg ? " [shadowed]" : ""); if (cc->sreg) cx_sandor(cc->sreg, cc->reg, mask, value); else @@ -687,7 +698,8 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) mask = cc->mask; switch (ctrl->id) { case V4L2_CID_AUDIO_BALANCE: - value = (ctrl->val < 0x40) ? (0x7f - ctrl->val) : (ctrl->val - 0x40); + value = (ctrl->val < 0x40) ? + (0x7f - ctrl->val) : (ctrl->val - 0x40); break; case V4L2_CID_AUDIO_VOLUME: value = 0x3f - (ctrl->val & 0x3f); @@ -696,9 +708,10 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; break; } - dprintk(1, "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctrl->id, ctrl->name, ctrl->val, cc->reg, value, - mask, cc->sreg ? " [shadowed]" : ""); + dprintk(1, + "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + ctrl->id, ctrl->name, ctrl->val, cc->reg, value, + mask, cc->sreg ? " [shadowed]" : ""); if (cc->sreg) cx_sandor(cc->sreg, cc->reg, mask, value); else @@ -710,7 +723,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) /* VIDEO IOCTLS */ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -728,7 +741,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -737,7 +750,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, unsigned int maxw, maxh; fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (fmt == NULL) + if (!fmt) return -EINVAL; maxw = norm_maxw(core->tvnorm); @@ -774,7 +787,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -794,7 +807,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, } void cx88_querycap(struct file *file, struct cx88_core *core, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); @@ -821,7 +834,7 @@ void cx88_querycap(struct file *file, struct cx88_core *core, EXPORT_SYMBOL(cx88_querycap); static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -833,7 +846,7 @@ static int vidioc_querycap(struct file *file, void *priv, } static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) + struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(formats))) return -EINVAL; @@ -879,21 +892,21 @@ int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i) if (n >= 4) return -EINVAL; - if (0 == INPUT(n).type) + if (!INPUT(n).type) return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; strcpy(i->name, iname[INPUT(n).type]); - if ((CX88_VMUX_TELEVISION == INPUT(n).type) || - (CX88_VMUX_CABLE == INPUT(n).type)) { + if ((INPUT(n).type == CX88_VMUX_TELEVISION) || + (INPUT(n).type == CX88_VMUX_CABLE)) i->type = V4L2_INPUT_TYPE_TUNER; - } + i->std = CX88_NORMS; return 0; } EXPORT_SYMBOL(cx88_enum_input); static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) + struct v4l2_input *i) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -917,7 +930,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) if (i >= 4) return -EINVAL; - if (0 == INPUT(i).type) + if (!INPUT(i).type) return -EINVAL; cx88_newstation(core); @@ -926,7 +939,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) } static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) + struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -944,12 +957,12 @@ static int vidioc_g_tuner(struct file *file, void *priv, cx88_get_stereo(core, t); reg = cx_read(MO_DEVICE_STATUS); - t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; + t->signal = (reg & (1 << 5)) ? 0xffff : 0x0000; return 0; } static int vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) + const struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -964,7 +977,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, } static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -982,7 +995,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, } int cx88_set_freq(struct cx88_core *core, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { struct v4l2_frequency new_freq = *f; @@ -1005,7 +1018,7 @@ int cx88_set_freq(struct cx88_core *core, EXPORT_SYMBOL(cx88_set_freq); static int vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1015,7 +1028,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) + struct v4l2_dbg_register *reg) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1027,7 +1040,7 @@ static int vidioc_g_register(struct file *file, void *fh, } static int vidioc_s_register(struct file *file, void *fh, - const struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1042,7 +1055,7 @@ static int vidioc_s_register(struct file *file, void *fh, /* ----------------------------------------------------------- */ static int radio_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) + struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1057,7 +1070,7 @@ static int radio_g_tuner(struct file *file, void *priv, } static int radio_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) + const struct v4l2_tuner *t) { struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; @@ -1152,7 +1165,6 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) /* exported stuff */ static const struct v4l2_file_operations video_fops = { - .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, @@ -1232,7 +1244,6 @@ static const struct video_device cx8800_vbi_template = { }; static const struct v4l2_file_operations radio_fops = { - .owner = THIS_MODULE, .open = radio_open, .poll = v4l2_ctrl_poll, @@ -1287,7 +1298,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, int i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) + if (!dev) return -ENOMEM; /* pci init */ @@ -1297,7 +1308,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_free; } core = cx88_core_get(dev->pci); - if (core == NULL) { + if (!core) { err = -EINVAL; goto fail_free; } @@ -1341,8 +1352,9 @@ static int cx8800_initdev(struct pci_dev *pci_dev, struct v4l2_ctrl *vc; vc = v4l2_ctrl_new_std(&core->audio_hdl, &cx8800_ctrl_aud_ops, - cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value); - if (vc == NULL) { + cc->id, cc->minimum, cc->maximum, + cc->step, cc->default_value); + if (!vc) { err = core->audio_hdl.error; goto fail_core; } @@ -1354,8 +1366,9 @@ static int cx8800_initdev(struct pci_dev *pci_dev, struct v4l2_ctrl *vc; vc = v4l2_ctrl_new_std(&core->video_hdl, &cx8800_ctrl_vid_ops, - cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value); - if (vc == NULL) { + cc->id, cc->minimum, cc->maximum, + cc->step, cc->default_value); + if (!vc) { err = core->video_hdl.error; goto fail_core; } @@ -1381,18 +1394,20 @@ static int cx8800_initdev(struct pci_dev *pci_dev, core->wm8775_data.is_nova_s = false; sd = v4l2_i2c_new_subdev_board(&core->v4l2_dev, &core->i2c_adap, - &wm8775_info, NULL); - if (sd != NULL) { + &wm8775_info, NULL); + if (sd) { core->sd_wm8775 = sd; sd->grp_id = WM8775_GID; } } if (core->board.audio_chip == CX88_AUDIO_TVAUDIO) { - /* This probes for a tda9874 as is used on some - Pixelview Ultra boards. */ + /* + * This probes for a tda9874 as is used on some + * Pixelview Ultra boards. + */ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, - "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); + "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); } switch (core->boardnr) { @@ -1504,7 +1519,8 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* start tvaudio thread */ if (core->board.tuner_type != UNSET) { - core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); + core->kthread = kthread_run(cx88_audio_thread, + core, "cx88 tvaudio"); if (IS_ERR(core->kthread)) { err = PTR_ERR(core->kthread); pr_err("failed to create cx88 audio thread, err=%d\n", @@ -1581,7 +1597,8 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) cx88_shutdown(core); pci_save_state(pci_dev); - if (pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)) != 0) { + if (pci_set_power_state(pci_dev, + pci_choose_state(pci_dev, state)) != 0) { pci_disable_device(pci_dev); dev->state.disabled = 1; } diff --git a/drivers/media/pci/cx88/cx88-vp3054-i2c.c b/drivers/media/pci/cx88/cx88-vp3054-i2c.c index eea56ae9071e..92876de3841c 100644 --- a/drivers/media/pci/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.c @@ -22,8 +22,7 @@ #include #include #include - -#include +#include MODULE_DESCRIPTION("driver for cx2388x VP3054 design"); MODULE_AUTHOR("Chris Pascoe "); @@ -108,7 +107,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) return 0; vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL); - if (vp3054_i2c == NULL) + if (!vp3054_i2c) return -ENOMEM; dev->vp3054 = vp3054_i2c; @@ -135,18 +134,17 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) return rc; } +EXPORT_SYMBOL(vp3054_i2c_probe); void vp3054_i2c_remove(struct cx8802_dev *dev) { struct vp3054_i2c_state *vp3054_i2c = dev->vp3054; - if (vp3054_i2c == NULL || + if (!vp3054_i2c || dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) return; i2c_del_adapter(&vp3054_i2c->adap); kfree(vp3054_i2c); } - -EXPORT_SYMBOL(vp3054_i2c_probe); EXPORT_SYMBOL(vp3054_i2c_remove); diff --git a/drivers/media/pci/cx88/cx88-vp3054-i2c.h b/drivers/media/pci/cx88/cx88-vp3054-i2c.h index 95d0c60a35e1..ec19bea8f1e2 100644 --- a/drivers/media/pci/cx88/cx88-vp3054-i2c.h +++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.h @@ -1,26 +1,20 @@ /* - - cx88-vp3054-i2c.h -- support for the secondary I2C bus of the - DNTV Live! DVB-T Pro (VP-3054), wired as: - GPIO[0] -> SCL, GPIO[1] -> SDA - - (c) 2005 Chris Pascoe - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ + * cx88-vp3054-i2c.h -- support for the secondary I2C bus of the + * DNTV Live! DVB-T Pro (VP-3054), wired as: + * GPIO[0] -> SCL, GPIO[1] -> SDA + * + * (c) 2005 Chris Pascoe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ /* ----------------------------------------------------------------------- */ struct vp3054_i2c_state { diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index ac1fb9fb340e..115414cf520f 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -1,5 +1,4 @@ /* - * * v4l2 device driver for cx2388x based TV cards * * (c) 2003,04 Gerd Knorr [SUSE Labs] @@ -99,7 +98,6 @@ static inline unsigned int norm_maxw(v4l2_std_id norm) return 720; } - static inline unsigned int norm_maxh(v4l2_std_id norm) { return (norm & V4L2_STD_525_60) ? 480 : 576; @@ -141,6 +139,7 @@ struct sram_channel { u32 cnt1_reg; u32 cnt2_reg; }; + extern const struct sram_channel cx88_sram_channels[]; /* ----------------------------------------------------------- */ @@ -384,8 +383,8 @@ struct cx88_core { /* state info */ struct task_struct *kthread; v4l2_std_id tvnorm; - unsigned int width, height; - unsigned int field; + unsigned int width, height; + unsigned int field; enum cx88_tvaudio tvaudio; u32 audiomode_manual; u32 audiomode_current; @@ -428,7 +427,8 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) if (!core->i2c_rc) { \ if (core->gate_ctrl) \ core->gate_ctrl(core, 1); \ - v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \ + v4l2_device_call_all(&core->v4l2_dev, \ + grpid, o, f, ##args); \ if (core->gate_ctrl) \ core->gate_ctrl(core, 0); \ } \ @@ -439,31 +439,31 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) #define WM8775_GID (1 << 0) #define wm8775_s_ctrl(core, id, val) \ - do { \ - struct v4l2_ctrl *ctrl_ = \ - v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \ - if (ctrl_ && !core->i2c_rc) { \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 1); \ - v4l2_ctrl_s_ctrl(ctrl_, val); \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 0); \ - } \ + do { \ + struct v4l2_ctrl *ctrl_ = \ + v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id);\ + if (ctrl_ && !core->i2c_rc) { \ + if (core->gate_ctrl) \ + core->gate_ctrl(core, 1); \ + v4l2_ctrl_s_ctrl(ctrl_, val); \ + if (core->gate_ctrl) \ + core->gate_ctrl(core, 0); \ + } \ } while (0) #define wm8775_g_ctrl(core, id) \ - ({ \ - struct v4l2_ctrl *ctrl_ = \ - v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \ - s32 val = 0; \ - if (ctrl_ && !core->i2c_rc) { \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 1); \ - val = v4l2_ctrl_g_ctrl(ctrl_); \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 0); \ - } \ - val; \ + ({ \ + struct v4l2_ctrl *ctrl_ = \ + v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id);\ + s32 val = 0; \ + if (ctrl_ && !core->i2c_rc) { \ + if (core->gate_ctrl) \ + core->gate_ctrl(core, 1); \ + val = v4l2_ctrl_g_ctrl(ctrl_); \ + if (core->gate_ctrl) \ + core->gate_ctrl(core, 0); \ + } \ + val; \ }) /* ----------------------------------------------------------- */ @@ -505,7 +505,6 @@ struct cx8800_dev { /* function 1: audio/alsa stuff */ /* =============> moved to cx88-alsa.c <====================== */ - /* ----------------------------------------------------------- */ /* function 2: mpeg stuff */ @@ -567,6 +566,7 @@ struct cx8802_dev { /* mpeg params */ struct cx2341x_handler cxhdl; + #endif #if IS_ENABLED(CONFIG_VIDEO_CX88_DVB) @@ -589,40 +589,42 @@ struct cx8802_dev { /* ----------------------------------------------------------- */ -#define cx_read(reg) readl(core->lmmio + ((reg)>>2)) -#define cx_write(reg, value) writel((value), core->lmmio + ((reg)>>2)) -#define cx_writeb(reg, value) writeb((value), core->bmmio + (reg)) +#define cx_read(reg) readl(core->lmmio + ((reg) >> 2)) +#define cx_write(reg, value) writel((value), core->lmmio + ((reg) >> 2)) +#define cx_writeb(reg, value) writeb((value), core->bmmio + (reg)) #define cx_andor(reg, mask, value) \ - writel((readl(core->lmmio+((reg)>>2)) & ~(mask)) |\ - ((value) & (mask)), core->lmmio+((reg)>>2)) -#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) -#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) + writel((readl(core->lmmio + ((reg) >> 2)) & ~(mask)) |\ + ((value) & (mask)), core->lmmio + ((reg) >> 2)) +#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) +#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) #define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); } /* shadow registers */ #define cx_sread(sreg) (core->shadow[sreg]) #define cx_swrite(sreg, reg, value) \ - (core->shadow[sreg] = value, \ - writel(core->shadow[sreg], core->lmmio + ((reg)>>2))) + (core->shadow[sreg] = value, \ + writel(core->shadow[sreg], core->lmmio + ((reg) >> 2))) #define cx_sandor(sreg, reg, mask, value) \ - (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | ((value) & (mask)), \ - writel(core->shadow[sreg], core->lmmio + ((reg)>>2))) + (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | \ + ((value) & (mask)), \ + writel(core->shadow[sreg], \ + core->lmmio + ((reg) >> 2))) /* ----------------------------------------------------------- */ /* cx88-core.c */ extern unsigned int cx88_core_debug; -extern void cx88_print_irqbits(const char *tag, const char *strings[], - int len, u32 bits, u32 mask); +void cx88_print_irqbits(const char *tag, const char *strings[], + int len, u32 bits, u32 mask); -extern int cx88_core_irq(struct cx88_core *core, u32 status); -extern void cx88_wakeup(struct cx88_core *core, - struct cx88_dmaqueue *q, u32 count); -extern void cx88_shutdown(struct cx88_core *core); -extern int cx88_reset(struct cx88_core *core); +int cx88_core_irq(struct cx88_core *core, u32 status); +void cx88_wakeup(struct cx88_core *core, + struct cx88_dmaqueue *q, u32 count); +void cx88_shutdown(struct cx88_core *core); +int cx88_reset(struct cx88_core *core); extern int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, @@ -634,43 +636,37 @@ cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, unsigned int lines, unsigned int lpi); -extern void cx88_risc_disasm(struct cx88_core *core, - struct cx88_riscmem *risc); -extern int cx88_sram_channel_setup(struct cx88_core *core, - const struct sram_channel *ch, - unsigned int bpl, u32 risc); -extern void cx88_sram_channel_dump(struct cx88_core *core, - const struct sram_channel *ch); - -extern int cx88_set_scale(struct cx88_core *core, unsigned int width, - unsigned int height, enum v4l2_field field); -extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); - -extern void cx88_vdev_init(struct cx88_core *core, - struct pci_dev *pci, - struct video_device *vfd, - const struct video_device *template_, - const char *type); -extern struct cx88_core *cx88_core_get(struct pci_dev *pci); -extern void cx88_core_put(struct cx88_core *core, - struct pci_dev *pci); - -extern int cx88_start_audio_dma(struct cx88_core *core); -extern int cx88_stop_audio_dma(struct cx88_core *core); - +void cx88_risc_disasm(struct cx88_core *core, + struct cx88_riscmem *risc); +int cx88_sram_channel_setup(struct cx88_core *core, + const struct sram_channel *ch, + unsigned int bpl, u32 risc); +void cx88_sram_channel_dump(struct cx88_core *core, + const struct sram_channel *ch); + +int cx88_set_scale(struct cx88_core *core, unsigned int width, + unsigned int height, enum v4l2_field field); +int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); + +void cx88_vdev_init(struct cx88_core *core, + struct pci_dev *pci, + struct video_device *vfd, + const struct video_device *template_, + const char *type); +struct cx88_core *cx88_core_get(struct pci_dev *pci); +void cx88_core_put(struct cx88_core *core, + struct pci_dev *pci); + +int cx88_start_audio_dma(struct cx88_core *core); +int cx88_stop_audio_dma(struct cx88_core *core); /* ----------------------------------------------------------- */ /* cx88-vbi.c */ /* Can be used as g_vbi_fmt, try_vbi_fmt and s_vbi_fmt */ int cx8800_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f); + struct v4l2_format *f); -/* -int cx8800_start_vbi_dma(struct cx8800_dev *dev, - struct cx88_dmaqueue *q, - struct cx88_buffer *buf); -*/ void cx8800_stop_vbi_dma(struct cx8800_dev *dev); int cx8800_restart_vbi_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q); @@ -679,17 +675,16 @@ extern const struct vb2_ops cx8800_vbi_qops; /* ----------------------------------------------------------- */ /* cx88-i2c.c */ -extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); - +int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); /* ----------------------------------------------------------- */ /* cx88-cards.c */ -extern int cx88_tuner_callback(void *dev, int component, int command, int arg); -extern int cx88_get_resources(const struct cx88_core *core, - struct pci_dev *pci); -extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); -extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); +int cx88_tuner_callback(void *dev, int component, int command, int arg); +int cx88_get_resources(const struct cx88_core *core, + struct pci_dev *pci); +struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); +void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); /* ----------------------------------------------------------- */ /* cx88-tvaudio.c */ @@ -720,18 +715,18 @@ int cx88_ir_fini(struct cx88_core *core); void cx88_ir_irq(struct cx88_core *core); int cx88_ir_start(struct cx88_core *core); void cx88_ir_stop(struct cx88_core *core); -extern void cx88_i2c_init_ir(struct cx88_core *core); +void cx88_i2c_init_ir(struct cx88_core *core); /* ----------------------------------------------------------- */ /* cx88-mpeg.c */ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf); + struct cx88_buffer *buf); void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); void cx8802_cancel_buffers(struct cx8802_dev *dev); int cx8802_start_dma(struct cx8802_dev *dev, - struct cx88_dmaqueue *q, - struct cx88_buffer *buf); + struct cx88_dmaqueue *q, + struct cx88_buffer *buf); /* ----------------------------------------------------------- */ /* cx88-video.c*/ @@ -739,6 +734,6 @@ int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i); int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f); int cx88_video_mux(struct cx88_core *core, unsigned int input); void cx88_querycap(struct file *file, struct cx88_core *core, - struct v4l2_capability *cap); + struct v4l2_capability *cap); #endif -- cgit v1.2.3 From d3d83ee20afda16ad0133ba00f63c11a8d842a35 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 22 Nov 2016 18:52:17 -0200 Subject: [media] DaVinci-VPFE-Capture: fix error handling A recent cleanup had the right idea to remove the initialization of the error variable, but missed the actual benefit of that, which is that we get warnings if there is a bug in it. Now we get a warning about a bug that was introduced by this cleanup: drivers/media/platform/davinci/vpfe_capture.c: In function 'vpfe_probe': drivers/media/platform/davinci/vpfe_capture.c:1992:9: error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized] This adds the missing initialization that the warning is about, and another one that was preexisting and that we did not get a warning for. That second bug has existed since the driver was first added. Fixes: efb74461f5a6 ("[media] DaVinci-VPFE-Capture: Delete an unnecessary variable initialisation in vpfe_probe()") Fixes: 7da8a6cb3e5b ("V4L/DVB (12248): v4l: vpfe capture bridge driver for DM355 and DM6446") [mchehab@s-opensource.com: fix a merge conflict] Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index bc2c62b95493..ee1cd79739c8 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1966,6 +1966,7 @@ static int vpfe_probe(struct platform_device *pdev) v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 sub device %s register fails\n", sdinfo->name); + ret = -ENXIO; goto probe_sd_out; } } -- cgit v1.2.3 From cf2113ca563191a9ee5943561827e50ad8cda4e0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 25 Nov 2016 08:28:35 -0200 Subject: [media] uvcvideo: freeing an error pointer A recent cleanup introduced a potential dereference of -EFAULT when we call kfree(map->menu_info). Fixes: 4cc5bed1caeb ("[media] uvcvideo: Use memdup_user() rather than duplicating its implementation") Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_v4l2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index a7e12fd20adc..3e7e283a44a8 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -66,14 +66,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, if (xmap->menu_count == 0 || xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { ret = -EINVAL; - goto done; + goto free_map; } size = xmap->menu_count * sizeof(*map->menu_info); map->menu_info = memdup_user(xmap->menu_info, size); if (IS_ERR(map->menu_info)) { ret = PTR_ERR(map->menu_info); - goto done; + goto free_map; } map->menu_count = xmap->menu_count; @@ -83,13 +83,13 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type " "%u.\n", xmap->v4l2_type); ret = -ENOTTY; - goto done; + goto free_map; } ret = uvc_ctrl_add_mapping(chain, map); -done: kfree(map->menu_info); +free_map: kfree(map); return ret; -- cgit v1.2.3 From f51e80804f084de269954d875c0892b081b7df3c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Nov 2016 06:23:34 -0200 Subject: [media] cec: pass parent device in register(), not allocate() The cec_allocate_adapter function doesn't need the parent device, only the cec_register_adapter function needs it. Drop the cec_devnode parent field, since devnode.dev.parent can be used instead. This change makes the framework consistent with other frameworks where the parent device is not used until the device is registered. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/cec-core.rst | 14 ++++++-------- drivers/media/cec/cec-api.c | 2 +- drivers/media/cec/cec-core.c | 18 ++++++++++-------- drivers/media/i2c/adv7511.c | 5 +++-- drivers/media/i2c/adv7604.c | 6 +++--- drivers/media/i2c/adv7842.c | 6 +++--- drivers/media/platform/vivid/vivid-cec.c | 3 +-- drivers/media/platform/vivid/vivid-cec.h | 1 - drivers/media/platform/vivid/vivid-core.c | 9 ++++----- drivers/media/usb/pulse8-cec/pulse8-cec.c | 4 ++-- drivers/staging/media/s5p-cec/s5p_cec.c | 5 ++--- drivers/staging/media/st-cec/stih-cec.c | 5 ++--- include/media/cec.h | 10 ++++------ 13 files changed, 41 insertions(+), 47 deletions(-) diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 8a88dd4ce3d4..81c6d8e93774 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -37,9 +37,8 @@ The struct cec_adapter represents the CEC adapter hardware. It is created by calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): .. c:function:: - struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, - void *priv, const char *name, u32 caps, u8 available_las, - struct device *parent); + struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, + const char *name, u32 caps, u8 available_las); .. c:function:: void cec_delete_adapter(struct cec_adapter *adap); @@ -66,20 +65,19 @@ available_las: the number of simultaneous logical addresses that this adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. -parent: - the parent device. - To register the /dev/cecX device node and the remote control device (if CEC_CAP_RC is set) you call: .. c:function:: - int cec_register_adapter(struct cec_adapter \*adap); + int cec_register_adapter(struct cec_adapter *adap, struct device *parent); + +where parent is the parent device. To unregister the devices call: .. c:function:: - void cec_unregister_adapter(struct cec_adapter \*adap); + void cec_unregister_adapter(struct cec_adapter *adap); Note: if cec_register_adapter() fails, then call cec_delete_adapter() to clean up. But if cec_register_adapter() succeeded, then only call diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 597fbb62d829..8950b6c9d6a9 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -88,7 +88,7 @@ static long cec_adap_g_caps(struct cec_adapter *adap, { struct cec_caps caps = {}; - strlcpy(caps.driver, adap->devnode.parent->driver->name, + strlcpy(caps.driver, adap->devnode.dev.parent->driver->name, sizeof(caps.driver)); strlcpy(caps.name, adap->name, sizeof(caps.name)); caps.available_log_addrs = adap->available_log_addrs; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index b0137e247dc9..aca3ab83a8a1 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -132,7 +132,6 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, devnode->dev.bus = &cec_bus_type; devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor); devnode->dev.release = cec_devnode_release; - devnode->dev.parent = devnode->parent; dev_set_name(&devnode->dev, "cec%d", devnode->minor); device_initialize(&devnode->dev); @@ -198,13 +197,11 @@ static void cec_devnode_unregister(struct cec_devnode *devnode) struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, const char *name, u32 caps, - u8 available_las, struct device *parent) + u8 available_las) { struct cec_adapter *adap; int res; - if (WARN_ON(!parent)) - return ERR_PTR(-EINVAL); if (WARN_ON(!caps)) return ERR_PTR(-EINVAL); if (WARN_ON(!ops)) @@ -214,8 +211,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap = kzalloc(sizeof(*adap), GFP_KERNEL); if (!adap) return ERR_PTR(-ENOMEM); - adap->owner = parent->driver->owner; - adap->devnode.parent = parent; strlcpy(adap->name, name, sizeof(adap->name)); adap->phys_addr = CEC_PHYS_ADDR_INVALID; adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; @@ -264,7 +259,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.vendor = 0; adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; - adap->rc->dev.parent = parent; adap->rc->driver_type = RC_DRIVER_SCANCODE; adap->rc->driver_name = CEC_NAME; adap->rc->allowed_protocols = RC_BIT_CEC; @@ -278,14 +272,22 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, } EXPORT_SYMBOL_GPL(cec_allocate_adapter); -int cec_register_adapter(struct cec_adapter *adap) +int cec_register_adapter(struct cec_adapter *adap, + struct device *parent) { int res; if (IS_ERR_OR_NULL(adap)) return 0; + if (WARN_ON(!parent)) + return -EINVAL; + + adap->owner = parent->driver->owner; + adap->devnode.dev.parent = parent; + #if IS_REACHABLE(CONFIG_RC_CORE) + adap->rc->dev.parent = parent; if (adap->capabilities & CEC_CAP_RC) { res = rc_register_device(adap->rc); diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 5ba0f21bcfe4..8c9e28949ab1 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1732,9 +1732,10 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd) static int adv7511_registered(struct v4l2_subdev *sd) { struct adv7511_state *state = get_adv7511_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); int err; - err = cec_register_adapter(state->cec_adap); + err = cec_register_adapter(state->cec_adap, &client->dev); if (err) cec_delete_adapter(state->cec_adap); return err; @@ -1928,7 +1929,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, state, dev_name(&client->dev), CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | CEC_CAP_RC, - ADV7511_MAX_ADDRS, &client->dev); + ADV7511_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) { destroy_workqueue(state->work_queue); diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 5630eb22daaa..d0375cac6a05 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2631,9 +2631,10 @@ static int adv76xx_subscribe_event(struct v4l2_subdev *sd, static int adv76xx_registered(struct v4l2_subdev *sd) { struct adv76xx_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); int err; - err = cec_register_adapter(state->cec_adap); + err = cec_register_adapter(state->cec_adap, &client->dev); if (err) cec_delete_adapter(state->cec_adap); return err; @@ -3511,8 +3512,7 @@ static int adv76xx_probe(struct i2c_client *client, state->cec_adap = cec_allocate_adapter(&adv76xx_cec_adap_ops, state, dev_name(&client->dev), CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV76XX_MAX_ADDRS, - &client->dev); + CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV76XX_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) goto err_entity; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 8c2a52e280af..2d61f0cc2b5b 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3250,9 +3250,10 @@ static int adv7842_subscribe_event(struct v4l2_subdev *sd, static int adv7842_registered(struct v4l2_subdev *sd) { struct adv7842_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); int err; - err = cec_register_adapter(state->cec_adap); + err = cec_register_adapter(state->cec_adap, &client->dev); if (err) cec_delete_adapter(state->cec_adap); return err; @@ -3568,8 +3569,7 @@ static int adv7842_probe(struct i2c_client *client, state->cec_adap = cec_allocate_adapter(&adv7842_cec_adap_ops, state, dev_name(&client->dev), CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV7842_MAX_ADDRS, - &client->dev); + CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV7842_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) goto err_entity; diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index f9f878b8e0a7..cb4933592a3c 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -216,7 +216,6 @@ static const struct cec_adap_ops vivid_cec_adap_ops = { struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, unsigned int idx, - struct device *parent, bool is_source) { char name[sizeof(dev->vid_out_dev.name) + 2]; @@ -227,5 +226,5 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, idx); return cec_allocate_adapter(&vivid_cec_adap_ops, dev, - name, caps, 1, parent); + name, caps, 1); } diff --git a/drivers/media/platform/vivid/vivid-cec.h b/drivers/media/platform/vivid/vivid-cec.h index 97892afa6b3b..3926b1422777 100644 --- a/drivers/media/platform/vivid/vivid-cec.h +++ b/drivers/media/platform/vivid/vivid-cec.h @@ -20,7 +20,6 @@ #ifdef CONFIG_VIDEO_VIVID_CEC struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, unsigned int idx, - struct device *parent, bool is_source); void vivid_cec_bus_free_work(struct vivid_dev *dev); diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index b8ef836766df..51e37812ec98 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -1167,12 +1167,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (in_type_counter[HDMI]) { struct cec_adapter *adap; - adap = vivid_cec_alloc_adap(dev, 0, &pdev->dev, false); + adap = vivid_cec_alloc_adap(dev, 0, false); ret = PTR_ERR_OR_ZERO(adap); if (ret < 0) goto unreg_dev; dev->cec_rx_adap = adap; - ret = cec_register_adapter(adap); + ret = cec_register_adapter(adap, &pdev->dev); if (ret < 0) { cec_delete_adapter(adap); dev->cec_rx_adap = NULL; @@ -1222,13 +1222,12 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->output_type[i] != HDMI) continue; dev->cec_output2bus_map[i] = bus_cnt; - adap = vivid_cec_alloc_adap(dev, bus_cnt, - &pdev->dev, true); + adap = vivid_cec_alloc_adap(dev, bus_cnt, true); ret = PTR_ERR_OR_ZERO(adap); if (ret < 0) goto unreg_dev; dev->cec_tx_adap[bus_cnt] = adap; - ret = cec_register_adapter(adap); + ret = cec_register_adapter(adap, &pdev->dev); if (ret < 0) { cec_delete_adapter(adap); dev->cec_tx_adap[bus_cnt] = NULL; diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index 9092494bb43c..7c18daeb0ade 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -659,7 +659,7 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->serio = serio; pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, - "HDMI CEC", caps, 1, &serio->dev); + "HDMI CEC", caps, 1); err = PTR_ERR_OR_ZERO(pulse8->adap); if (err < 0) goto free_device; @@ -679,7 +679,7 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) if (err) goto close_serio; - err = cec_register_adapter(pulse8->adap); + err = cec_register_adapter(pulse8->adap, &serio->dev); if (err < 0) goto close_serio; diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 33e435855d66..2a07968b5ac6 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -203,12 +203,11 @@ static int s5p_cec_probe(struct platform_device *pdev) cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME, CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, - 1, &pdev->dev); + CEC_CAP_PASSTHROUGH | CEC_CAP_RC, 1); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; - ret = cec_register_adapter(cec->adap); + ret = cec_register_adapter(cec->adap, &pdev->dev); if (ret) { cec_delete_adapter(cec->adap); return ret; diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c index eed1fd6bbefa..3c25638a9610 100644 --- a/drivers/staging/media/st-cec/stih-cec.c +++ b/drivers/staging/media/st-cec/stih-cec.c @@ -335,13 +335,12 @@ static int stih_cec_probe(struct platform_device *pdev) cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, CEC_NAME, CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | - CEC_CAP_PHYS_ADDR | CEC_CAP_TRANSMIT, - 1, &pdev->dev); + CEC_CAP_PHYS_ADDR | CEC_CAP_TRANSMIT, 1); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; - ret = cec_register_adapter(cec->adap); + ret = cec_register_adapter(cec->adap, &pdev->dev); if (ret) { cec_delete_adapter(cec->adap); return ret; diff --git a/include/media/cec.h b/include/media/cec.h index 717eaf552f3d..96a0aa770d61 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -35,7 +35,6 @@ * struct cec_devnode - cec device node * @dev: cec device * @cdev: cec character device - * @parent: parent device * @minor: device node minor number * @registered: the device was correctly registered * @unregistered: the device was unregistered @@ -51,7 +50,6 @@ struct cec_devnode { /* sysfs */ struct device dev; struct cdev cdev; - struct device *parent; /* device info */ int minor; @@ -198,9 +196,8 @@ static inline bool cec_is_sink(const struct cec_adapter *adap) #if IS_ENABLED(CONFIG_MEDIA_CEC_SUPPORT) struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, - void *priv, const char *name, u32 caps, u8 available_las, - struct device *parent); -int cec_register_adapter(struct cec_adapter *adap); + void *priv, const char *name, u32 caps, u8 available_las); +int cec_register_adapter(struct cec_adapter *adap, struct device *parent); void cec_unregister_adapter(struct cec_adapter *adap); void cec_delete_adapter(struct cec_adapter *adap); @@ -218,7 +215,8 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); #else -static inline int cec_register_adapter(struct cec_adapter *adap) +static inline int cec_register_adapter(struct cec_adapter *adap, + struct device *parent) { return 0; } -- cgit v1.2.3 From 94868d612fd917487a6c9a4b08b578031db3e717 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 15 Nov 2016 10:06:24 -0200 Subject: [media] v4l2-tpg: Init hv_enc field with a valid value Zero is not a valid value for hsv_enc. Set the field to a valid initial value. This is not a problem for vivid, because it sets the field to 180 via tpg_s_hsv_enc() on the control initialization, but it might be a source of errors for other drivers that use this code. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 28d7b072d867..e47b46e2d26c 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -117,6 +117,7 @@ void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h) tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24); tpg->colorspace = V4L2_COLORSPACE_SRGB; tpg->perc_fill = 100; + tpg->hsv_enc = V4L2_HSV_ENC_180; } EXPORT_SYMBOL_GPL(tpg_init); -- cgit v1.2.3 From a000f0d3995f622410d433a01e94fbfb45969e27 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 15 Nov 2016 10:06:25 -0200 Subject: [media] vivid: Set color_enc on HSV formats HSV formats were missing the color encoding, which leads to an invalid ycbcr_enc value during get_fmt and try_fmt. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-vid-common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 3d003fb913ed..5fc010f6ce67 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -447,6 +447,7 @@ struct vivid_fmt vivid_formats[] = { }, { .fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */ + .color_enc = TGP_COLOR_ENC_HSV, .vdownsampling = { 1 }, .bit_depth = { 24 }, .planes = 1, @@ -454,6 +455,7 @@ struct vivid_fmt vivid_formats[] = { }, { .fourcc = V4L2_PIX_FMT_HSV32, /* HSV 32bits */ + .color_enc = TGP_COLOR_ENC_HSV, .vdownsampling = { 1 }, .bit_depth = { 32 }, .planes = 1, -- cgit v1.2.3 From 3605163d98dbcd37e5d6f51c4982d7da77bdcba9 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 16 Nov 2016 07:04:50 -0200 Subject: [media] s5p-mfc: Set DMA_ATTR_ALLOC_SINGLE_PAGES We do video allocation all the time and we need it to be fast. Plus TLB efficiency isn't terribly important for video. That means we want to set DMA_ATTR_ALLOC_SINGLE_PAGES. See also the previous change (commit 14d3ae2efeed "ARM: dma-mapping: Use DMA_ATTR_ALLOC_SINGLE_PAGES hint to optimize allocation"). [m.szyprowski: rebased patch onto v4.9-rc1 and adapted changes to latest videbuf2 changes, this simplifies code changes to only set proper dma attribute flag and comment the reason for it, added commit id of arch/arm/mm patch] Signed-off-by: Douglas Anderson Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 320124352e82..da735cda2882 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -851,6 +851,11 @@ static int s5p_mfc_open(struct file *file) ret = -ENOENT; goto err_queue_init; } + /* + * We'll do mostly sequential access, so sacrifice TLB efficiency for + * faster allocation. + */ + q->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES; q->mem_ops = &vb2_dma_contig_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(q); @@ -881,6 +886,12 @@ static int s5p_mfc_open(struct file *file) * will keep the value of bytesused intact. */ q->allow_zero_bytesused = 1; + + /* + * We'll do mostly sequential access, so sacrifice TLB efficiency for + * faster allocation. + */ + q->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES; q->mem_ops = &vb2_dma_contig_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(q); -- cgit v1.2.3 From 0a79ef333dfa7f25abc2eab10f3a11bbdf9a9f17 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:51 -0200 Subject: [media] s5p-mfc: Use printk_ratelimited for reporting ioctl errors Some applications don't check error codes from QBUF/DQBUF ioctls, so don't spam kernel log with errors if they fall into endless loop trying to queue next buffer after a failure. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_debug.h | 6 ++++++ drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h index 5936923c631c..1936a5b868f5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h @@ -39,6 +39,12 @@ extern int mfc_debug_level; __func__, __LINE__, ##args); \ } while (0) +#define mfc_err_limited(fmt, args...) \ + do { \ + printk_ratelimited(KERN_ERR "%s:%d: " fmt, \ + __func__, __LINE__, ##args); \ + } while (0) + #define mfc_info(fmt, args...) \ do { \ printk(KERN_INFO "%s:%d: " fmt, \ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index cf787eae11b7..367ef8e8dbf0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -642,7 +642,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) int ret; if (ctx->state == MFCINST_ERROR) { - mfc_err("Call on DQBUF after unrecoverable error\n"); + mfc_err_limited("Call on DQBUF after unrecoverable error\n"); return -EIO; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index fcc2e054c61f..e39d9e06e299 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1268,7 +1268,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) int ret; if (ctx->state == MFCINST_ERROR) { - mfc_err("Call on DQBUF after unrecoverable error\n"); + mfc_err_limited("Call on DQBUF after unrecoverable error\n"); return -EIO; } if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { -- cgit v1.2.3 From 2e4e084465dd21f8a76c9fc5da496009d5803ada Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:52 -0200 Subject: [media] s5p-mfc: Remove special clock rate management The maximum rate of special clock depends on SoC variant and should be set in device tree via assigned-clock-rates property, so remove the code which forces special clock to 200MHz. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index b5806ab7ac31..818c04646061 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -20,7 +20,6 @@ #define MFC_GATE_CLK_NAME "mfc" #define MFC_SCLK_NAME "sclk_mfc" -#define MFC_SCLK_RATE (200 * 1000000) #define CLK_DEBUG @@ -57,7 +56,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) mfc_info("Failed to get MFC special clock control\n"); pm->clock = NULL; } else { - clk_set_rate(pm->clock, MFC_SCLK_RATE); ret = clk_prepare_enable(pm->clock); if (ret) { mfc_err("Failed to enable MFC special clock\n"); -- cgit v1.2.3 From 8accb8fdf6ea6e1e4eb513e88e06d629ed01103b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:53 -0200 Subject: [media] s5p-mfc: Ensure that clock is disabled before turning power off Move clock disabling before turning power off. This will enable later to add calls to clk_prepare/unprepare in the s5p_mfc_power_off() function to avoid keeping clocks prepared all the time when driver is bound. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index da735cda2882..991649111e77 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -963,11 +963,13 @@ static int s5p_mfc_release(struct file *file) mfc_debug(2, "Last instance\n"); s5p_mfc_deinit_hw(dev); del_timer_sync(&dev->watchdog_timer); + s5p_mfc_clock_off(); if (s5p_mfc_power_off() < 0) mfc_err("Power off failed\n"); + } else { + mfc_debug(2, "Shutting down clock\n"); + s5p_mfc_clock_off(); } - mfc_debug(2, "Shutting down clock\n"); - s5p_mfc_clock_off(); } if (dev) dev->ctx[ctx->num] = NULL; -- cgit v1.2.3 From 7e55a016fac080118a634179405c821c31d8bd2e Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:54 -0200 Subject: [media] s5p-mfc: Remove dead conditional code CONFIG_PM is always enabled on Exynos platforms, so remove dead code related to early development of MFC driver on platform without PM support. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 22 ------------------ drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 1 - drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 30 +++++-------------------- 3 files changed, 5 insertions(+), 48 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 991649111e77..b34ccbefbb02 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1405,31 +1405,9 @@ static int s5p_mfc_resume(struct device *dev) } #endif -#ifdef CONFIG_PM -static int s5p_mfc_runtime_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev); - - atomic_set(&m_dev->pm.power, 0); - return 0; -} - -static int s5p_mfc_runtime_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev); - - atomic_set(&m_dev->pm.power, 1); - return 0; -} -#endif - /* Power management */ static const struct dev_pm_ops s5p_mfc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume) - SET_RUNTIME_PM_OPS(s5p_mfc_runtime_suspend, s5p_mfc_runtime_resume, - NULL) }; static struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index c068ee3ece6e..58b15c212dd2 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -200,7 +200,6 @@ struct s5p_mfc_pm { struct clk *clock; struct clk *clock_gate; bool use_clock_gating; - atomic_t power; struct device *device; }; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 818c04646061..11a918eb7564 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -21,14 +21,9 @@ #define MFC_GATE_CLK_NAME "mfc" #define MFC_SCLK_NAME "sclk_mfc" -#define CLK_DEBUG - static struct s5p_mfc_pm *pm; static struct s5p_mfc_dev *p_dev; - -#ifdef CLK_DEBUG static atomic_t clk_ref; -#endif int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { @@ -64,14 +59,10 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) } } - atomic_set(&pm->power, 0); -#ifdef CONFIG_PM pm->device = &dev->plat_dev->dev; pm_runtime_enable(pm->device); -#endif -#ifdef CLK_DEBUG atomic_set(&clk_ref, 0); -#endif + return 0; err_s_clk: @@ -95,18 +86,16 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) clk_unprepare(pm->clock_gate); clk_put(pm->clock_gate); pm->clock_gate = NULL; -#ifdef CONFIG_PM pm_runtime_disable(pm->device); -#endif } int s5p_mfc_clock_on(void) { int ret = 0; -#ifdef CLK_DEBUG + atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); -#endif + if (!pm->use_clock_gating) return 0; if (!IS_ERR_OR_NULL(pm->clock_gate)) @@ -116,10 +105,9 @@ int s5p_mfc_clock_on(void) void s5p_mfc_clock_off(void) { -#ifdef CLK_DEBUG atomic_dec(&clk_ref); mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); -#endif + if (!pm->use_clock_gating) return; if (!IS_ERR_OR_NULL(pm->clock_gate)) @@ -130,13 +118,10 @@ int s5p_mfc_power_on(void) { int ret = 0; -#ifdef CONFIG_PM ret = pm_runtime_get_sync(pm->device); if (ret) return ret; -#else - atomic_set(&pm->power, 1); -#endif + if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) ret = clk_enable(pm->clock_gate); return ret; @@ -146,12 +131,7 @@ int s5p_mfc_power_off(void) { if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) clk_disable(pm->clock_gate); -#ifdef CONFIG_PM return pm_runtime_put_sync(pm->device); -#else - atomic_set(&pm->power, 0); - return 0; -#endif } -- cgit v1.2.3 From 387e08e2021022e764a235df6c1f0ed3d861f711 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:55 -0200 Subject: [media] s5p-mfc: Kill all IS_ERR_OR_NULL in clocks management code After commit "s5p-mfc: Fix clock management in s5p_mfc_release function" all clocks related functions are called only when MFC device is really available, so there is no additional check needed for NULL gate clocks. This patch simplifies the code and kills IS_ERR_OR_NULL macro usage. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 11a918eb7564..b514584cf00d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -91,16 +91,12 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) int s5p_mfc_clock_on(void) { - int ret = 0; - atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); if (!pm->use_clock_gating) return 0; - if (!IS_ERR_OR_NULL(pm->clock_gate)) - ret = clk_enable(pm->clock_gate); - return ret; + return clk_enable(pm->clock_gate); } void s5p_mfc_clock_off(void) @@ -110,8 +106,7 @@ void s5p_mfc_clock_off(void) if (!pm->use_clock_gating) return; - if (!IS_ERR_OR_NULL(pm->clock_gate)) - clk_disable(pm->clock_gate); + clk_disable(pm->clock_gate); } int s5p_mfc_power_on(void) @@ -122,14 +117,14 @@ int s5p_mfc_power_on(void) if (ret) return ret; - if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) + if (!pm->use_clock_gating) ret = clk_enable(pm->clock_gate); return ret; } int s5p_mfc_power_off(void) { - if (!pm->use_clock_gating && !IS_ERR_OR_NULL(pm->clock_gate)) + if (!pm->use_clock_gating) clk_disable(pm->clock_gate); return pm_runtime_put_sync(pm->device); } -- cgit v1.2.3 From 741f4331d07fd670b9ebb5eeda18208b6eb2ba28 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:56 -0200 Subject: [media] s5p-mfc: Don't keep clock prepared all the time This patch moves preparation of clocks from s5p_mfc_init_pm() (driver probe) to s5p_mfc_power_on() (start of device operation). This change will allow to use runtime power usage optimization on newer Samsung Exynos platforms (for example Exynos 5433). Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 52 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index b514584cf00d..796dac85746a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -39,23 +39,11 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) goto err_g_ip_clk; } - ret = clk_prepare(pm->clock_gate); - if (ret) { - mfc_err("Failed to prepare clock-gating control\n"); - goto err_p_ip_clk; - } - if (dev->variant->version != MFC_VERSION_V6) { pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME); if (IS_ERR(pm->clock)) { mfc_info("Failed to get MFC special clock control\n"); pm->clock = NULL; - } else { - ret = clk_prepare_enable(pm->clock); - if (ret) { - mfc_err("Failed to enable MFC special clock\n"); - goto err_s_clk; - } } } @@ -65,10 +53,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) return 0; -err_s_clk: - clk_put(pm->clock); - pm->clock = NULL; -err_p_ip_clk: clk_put(pm->clock_gate); pm->clock_gate = NULL; err_g_ip_clk: @@ -79,11 +63,9 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) { if (dev->variant->version != MFC_VERSION_V6 && pm->clock) { - clk_disable_unprepare(pm->clock); clk_put(pm->clock); pm->clock = NULL; } - clk_unprepare(pm->clock_gate); clk_put(pm->clock_gate); pm->clock_gate = NULL; pm_runtime_disable(pm->device); @@ -111,22 +93,44 @@ void s5p_mfc_clock_off(void) int s5p_mfc_power_on(void) { - int ret = 0; + int ret; ret = pm_runtime_get_sync(pm->device); if (ret) return ret; - if (!pm->use_clock_gating) - ret = clk_enable(pm->clock_gate); + ret = clk_prepare_enable(pm->clock_gate); + if (ret) + goto err_pm; + + if (pm->clock) { + ret = clk_prepare_enable(pm->clock); + if (ret) + goto err_gate; + } + + if (pm->use_clock_gating) + clk_disable(pm->clock_gate); + return 0; + +err_gate: + clk_disable_unprepare(pm->clock_gate); +err_pm: + pm_runtime_put_sync(pm->device); return ret; + } int s5p_mfc_power_off(void) { - if (!pm->use_clock_gating) - clk_disable(pm->clock_gate); + if (pm->clock) + clk_disable_unprepare(pm->clock); + + if (pm->use_clock_gating) + clk_unprepare(pm->clock_gate); + else + clk_disable_unprepare(pm->clock_gate); + return pm_runtime_put_sync(pm->device); } - -- cgit v1.2.3 From 1bce6fb3edf17a0444226fbbd0f568559512f941 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:57 -0200 Subject: [media] s5p-mfc: Rework clock handling This patch changes the code for handling clocks. Now clocks are defined per each device variant, what is a preparation for adding support for Exynos 5433 MFC V8, which has more clocks than all previous versions. Also use devm_clk_get() to simplify cleanup path. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 8 ++ drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 9 ++- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 98 ++++++++++--------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index b34ccbefbb02..5fcf17008ded 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1434,6 +1434,8 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { .buf_size = &buf_size_v5, .buf_align = &mfc_buf_align_v5, .fw_name[0] = "s5p-mfc.fw", + .clk_names = {"mfc", "sclk_mfc"}, + .num_clocks = 2, .use_clock_gating = true, }; @@ -1467,6 +1469,8 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = { * for init buffer command */ .fw_name[1] = "s5p-mfc-v6-v2.fw", + .clk_names = {"mfc"}, + .num_clocks = 1, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = { @@ -1494,6 +1498,8 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = { .buf_size = &buf_size_v7, .buf_align = &mfc_buf_align_v7, .fw_name[0] = "s5p-mfc-v7.fw", + .clk_names = {"mfc", "sclk_mfc"}, + .num_clocks = 2, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { @@ -1521,6 +1527,8 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = { .buf_size = &buf_size_v8, .buf_align = &mfc_buf_align_v8, .fw_name[0] = "s5p-mfc-v8.fw", + .clk_names = {"mfc"}, + .num_clocks = 1, }; static const struct of_device_id exynos_mfc_match[] = { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 58b15c212dd2..ab23236aa942 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -104,6 +104,8 @@ static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b) #define S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET 16 #define S5P_MFC_R2H_CMD_ERR_RET 32 +#define MFC_MAX_CLOCKS 4 + #define mfc_read(dev, offset) readl(dev->regs_base + (offset)) #define mfc_write(dev, data, offset) writel((data), dev->regs_base + \ (offset)) @@ -197,9 +199,12 @@ struct s5p_mfc_buf { * struct s5p_mfc_pm - power management data structure */ struct s5p_mfc_pm { - struct clk *clock; struct clk *clock_gate; + const char **clk_names; + struct clk *clocks[MFC_MAX_CLOCKS]; + int num_clocks; bool use_clock_gating; + struct device *device; }; @@ -235,6 +240,8 @@ struct s5p_mfc_variant { struct s5p_mfc_buf_size *buf_size; struct s5p_mfc_buf_align *buf_align; char *fw_name[MFC_FW_MAX_VERSIONS]; + const char *clk_names[MFC_MAX_CLOCKS]; + int num_clocks; bool use_clock_gating; }; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 796dac85746a..eb85cedc5ef3 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -18,56 +18,42 @@ #include "s5p_mfc_debug.h" #include "s5p_mfc_pm.h" -#define MFC_GATE_CLK_NAME "mfc" -#define MFC_SCLK_NAME "sclk_mfc" - static struct s5p_mfc_pm *pm; static struct s5p_mfc_dev *p_dev; static atomic_t clk_ref; int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { - int ret = 0; + int i; pm = &dev->pm; p_dev = dev; - pm->use_clock_gating = dev->variant->use_clock_gating; - pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME); - if (IS_ERR(pm->clock_gate)) { - mfc_err("Failed to get clock-gating control\n"); - ret = PTR_ERR(pm->clock_gate); - goto err_g_ip_clk; - } - if (dev->variant->version != MFC_VERSION_V6) { - pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME); - if (IS_ERR(pm->clock)) { - mfc_info("Failed to get MFC special clock control\n"); - pm->clock = NULL; + pm->num_clocks = dev->variant->num_clocks; + pm->clk_names = dev->variant->clk_names; + pm->device = &dev->plat_dev->dev; + pm->clock_gate = NULL; + + /* clock control */ + for (i = 0; i < pm->num_clocks; i++) { + pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]); + if (IS_ERR(pm->clocks[i])) { + mfc_err("Failed to get clock: %s\n", + pm->clk_names[i]); + return PTR_ERR(pm->clocks[i]); } } - pm->device = &dev->plat_dev->dev; + if (dev->variant->use_clock_gating) + pm->clock_gate = pm->clocks[0]; + pm_runtime_enable(pm->device); atomic_set(&clk_ref, 0); - return 0; - - clk_put(pm->clock_gate); - pm->clock_gate = NULL; -err_g_ip_clk: - return ret; } void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) { - if (dev->variant->version != MFC_VERSION_V6 && - pm->clock) { - clk_put(pm->clock); - pm->clock = NULL; - } - clk_put(pm->clock_gate); - pm->clock_gate = NULL; pm_runtime_disable(pm->device); } @@ -76,8 +62,6 @@ int s5p_mfc_clock_on(void) atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); - if (!pm->use_clock_gating) - return 0; return clk_enable(pm->clock_gate); } @@ -86,50 +70,48 @@ void s5p_mfc_clock_off(void) atomic_dec(&clk_ref); mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); - if (!pm->use_clock_gating) - return; clk_disable(pm->clock_gate); } int s5p_mfc_power_on(void) { - int ret; + int i, ret = 0; ret = pm_runtime_get_sync(pm->device); - if (ret) + if (ret < 0) return ret; - ret = clk_prepare_enable(pm->clock_gate); - if (ret) - goto err_pm; - - if (pm->clock) { - ret = clk_prepare_enable(pm->clock); - if (ret) - goto err_gate; + /* clock control */ + for (i = 0; i < pm->num_clocks; i++) { + ret = clk_prepare_enable(pm->clocks[i]); + if (ret < 0) { + mfc_err("clock prepare failed for clock: %s\n", + pm->clk_names[i]); + i++; + goto err; + } } - if (pm->use_clock_gating) - clk_disable(pm->clock_gate); - return 0; + /* prepare for software clock gating */ + clk_disable(pm->clock_gate); -err_gate: - clk_disable_unprepare(pm->clock_gate); -err_pm: - pm_runtime_put_sync(pm->device); + return 0; +err: + while (--i > 0) + clk_disable_unprepare(pm->clocks[i]); + pm_runtime_put(pm->device); return ret; - } int s5p_mfc_power_off(void) { - if (pm->clock) - clk_disable_unprepare(pm->clock); + int i; + + /* finish software clock gating */ + clk_enable(pm->clock_gate); - if (pm->use_clock_gating) - clk_unprepare(pm->clock_gate); - else - clk_disable_unprepare(pm->clock_gate); + for (i = 0; i < pm->num_clocks; i++) + clk_disable_unprepare(pm->clocks[i]); return pm_runtime_put_sync(pm->device); } -- cgit v1.2.3 From 003611334d5592984e319e08c6b66825aca00290 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 16 Nov 2016 07:04:58 -0200 Subject: [media] s5p-mfc: Add support for MFC v8 available in Exynos 5433 SoCs Exynos5433 SoC has MFC v8 hardware module, but it has more complex clock hierarchy, so a new compatible is added. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/s5p-mfc.txt | 1 + drivers/media/platform/s5p-mfc/s5p_mfc.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt index 92c94f5ecbf1..2c901286d818 100644 --- a/Documentation/devicetree/bindings/media/s5p-mfc.txt +++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt @@ -12,6 +12,7 @@ Required properties: (b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs (c) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC (d) "samsung,mfc-v8" for MFC v8 present in Exynos5800 SoC + (e) "samsung,exynos5433-mfc" for MFC v8 present in Exynos5433 SoC - reg : Physical base address of the IP registers and length of memory mapped region. diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 5fcf17008ded..bb0a5887c9a9 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1531,6 +1531,17 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = { .num_clocks = 1, }; +static struct s5p_mfc_variant mfc_drvdata_v8_5433 = { + .version = MFC_VERSION_V8, + .version_bit = MFC_V8_BIT, + .port_num = MFC_NUM_PORTS_V8, + .buf_size = &buf_size_v8, + .buf_align = &mfc_buf_align_v8, + .fw_name[0] = "s5p-mfc-v8.fw", + .clk_names = {"pclk", "aclk", "aclk_xiu"}, + .num_clocks = 3, +}; + static const struct of_device_id exynos_mfc_match[] = { { .compatible = "samsung,mfc-v5", @@ -1544,6 +1555,9 @@ static const struct of_device_id exynos_mfc_match[] = { }, { .compatible = "samsung,mfc-v8", .data = &mfc_drvdata_v8, + }, { + .compatible = "samsung,exynos5433-mfc", + .data = &mfc_drvdata_v8_5433, }, {}, }; -- cgit v1.2.3 From b40769ee2ed09ed6c6da33b0cbdf423ff94f685b Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 26 Nov 2016 19:31:24 -0200 Subject: [media] lirc: fix error paths in lirc_cdev_add() "c77d17c0 [media] lirc: use-after free" introduces two problems: cdev_del() can be called with a NULL argument, and the kobject_put() path will cause a double free. Reported-by: Dan Carpenter Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index d3039efb4e7c..3854809e8531 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -157,13 +157,13 @@ static const struct file_operations lirc_dev_fops = { static int lirc_cdev_add(struct irctl *ir) { - int retval = -ENOMEM; struct lirc_driver *d = &ir->d; struct cdev *cdev; + int retval; cdev = cdev_alloc(); if (!cdev) - goto err_out; + return -ENOMEM; if (d->fops) { cdev->ops = d->fops; @@ -177,10 +177,8 @@ static int lirc_cdev_add(struct irctl *ir) goto err_out; retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); - if (retval) { - kobject_put(&cdev->kobj); + if (retval) goto err_out; - } ir->cdev = cdev; -- cgit v1.2.3 From d930b5b5bf122a61952cfebabb1e618682a2631a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 30 Nov 2016 19:36:14 -0200 Subject: [media] mn88473: fix chip id check on probe A register used to identify chip during probe was overwritten during firmware download and due to that later probe's for warm chip were failing. Detect chip from the another register, which is located on different register bank 2. Fixes: 7908fad99a6c ("[media] mn88473: finalize driver") Cc: # v4.8+ Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index f3b59a5827d9..c221c7d2ac3e 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -648,18 +648,6 @@ static int mn88473_probe(struct i2c_client *client, goto err_kfree; } - /* Check demod answers with correct chip id */ - ret = regmap_read(dev->regmap[0], 0xff, &uitmp); - if (ret) - goto err_regmap_0_regmap_exit; - - dev_dbg(&client->dev, "chip id=%02x\n", uitmp); - - if (uitmp != 0x03) { - ret = -ENODEV; - goto err_regmap_0_regmap_exit; - } - /* * Chip has three I2C addresses for different register banks. Used * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients, @@ -696,6 +684,18 @@ static int mn88473_probe(struct i2c_client *client, } i2c_set_clientdata(dev->client[2], dev); + /* Check demod answers with correct chip id */ + ret = regmap_read(dev->regmap[2], 0xff, &uitmp); + if (ret) + goto err_regmap_2_regmap_exit; + + dev_dbg(&client->dev, "chip id=%02x\n", uitmp); + + if (uitmp != 0x03) { + ret = -ENODEV; + goto err_regmap_2_regmap_exit; + } + /* Sleep because chip is active by default */ ret = regmap_write(dev->regmap[2], 0x05, 0x3e); if (ret) -- cgit v1.2.3 From 365fe4e0ce218dc5ad10df17b150a366b6015499 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 30 Nov 2016 22:08:27 -0200 Subject: [media] mn88472: fix chip id check on probe A register used to identify chip during probe was overwritten during firmware download and due to that later probe's for warm chip were failing. Detect chip from the another register, which is located on different register bank 2. Fixes: 94d0eaa41987 ("[media] mn88472: move out of staging to media") Cc: # v4.8+ Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index b6f5f8337cfd..29dd13b36c28 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -488,18 +488,6 @@ static int mn88472_probe(struct i2c_client *client, goto err_kfree; } - /* Check demod answers with correct chip id */ - ret = regmap_read(dev->regmap[0], 0xff, &utmp); - if (ret) - goto err_regmap_0_regmap_exit; - - dev_dbg(&client->dev, "chip id=%02x\n", utmp); - - if (utmp != 0x02) { - ret = -ENODEV; - goto err_regmap_0_regmap_exit; - } - /* * Chip has three I2C addresses for different register banks. Used * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients, @@ -536,6 +524,18 @@ static int mn88472_probe(struct i2c_client *client, } i2c_set_clientdata(dev->client[2], dev); + /* Check demod answers with correct chip id */ + ret = regmap_read(dev->regmap[2], 0xff, &utmp); + if (ret) + goto err_regmap_2_regmap_exit; + + dev_dbg(&client->dev, "chip id=%02x\n", utmp); + + if (utmp != 0x02) { + ret = -ENODEV; + goto err_regmap_2_regmap_exit; + } + /* Sleep because chip is active by default */ ret = regmap_write(dev->regmap[2], 0x05, 0x3e); if (ret) -- cgit v1.2.3 From ea48c3680829c0c522a799a4a9e0fb6cc5afd0a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Dec 2016 14:53:26 -0200 Subject: [media] em28xx: don't change the device's name Changing the device name, causes it to be unable to remove the sysfs file, causing troubles if a device is removed and then re-inserted. [ 1010.310320] WARNING: CPU: 3 PID: 119 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x7b/0x90 [ 1010.310323] sysfs: cannot create duplicate filename '/bus/usb/devices/1-3.3' [ 1010.310325] Modules linked in: lgdt330x em28xx_dvb dvb_core em28xx_alsa tuner_xc2028 tuner tvp5150 em28xx_v4l videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core em28xx tveeprom v4l2_common videodev media xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables x_tables cmac bnep cpufreq_powersave cpufreq_conservative cpufreq_userspace binfmt_misc parport_pc ppdev lp parport snd_hda_codec_hdmi iTCO_wdt snd_hda_codec_realtek iTCO_vendor_support snd_hda_codec_generic arc4 intel_rapl x86_pkg_temp_thermal iwlmvm intel_powerclamp coretemp kvm_intel mac80211 kvm i915 [ 1010.310383] irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel iwlwifi pl2303 aesni_intel btusb aes_x86_64 usbserial lrw btrtl gf128mul glue_helper btbcm ablk_helper cryptd btintel bluetooth drm_kms_helper cfg80211 drm psmouse pcspkr i2c_i801 e1000e serio_raw snd_hda_intel snd_soc_rt5640 snd_hda_codec snd_soc_rl6231 snd_soc_ssm4567 mei_me i2c_smbus rfkill snd_hda_core ptp mei snd_soc_core ehci_pci sg lpc_ich shpchp mfd_core ehci_hcd pps_core snd_hwdep i2c_algo_bit snd_compress snd_pcm sdhci_acpi snd_timer battery snd sdhci elan_i2c snd_soc_sst_acpi mmc_core fjes dw_dmac i2c_hid soundcore snd_soc_sst_match i2c_designware_platform video i2c_designware_core acpi_pad acpi_als kfifo_buf tpm_tis button industrialio tpm_tis_core tpm ext4 crc16 jbd2 fscrypto mbcache dm_mod joydev evdev hid_logitech_hidpp [ 1010.310449] sd_mod hid_logitech_dj usbhid hid ahci libahci crc32c_intel libata xhci_pci xhci_hcd scsi_mod usbcore fan thermal [ 1010.310464] CPU: 3 PID: 119 Comm: kworker/3:2 Not tainted 4.9.0-rc8+ #14 [ 1010.310466] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015 [ 1010.310487] Workqueue: usb_hub_wq hub_event [usbcore] [ 1010.310490] 0000000000000000 ffffffff848f56c5 ffff8803b1f7f858 0000000000000000 [ 1010.310496] ffffffff8414f8f8 ffff88030000001f ffffed00763eff07 ffff8803b1f7f8f0 [ 1010.310501] ffff8803b3ea1e60 0000000000000001 ffffffffffffffef ffff8803b45c6840 [ 1010.310505] Call Trace: [ 1010.310517] [] ? dump_stack+0x5c/0x77 [ 1010.310522] [] ? __warn+0x168/0x1a0 [ 1010.310526] [] ? warn_slowpath_fmt+0xb4/0xf0 [ 1010.310529] [] ? __warn+0x1a0/0x1a0 [ 1010.310534] [] ? kasan_kmalloc+0xa6/0xd0 [ 1010.310539] [] ? kernfs_path_from_node+0x4a/0x60 [ 1010.310543] [] ? sysfs_warn_dup+0x7b/0x90 [ 1010.310547] [] ? sysfs_do_create_link_sd.isra.2+0xb6/0xd0 [ 1010.310553] [] ? bus_add_device+0x318/0x6b0 [ 1010.310557] [] ? sysfs_create_groups+0x83/0x110 [ 1010.310562] [] ? device_add+0x777/0x1350 [ 1010.310567] [] ? device_private_init+0x180/0x180 [ 1010.310583] [] ? usb_new_device+0x707/0x1030 [usbcore] [ 1010.310598] [] ? hub_event+0x1d65/0x3280 [usbcore] [ 1010.310604] [] ? account_entity_dequeue+0x30b/0x4a0 [ 1010.310618] [] ? hub_port_debounce+0x280/0x280 [usbcore] [ 1010.310624] [] ? compat_start_thread+0x80/0x80 [ 1010.310629] [] ? __schedule+0x704/0x1770 [ 1010.310633] [] ? io_schedule_timeout+0x390/0x390 [ 1010.310638] [] ? cache_reap+0x173/0x200 [ 1010.310642] [] ? process_one_work+0x4ed/0xe60 [ 1010.310646] [] ? worker_thread+0xe2/0xfd0 [ 1010.310650] [] ? __wake_up_common+0xbc/0x160 [ 1010.310654] [] ? process_one_work+0xe60/0xe60 [ 1010.310658] [] ? kthread+0x1cc/0x220 [ 1010.310663] [] ? kthread_park+0x80/0x80 [ 1010.310667] [] ? kthread_park+0x80/0x80 [ 1010.310671] [] ? kthread_park+0x80/0x80 [ 1010.310675] [] ? ret_from_fork+0x25/0x30 Tested-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index b516c691b9eb..50e4c6e51ee7 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3236,8 +3236,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, int minor) { int retval; - static const char *default_chip_name = "em28xx"; - const char *chip_name = default_chip_name; + const char *chip_name = NULL; dev->udev = udev; mutex_init(&dev->ctrl_urb_lock); @@ -3324,14 +3323,9 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, break; } } - - dev_set_name(&dev->udev->dev, "%d-%s: %s#%d", - dev->udev->bus->busnum, dev->udev->devpath, - chip_name, dev->devno); - - if (chip_name == default_chip_name) - dev_info(&dev->udev->dev, - "unknown em28xx chip ID (%d)\n", dev->chip_id); + if (!chip_name) + dev_info(&dev->udev->dev, + "unknown em28xx chip ID (%d)\n", dev->chip_id); else dev_info(&dev->udev->dev, "chip ID is %s\n", chip_name); -- cgit v1.2.3 From 29b05e22f5c68c657f5ec30a31023b81124287fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Dec 2016 13:48:10 -0200 Subject: [media] em28xx: use usb_interface for dev_foo() calls The usb_device->dev is not the right device for dev_foo() calls. Instead, it should use usb_interface->dev. Tested-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 34 ++++++------ drivers/media/usb/em28xx/em28xx-camera.c | 30 +++++------ drivers/media/usb/em28xx/em28xx-cards.c | 61 ++++++++++----------- drivers/media/usb/em28xx/em28xx-core.c | 48 ++++++++--------- drivers/media/usb/em28xx/em28xx-dvb.c | 61 ++++++++++----------- drivers/media/usb/em28xx/em28xx-i2c.c | 92 ++++++++++++++++---------------- drivers/media/usb/em28xx/em28xx-input.c | 32 +++++------ drivers/media/usb/em28xx/em28xx-vbi.c | 2 +- drivers/media/usb/em28xx/em28xx-video.c | 68 +++++++++++------------ drivers/media/usb/em28xx/em28xx.h | 1 + 10 files changed, 216 insertions(+), 213 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 7060e5146e31..7f8601427b7f 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define dprintk(fmt, arg...) do { \ if (debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "video: %s: " fmt, __func__, ## arg); \ } while (0) @@ -166,7 +166,7 @@ static void em28xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "resubmit of audio urb failed (error=%i)\n", status); return; @@ -185,7 +185,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "submit of audio urb failed (error=%i)\n", errCode); em28xx_deinit_isoc_audio(dev); @@ -322,7 +322,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) err: mutex_unlock(&dev->lock); - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Error while configuring em28xx mixer\n"); return ret; } @@ -761,7 +761,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) intf = usb_ifnum_to_if(dev->udev, dev->ifnum); if (intf->num_altsetting <= alt) { - dev_err(&dev->udev->dev, "alt %d doesn't exist on interface %d\n", + dev_err(&dev->intf->dev, "alt %d doesn't exist on interface %d\n", dev->ifnum, alt); return -ENODEV; } @@ -777,14 +777,14 @@ static int em28xx_audio_urb_init(struct em28xx *dev) } if (!ep) { - dev_err(&dev->udev->dev, "Couldn't find an audio endpoint"); + dev_err(&dev->intf->dev, "Couldn't find an audio endpoint"); return -ENODEV; } ep_size = em28xx_audio_ep_packet_size(dev->udev, ep); interval = 1 << (ep->bInterval - 1); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), dev->ifnum, alt, interval, ep_size); @@ -824,7 +824,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) if (urb_size > ep_size * npackets) npackets = DIV_ROUND_UP(urb_size, ep_size); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "Number of URBs: %d, with %d packets and %d size\n", num_urb, npackets, urb_size); @@ -863,7 +863,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "usb_alloc_coherent failed!\n"); em28xx_audio_free_urb(dev); return -ENOMEM; @@ -904,16 +904,16 @@ static int em28xx_audio_init(struct em28xx *dev) return 0; } - dev_info(&dev->udev->dev, "Binding audio extension\n"); + dev_info(&dev->intf->dev, "Binding audio extension\n"); kref_get(&dev->ref); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "em28xx-audio.c: Copyright (C) 2006 Markus Rechberger\n"); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho Chehab\n"); - err = snd_card_new(&dev->udev->dev, index[devnr], "Em28xx Audio", + err = snd_card_new(&dev->intf->dev, index[devnr], "Em28xx Audio", THIS_MODULE, 0, &card); if (err < 0) return err; @@ -961,7 +961,7 @@ static int em28xx_audio_init(struct em28xx *dev) if (err < 0) goto urb_free; - dev_info(&dev->udev->dev, "Audio extension successfully initialized\n"); + dev_info(&dev->intf->dev, "Audio extension successfully initialized\n"); return 0; urb_free: @@ -986,7 +986,7 @@ static int em28xx_audio_fini(struct em28xx *dev) return 0; } - dev_info(&dev->udev->dev, "Closing audio extension\n"); + dev_info(&dev->intf->dev, "Closing audio extension\n"); if (dev->adev.sndcard) { snd_card_disconnect(dev->adev.sndcard); @@ -1010,7 +1010,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - dev_info(&dev->udev->dev, "Suspending audio extension\n"); + dev_info(&dev->intf->dev, "Suspending audio extension\n"); em28xx_deinit_isoc_audio(dev); atomic_set(&dev->adev.stream_started, 0); return 0; @@ -1024,7 +1024,7 @@ static int em28xx_audio_resume(struct em28xx *dev) if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; - dev_info(&dev->udev->dev, "Resuming audio extension\n"); + dev_info(&dev->intf->dev, "Resuming audio extension\n"); /* Nothing to do other than schedule_work() ?? */ schedule_work(&dev->adev.wq_trigger); return 0; diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 2e24b65901ec..89c890ba7dd6 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -121,14 +121,14 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) ret = i2c_master_send(&client, ®, 1); if (ret < 0) { if (ret != -ENXIO) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -138,14 +138,14 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) reg = 0xff; ret = i2c_master_send(&client, ®, 1); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; } ret = i2c_master_recv(&client, (u8 *)&id_be, 2); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -185,16 +185,16 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_MT9M001; break; default: - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unknown Micron sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unsupported sensor detected: %s\n", name); else - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; @@ -225,7 +225,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { if (ret != -ENXIO) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -234,7 +234,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x1d; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -247,7 +247,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x0a; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -256,7 +256,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) reg = 0x0b; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -296,17 +296,17 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) name = "OV9655"; break; default: - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unknown OmniVision sensor detected: 0x%04x\n", id); return 0; } if (dev->em28xx_sensor == EM28XX_NOSENSOR) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unsupported sensor detected: %s\n", name); else - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "sensor %s detected\n", name); dev->i2c_client[dev->def_i2c_bus].addr = client.addr; @@ -331,7 +331,7 @@ int em28xx_detect_sensor(struct em28xx *dev) */ if (dev->em28xx_sensor == EM28XX_NOSENSOR && ret < 0) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "No sensor detected\n"); return -ENODEV; } diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 50e4c6e51ee7..56739ce6ce16 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2677,7 +2677,7 @@ static int em28xx_wait_until_ac97_features_equals(struct em28xx *dev, msleep(50); } - dev_warn(&dev->udev->dev, "AC97 registers access is not reliable !\n"); + dev_warn(&dev->intf->dev, "AC97 registers access is not reliable !\n"); return -ETIMEDOUT; } @@ -2831,7 +2831,7 @@ static int em28xx_hint_board(struct em28xx *dev) dev->model = em28xx_eeprom_hash[i].model; dev->tuner_type = em28xx_eeprom_hash[i].tuner; - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Your board has no unique USB ID.\n" "A hint were successfully done, based on eeprom hash.\n" "This method is not 100%% failproof.\n" @@ -2861,7 +2861,7 @@ static int em28xx_hint_board(struct em28xx *dev) if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { dev->model = em28xx_i2c_hash[i].model; dev->tuner_type = em28xx_i2c_hash[i].tuner; - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Your board has no unique USB ID.\n" "A hint were successfully done, based on i2c devicelist hash.\n" "This method is not 100%% failproof.\n" @@ -2874,7 +2874,7 @@ static int em28xx_hint_board(struct em28xx *dev) } } - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Your board has no unique USB ID and thus need a hint to be detected.\n" "You may try to use card= insmod option to workaround that.\n" "Please send an email with this log to:\n" @@ -2883,10 +2883,10 @@ static int em28xx_hint_board(struct em28xx *dev) "Board i2c devicelist hash is 0x%08lx\n", dev->hash, dev->i2c_hash); - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Here is a list of valid choices for the card= insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, " card=%d -> %s\n", i, em28xx_boards[i].name); } return -1; @@ -2921,7 +2921,7 @@ static void em28xx_card_setup(struct em28xx *dev) * hash identities which has not been determined as yet. */ if (em28xx_hint_board(dev) < 0) - dev_err(&dev->udev->dev, "Board not discovered\n"); + dev_err(&dev->intf->dev, "Board not discovered\n"); else { em28xx_set_model(dev); em28xx_pre_card_setup(dev); @@ -2931,7 +2931,7 @@ static void em28xx_card_setup(struct em28xx *dev) em28xx_set_model(dev); } - dev_info(&dev->udev->dev, "Identified as %s (card=%d)\n", + dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n", dev->board.name, dev->model); dev->tuner_type = em28xx_boards[dev->model].tuner_type; @@ -3030,7 +3030,7 @@ static void em28xx_card_setup(struct em28xx *dev) } if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "\n\n" "The support for this board weren't valid yet.\n" "Please send a report of having this working\n" @@ -3161,7 +3161,7 @@ static int em28xx_media_device_init(struct em28xx *dev, else if (udev->manufacturer) media_device_usb_init(mdev, udev, udev->manufacturer); else - media_device_usb_init(mdev, udev, dev_name(&dev->udev->dev)); + media_device_usb_init(mdev, udev, dev_name(&dev->intf->dev)); dev->media_dev = mdev; #endif @@ -3217,7 +3217,7 @@ void em28xx_free_device(struct kref *ref) { struct em28xx *dev = kref_to_dev(ref); - dev_info(&dev->udev->dev, "Freeing device\n"); + dev_info(&dev->intf->dev, "Freeing device\n"); if (!dev->disconnected) em28xx_release_resources(dev); @@ -3239,6 +3239,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, const char *chip_name = NULL; dev->udev = udev; + dev->intf = interface; mutex_init(&dev->ctrl_urb_lock); spin_lock_init(&dev->slock); @@ -3324,10 +3325,10 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, } } if (!chip_name) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unknown em28xx chip ID (%d)\n", dev->chip_id); else - dev_info(&dev->udev->dev, "chip ID is %s\n", chip_name); + dev_info(&dev->intf->dev, "chip ID is %s\n", chip_name); em28xx_media_device_init(dev, udev); @@ -3346,7 +3347,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, /* Resets I2C speed */ retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_write_reg failed! retval [%d]\n", __func__, retval); return retval; @@ -3361,7 +3362,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, else retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); return retval; @@ -3376,7 +3377,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_i2c_register(dev, 1, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_i2c_register bus 1 - error [%d]!\n", __func__, retval); @@ -3417,7 +3418,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ - dev_err(&udev->dev, + dev_err(&interface->dev, "Driver supports up to %i em28xx boards.\n", EM28XX_MAXBOARDS); retval = -ENOMEM; @@ -3427,7 +3428,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - dev_err(&udev->dev, + dev_err(&interface->dev, "audio device (%04x:%04x): interface %i, class %i\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), @@ -3488,7 +3489,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (usb_endpoint_xfer_isoc(e)) { has_vendor_audio = true; } else { - dev_err(&udev->dev, + dev_err(&interface->dev, "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); } break; @@ -3562,7 +3563,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - dev_err(&udev->dev, + dev_err(&interface->dev, "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", @@ -3578,8 +3579,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, * not enough even for most Digital TV streams. */ if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { - dev_err(&udev->dev, "Device initialization failed.\n"); - dev_err(&udev->dev, + dev_err(&interface->dev, "Device initialization failed.\n"); + dev_err(&interface->dev, "Device must be connected to a high-speed USB 2.0 port.\n"); retval = -ENODEV; goto err_free; @@ -3593,7 +3594,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev->ifnum = ifnum; if (has_vendor_audio) { - dev_err(&udev->dev, + dev_err(&interface->dev, "Audio interface %i found (Vendor Class)\n", ifnum); dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; } @@ -3603,7 +3604,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) - dev_err(&udev->dev, + dev_err(&interface->dev, "em28xx: device seems to have vendor AND usb audio class interfaces !\n" "\t\tThe vendor interface will be ignored. Please contact the developers \n"); dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; @@ -3612,12 +3613,12 @@ static int em28xx_usb_probe(struct usb_interface *interface, } if (has_video) - dev_err(&udev->dev, "Video interface %i found:%s%s\n", + dev_err(&interface->dev, "Video interface %i found:%s%s\n", ifnum, dev->analog_ep_bulk ? " bulk" : "", dev->analog_ep_isoc ? " isoc" : ""); if (has_dvb) - dev_err(&udev->dev, "DVB interface %i found:%s%s\n", + dev_err(&interface->dev, "DVB interface %i found:%s%s\n", ifnum, dev->dvb_ep_bulk ? " bulk" : "", dev->dvb_ep_isoc ? " isoc" : ""); @@ -3649,7 +3650,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Disable V4L2 if the device doesn't have a decoder */ if (has_video && dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) { - dev_err(&udev->dev, + dev_err(&interface->dev, "Currently, V4L2 is not supported on this model\n"); has_video = false; dev->has_video = false; @@ -3659,13 +3660,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (has_video) { if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) dev->analog_xfer_bulk = 1; - dev_err(&udev->dev, "analog set to %s mode.\n", + dev_err(&interface->dev, "analog set to %s mode.\n", dev->analog_xfer_bulk ? "bulk" : "isoc"); } if (has_dvb) { if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) dev->dvb_xfer_bulk = 1; - dev_err(&udev->dev, "dvb set to %s mode.\n", + dev_err(&interface->dev, "dvb set to %s mode.\n", dev->dvb_xfer_bulk ? "bulk" : "isoc"); } @@ -3713,7 +3714,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) dev->disconnected = 1; - dev_err(&dev->udev->dev, "Disconnecting\n"); + dev_err(&dev->intf->dev, "Disconnecting\n"); flush_request_modules(dev); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 7f1fe5d9d685..f1b4681f3c90 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -52,7 +52,7 @@ MODULE_PARM_DESC(core_debug, "enable debug messages [core and isoc]"); #define em28xx_coredbg(fmt, arg...) do { \ if (core_debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "core: %s: " fmt, __func__, ## arg); \ } while (0) @@ -63,14 +63,14 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); #define em28xx_regdbg(fmt, arg...) do { \ if (reg_debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "reg: %s: " fmt, __func__, ## arg); \ } while (0) /* FIXME: don't abuse core_debug */ #define em28xx_isocdbg(fmt, arg...) do { \ if (core_debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "core: %s: " fmt, __func__, ## arg); \ } while (0) @@ -258,7 +258,7 @@ static int em28xx_is_ac97_ready(struct em28xx *dev) msleep(5); } - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "AC97 command still being executed: not handled properly!\n"); return -EBUSY; } @@ -352,7 +352,7 @@ static int set_ac97_input(struct em28xx *dev) ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); if (ret < 0) - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "couldn't setup AC97 register %d\n", inputs[i].reg); } @@ -437,7 +437,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) for (i = 0; i < ARRAY_SIZE(outputs); i++) { ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); if (ret < 0) - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "couldn't setup AC97 register %d\n", outputs[i].reg); } @@ -476,7 +476,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_write_ac97(dev, outputs[i].reg, vol); if (ret < 0) - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "couldn't setup AC97 register %d\n", outputs[i].reg); } @@ -514,7 +514,7 @@ int em28xx_audio_setup(struct em28xx *dev) /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); - dev_info(&dev->udev->dev, "Config register raw data: 0x%02x\n", cfg); + dev_info(&dev->intf->dev, "Config register raw data: 0x%02x\n", cfg); if (cfg < 0) { /* Register read error */ /* Be conservative */ dev->int_audio_type = EM28XX_INT_AUDIO_AC97; @@ -535,7 +535,7 @@ int em28xx_audio_setup(struct em28xx *dev) i2s_samplerates = 5; else i2s_samplerates = 3; - dev_info(&dev->udev->dev, "I2S Audio (%d sample rate(s))\n", + dev_info(&dev->intf->dev, "I2S Audio (%d sample rate(s))\n", i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; @@ -553,7 +553,7 @@ int em28xx_audio_setup(struct em28xx *dev) * Note: (some) em2800 devices without eeprom reports 0x91 on * CHIPCFG register, even not having an AC97 chip */ - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "AC97 chip type couldn't be determined\n"); dev->audio_mode.ac97 = EM28XX_NO_AC97; if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR) @@ -567,13 +567,13 @@ int em28xx_audio_setup(struct em28xx *dev) goto init_audio; vid = vid1 << 16 | vid2; - dev_warn(&dev->udev->dev, "AC97 vendor ID = 0x%08x\n", vid); + dev_warn(&dev->intf->dev, "AC97 vendor ID = 0x%08x\n", vid); feat = em28xx_read_ac97(dev, AC97_RESET); if (feat < 0) goto init_audio; - dev_warn(&dev->udev->dev, "AC97 features = 0x%04x\n", feat); + dev_warn(&dev->intf->dev, "AC97 features = 0x%04x\n", feat); /* Try to identify what audio processor we have */ if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) @@ -585,19 +585,19 @@ init_audio: /* Reports detected AC97 processor */ switch (dev->audio_mode.ac97) { case EM28XX_NO_AC97: - dev_info(&dev->udev->dev, "No AC97 audio processor\n"); + dev_info(&dev->intf->dev, "No AC97 audio processor\n"); break; case EM28XX_AC97_EM202: - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "Empia 202 AC97 audio processor detected\n"); break; case EM28XX_AC97_SIGMATEL: - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "Sigmatel audio processor detected (stac 97%02x)\n", vid & 0xff); break; case EM28XX_AC97_OTHER: - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "Unknown AC97 audio processor detected!\n"); break; default: @@ -882,7 +882,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if (mode == EM28XX_DIGITAL_MODE) { if ((xfer_bulk && !dev->dvb_ep_bulk) || (!xfer_bulk && !dev->dvb_ep_isoc)) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "no endpoint for DVB mode and transfer type %d\n", xfer_bulk > 0); return -EINVAL; @@ -891,14 +891,14 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, } else if (mode == EM28XX_ANALOG_MODE) { if ((xfer_bulk && !dev->analog_ep_bulk) || (!xfer_bulk && !dev->analog_ep_isoc)) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "no endpoint for analog mode and transfer type %d\n", xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.analog_bufs; } else { - dev_err(&dev->udev->dev, "invalid mode selected\n"); + dev_err(&dev->intf->dev, "invalid mode selected\n"); return -EINVAL; } @@ -940,7 +940,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -1023,7 +1023,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, if (xfer_bulk) { rc = usb_clear_halt(dev->udev, usb_bufs->urb[0]->pipe); if (rc < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", rc); em28xx_uninit_usb_xfer(dev, mode); @@ -1040,7 +1040,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, for (i = 0; i < usb_bufs->num_bufs; i++) { rc = usb_submit_urb(usb_bufs->urb[i], GFP_ATOMIC); if (rc) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "submit of urb %i failed (error=%i)\n", i, rc); em28xx_uninit_usb_xfer(dev, mode); return rc; @@ -1123,7 +1123,7 @@ int em28xx_suspend_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - dev_info(&dev->udev->dev, "Suspending extensions\n"); + dev_info(&dev->intf->dev, "Suspending extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->suspend) @@ -1137,7 +1137,7 @@ int em28xx_resume_extension(struct em28xx *dev) { const struct em28xx_ops *ops = NULL; - dev_info(&dev->udev->dev, "Resuming extensions\n"); + dev_info(&dev->intf->dev, "Resuming extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { if (ops->resume) diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 445e51db636f..d7cfcbe3bf19 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -75,7 +75,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define dprintk(level, fmt, arg...) do { \ if (debug >= level) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "dvb: " fmt, ## arg); \ } while (0) @@ -736,13 +736,13 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) ret = gpio_request_one(dvb->lna_gpio, flags, NULL); if (ret) - dev_err(&dev->udev->dev, "gpio request failed %d\n", ret); + dev_err(&dev->intf->dev, "gpio request failed %d\n", ret); else gpio_free(dvb->lna_gpio); return ret; #else - dev_warn(&dev->udev->dev, "%s: LNA control is disabled (lna=%u)\n", + dev_warn(&dev->intf->dev, "%s: LNA control is disabled (lna=%u)\n", KBUILD_MODNAME, c->lna); return 0; #endif @@ -936,20 +936,20 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) cfg.ctrl = &ctl; if (!dev->dvb->fe[0]) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "dvb frontend not attached. Can't attach xc3028\n"); return -EINVAL; } fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); if (!fe) { - dev_err(&dev->udev->dev, "xc3028 attach failed\n"); + dev_err(&dev->intf->dev, "xc3028 attach failed\n"); dvb_frontend_detach(dev->dvb->fe[0]); dev->dvb->fe[0] = NULL; return -EINVAL; } - dev_info(&dev->udev->dev, "xc3028 attached\n"); + dev_info(&dev->intf->dev, "xc3028 attached\n"); return 0; } @@ -966,10 +966,10 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, /* register adapter */ result = dvb_register_adapter(&dvb->adapter, - dev_name(&dev->udev->dev), module, + dev_name(&dev->intf->dev), module, device, adapter_nr); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "dvb_register_adapter failed (errno = %d)\n", result); goto fail_adapter; @@ -988,7 +988,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "dvb_register_frontend failed (errno = %d)\n", result); goto fail_frontend0; @@ -998,7 +998,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, if (dvb->fe[1]) { result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "2nd dvb_register_frontend failed (errno = %d)\n", result); goto fail_frontend1; @@ -1017,7 +1017,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "dvb_dmx_init failed (errno = %d)\n", result); goto fail_dmx; @@ -1028,7 +1028,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "dvb_dmxdev_init failed (errno = %d)\n", result); goto fail_dmxdev; @@ -1037,7 +1037,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", result); goto fail_fe_hw; @@ -1046,7 +1046,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", result); goto fail_fe_mem; @@ -1054,7 +1054,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "connect_frontend failed (errno = %d)\n", result); goto fail_fe_conn; @@ -1128,7 +1128,7 @@ static int em28xx_dvb_init(struct em28xx *dev) return 0; } - dev_info(&dev->udev->dev, "Binding DVB extension\n"); + dev_info(&dev->intf->dev, "Binding DVB extension\n"); dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (!dvb) @@ -1152,7 +1152,7 @@ static int em28xx_dvb_init(struct em28xx *dev) EM28XX_DVB_NUM_ISOC_PACKETS); } if (result) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to pre-allocate USB transfer buffers for DVB.\n"); kfree(dvb); dev->dvb = NULL; @@ -1270,7 +1270,8 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, - &dev->i2c_adap[dev->def_i2c_bus], &dev->udev->dev); + &dev->i2c_adap[dev->def_i2c_bus], + &dev->intf->dev); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1332,7 +1333,7 @@ static int em28xx_dvb_init(struct em28xx *dev) result = gpio_request_one(dvb->lna_gpio, GPIOF_OUT_INIT_LOW, NULL); if (result) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "gpio request failed %d\n", result); else @@ -1949,12 +1950,12 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; default: - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "The frontend of your DVB/ATSC card isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { - dev_err(&dev->udev->dev, "frontend initialization failed\n"); + dev_err(&dev->intf->dev, "frontend initialization failed\n"); result = -EINVAL; goto out_free; } @@ -1964,12 +1965,12 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[1]->callback = em28xx_tuner_callback; /* register everything */ - result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); + result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->intf->dev); if (result < 0) goto out_free; - dev_info(&dev->udev->dev, "DVB extension successfully initialized\n"); + dev_info(&dev->intf->dev, "DVB extension successfully initialized\n"); kref_get(&dev->ref); @@ -2009,7 +2010,7 @@ static int em28xx_dvb_fini(struct em28xx *dev) if (!dev->dvb) return 0; - dev_info(&dev->udev->dev, "Closing DVB extension\n"); + dev_info(&dev->intf->dev, "Closing DVB extension\n"); dvb = dev->dvb; @@ -2067,17 +2068,17 @@ static int em28xx_dvb_suspend(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - dev_info(&dev->udev->dev, "Suspending DVB extension\n"); + dev_info(&dev->intf->dev, "Suspending DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_suspend(dvb->fe[0]); - dev_info(&dev->udev->dev, "fe0 suspend %d\n", ret); + dev_info(&dev->intf->dev, "fe0 suspend %d\n", ret); } if (dvb->fe[1]) { dvb_frontend_suspend(dvb->fe[1]); - dev_info(&dev->udev->dev, "fe1 suspend %d\n", ret); + dev_info(&dev->intf->dev, "fe1 suspend %d\n", ret); } } @@ -2094,18 +2095,18 @@ static int em28xx_dvb_resume(struct em28xx *dev) if (!dev->board.has_dvb) return 0; - dev_info(&dev->udev->dev, "Resuming DVB extension\n"); + dev_info(&dev->intf->dev, "Resuming DVB extension\n"); if (dev->dvb) { struct em28xx_dvb *dvb = dev->dvb; if (dvb->fe[0]) { ret = dvb_frontend_resume(dvb->fe[0]); - dev_info(&dev->udev->dev, "fe0 resume %d\n", ret); + dev_info(&dev->intf->dev, "fe0 resume %d\n", ret); } if (dvb->fe[1]) { ret = dvb_frontend_resume(dvb->fe[1]); - dev_info(&dev->udev->dev, "fe1 resume %d\n", ret); + dev_info(&dev->intf->dev, "fe1 resume %d\n", ret); } } diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 00e39edc0837..8c472d5adb50 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -46,7 +46,7 @@ MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I #define dprintk(level, fmt, arg...) do { \ if (i2c_debug > level) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "i2c: %s: " fmt, __func__, ## arg); \ } while (0) @@ -78,7 +78,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) /* trigger write */ ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); if (ret != 2 + len) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to trigger write to i2c address 0x%x (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; @@ -93,7 +93,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) return -ENXIO; } if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; @@ -123,7 +123,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) buf2[0] = addr; ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); if (ret != 2) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to trigger read from i2c address 0x%x (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; @@ -140,7 +140,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) return -ENXIO; } if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; @@ -154,7 +154,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) /* get the received message */ ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); if (ret != len) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", addr, ret); return (ret < 0) ? ret : -EIO; @@ -200,12 +200,12 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); if (ret != len) { if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } else { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", len, addr, ret); return -EIO; @@ -223,7 +223,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, return -ENXIO; } if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; @@ -244,7 +244,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, return -ETIMEDOUT; } - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "write to i2c device at 0x%x failed with unknown error (status=%i)\n", addr, ret); return -EIO; @@ -268,7 +268,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) /* Read data from i2c device */ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "reading from i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; @@ -287,7 +287,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) if (ret == 0) /* success */ return len; if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "failed to get i2c transfer status from bridge register (error=%i)\n", ret); return ret; @@ -306,7 +306,7 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) return -ETIMEDOUT; } - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "write to i2c device at 0x%x failed with unknown error (status=%i)\n", addr, ret); return -EIO; @@ -347,12 +347,12 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len); if (ret != len) { if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "writing to i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; } else { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", len, addr, ret); return -EIO; @@ -398,7 +398,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, /* Read value */ ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); if (ret < 0) { - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "reading from i2c device at 0x%x failed (error=%i)\n", addr, ret); return ret; @@ -672,7 +672,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); if (err < 0) { - dev_info(&dev->udev->dev, "board has no eeprom\n"); + dev_info(&dev->intf->dev, "board has no eeprom\n"); return -ENODEV; } @@ -685,7 +685,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->eeprom_addrwidth_16bit, len, data); if (err != len) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to read eeprom (err=%d)\n", err); goto error; } @@ -696,7 +696,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, 16, 1, data, len, true); if (dev->eeprom_addrwidth_16bit) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "eeprom %06x: ... (skipped)\n", 256); } @@ -709,12 +709,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, dev->hash = em28xx_hash_mem(data, len, 32); mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", data[0], data[1], data[2], data[3], dev->hash); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "EEPROM info:\n"); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", mc_start, data[2]); /* @@ -734,7 +734,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, data); if (err != 2) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to read hardware configuration data from eeprom (err=%d)\n", err); goto error; @@ -753,7 +753,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, data); if (err != len) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to read hardware configuration data from eeprom (err=%d)\n", err); goto error; @@ -763,7 +763,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, /* NOTE: not all devices provide this type of dataset */ if (data[0] != 0x1a || data[1] != 0xeb || data[2] != 0x67 || data[3] != 0x95) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tno hardware configuration dataset found in eeprom\n"); kfree(data); return 0; @@ -775,13 +775,13 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, data[0] == 0x1a && data[1] == 0xeb && data[2] == 0x67 && data[3] == 0x95) { dev->hash = em28xx_hash_mem(data, len, 32); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", data[0], data[1], data[2], data[3], dev->hash); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "EEPROM info:\n"); } else { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "unknown eeprom format or eeprom corrupted !\n"); err = -ENODEV; goto error; @@ -793,50 +793,50 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { case 0: - dev_info(&dev->udev->dev, "\tNo audio on board.\n"); + dev_info(&dev->intf->dev, "\tNo audio on board.\n"); break; case 1: - dev_info(&dev->udev->dev, "\tAC97 audio (5 sample rates)\n"); + dev_info(&dev->intf->dev, "\tAC97 audio (5 sample rates)\n"); break; case 2: if (dev->chip_id < CHIP_ID_EM2860) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tI2S audio, sample rate=32k\n"); else - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tI2S audio, 3 sample rates\n"); break; case 3: if (dev->chip_id < CHIP_ID_EM2860) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tI2S audio, 3 sample rates\n"); else - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tI2S audio, 5 sample rates\n"); break; } if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) - dev_info(&dev->udev->dev, "\tUSB Remote wakeup capable\n"); + dev_info(&dev->intf->dev, "\tUSB Remote wakeup capable\n"); if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) - dev_info(&dev->udev->dev, "\tUSB Self power capable\n"); + dev_info(&dev->intf->dev, "\tUSB Self power capable\n"); switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { case 0: - dev_info(&dev->udev->dev, "\t500mA max power\n"); + dev_info(&dev->intf->dev, "\t500mA max power\n"); break; case 1: - dev_info(&dev->udev->dev, "\t400mA max power\n"); + dev_info(&dev->intf->dev, "\t400mA max power\n"); break; case 2: - dev_info(&dev->udev->dev, "\t300mA max power\n"); + dev_info(&dev->intf->dev, "\t300mA max power\n"); break; case 3: - dev_info(&dev->udev->dev, "\t200mA max power\n"); + dev_info(&dev->intf->dev, "\t200mA max power\n"); break; } - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", dev_config->string_idx_table, le16_to_cpu(dev_config->string1), @@ -930,7 +930,7 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) if (rc < 0) continue; i2c_devicelist[i] = i; - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "found i2c device @ 0x%x on bus %d [%s]\n", i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); } @@ -956,8 +956,8 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, return -ENODEV; dev->i2c_adap[bus] = em28xx_adap_template; - dev->i2c_adap[bus].dev.parent = &dev->udev->dev; - strcpy(dev->i2c_adap[bus].name, dev_name(&dev->udev->dev)); + dev->i2c_adap[bus].dev.parent = &dev->intf->dev; + strcpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev)); dev->i2c_bus[bus].bus = bus; dev->i2c_bus[bus].algo_type = algo_type; @@ -966,7 +966,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: i2c_add_adapter failed! retval [%d]\n", __func__, retval); return retval; @@ -979,7 +979,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, if (!bus) { retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index a1904e2230ea..0082ea6d6c08 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -43,7 +43,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); #define dprintk( fmt, arg...) do { \ if (ir_debug) \ - dev_printk(KERN_DEBUG, &ir->dev->udev->dev, \ + dev_printk(KERN_DEBUG, &ir->dev->intf->dev, \ "input: %s: " fmt, __func__, ## arg); \ } while (0) @@ -459,7 +459,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) case CHIP_ID_EM28178: return em2874_ir_change_protocol(rc_dev, rc_type); default: - dev_err(&ir->dev->udev->dev, + dev_err(&ir->dev->intf->dev, "Unrecognized em28xx chip id 0x%02x: IR not supported\n", dev->chip_id); return -EINVAL; @@ -569,7 +569,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) struct input_dev *input_dev; int err; - dev_info(&dev->udev->dev, "Registering snapshot button...\n"); + dev_info(&dev->intf->dev, "Registering snapshot button...\n"); input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; @@ -589,11 +589,11 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); input_dev->id.version = 1; - input_dev->dev.parent = &dev->udev->dev; + input_dev->dev.parent = &dev->intf->dev; err = input_register_device(input_dev); if (err) { - dev_err(&dev->udev->dev, "input_register_device failed\n"); + dev_err(&dev->intf->dev, "input_register_device failed\n"); input_free_device(input_dev); return err; } @@ -633,7 +633,7 @@ static void em28xx_init_buttons(struct em28xx *dev) } else if (button->role == EM28XX_BUTTON_ILLUMINATION) { /* Check sanity */ if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "BUG: illumination button defined, but no illumination LED.\n"); goto next_button; } @@ -670,7 +670,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) dev->num_button_polling_addresses = 0; /* Deregister input devices */ if (dev->sbutton_input_dev != NULL) { - dev_info(&dev->udev->dev, "Deregistering snapshot button\n"); + dev_info(&dev->intf->dev, "Deregistering snapshot button\n"); input_unregister_device(dev->sbutton_input_dev); dev->sbutton_input_dev = NULL; } @@ -699,7 +699,7 @@ static int em28xx_ir_init(struct em28xx *dev) i2c_rc_dev_addr = em28xx_probe_i2c_ir(dev); if (!i2c_rc_dev_addr) { dev->board.has_ir_i2c = 0; - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "No i2c IR remote control device found.\n"); return -ENODEV; } @@ -707,12 +707,12 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { /* No remote control support */ - dev_warn(&dev->udev->dev, + dev_warn(&dev->intf->dev, "Remote control support is not available for this card.\n"); return 0; } - dev_info(&dev->udev->dev, "Registering input extension\n"); + dev_info(&dev->intf->dev, "Registering input extension\n"); ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) @@ -797,7 +797,7 @@ static int em28xx_ir_init(struct em28xx *dev) /* init input device */ snprintf(ir->name, sizeof(ir->name), "%s IR", - dev_name(&dev->udev->dev)); + dev_name(&dev->intf->dev)); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); @@ -808,7 +808,7 @@ static int em28xx_ir_init(struct em28xx *dev) rc->input_id.version = 1; rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); - rc->dev.parent = &dev->udev->dev; + rc->dev.parent = &dev->intf->dev; rc->driver_name = MODULE_NAME; /* all done */ @@ -816,7 +816,7 @@ static int em28xx_ir_init(struct em28xx *dev) if (err) goto error; - dev_info(&dev->udev->dev, "Input extension successfully initalized\n"); + dev_info(&dev->intf->dev, "Input extension successfully initalized\n"); return 0; @@ -837,7 +837,7 @@ static int em28xx_ir_fini(struct em28xx *dev) return 0; } - dev_info(&dev->udev->dev, "Closing input extension\n"); + dev_info(&dev->intf->dev, "Closing input extension\n"); em28xx_shutdown_buttons(dev); @@ -866,7 +866,7 @@ static int em28xx_ir_suspend(struct em28xx *dev) if (dev->is_audio_only) return 0; - dev_info(&dev->udev->dev, "Suspending input extension\n"); + dev_info(&dev->intf->dev, "Suspending input extension\n"); if (ir) cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&dev->buttons_query_work); @@ -883,7 +883,7 @@ static int em28xx_ir_resume(struct em28xx *dev) if (dev->is_audio_only) return 0; - dev_info(&dev->udev->dev, "Resuming input extension\n"); + dev_info(&dev->intf->dev, "Resuming input extension\n"); /* if suspend calls ir_raw_event_unregister(), the should call ir_raw_event_register() */ if (ir) diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 1b21d001cc7e..0bac552bbe87 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -65,7 +65,7 @@ static int vbi_buffer_prepare(struct vb2_buffer *vb) size = v4l2->vbi_width * v4l2->vbi_height * 2; if (vb2_plane_size(vb, 0) < size) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "%s data will not fit into plane (%lu < %lu)\n", __func__, vb2_plane_size(vb, 0), size); return -EINVAL; diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 2d282ed9aac0..4780f6492329 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -66,13 +66,13 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); #define em28xx_videodbg(fmt, arg...) do { \ if (video_debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "video: %s: " fmt, __func__, ## arg); \ } while (0) #define em28xx_isocdbg(fmt, arg...) do {\ if (isoc_debug) \ - dev_printk(KERN_DEBUG, &dev->udev->dev, \ + dev_printk(KERN_DEBUG, &dev->intf->dev, \ "isoc: %s: " fmt, __func__, ## arg); \ } while (0) @@ -413,7 +413,7 @@ set_alt: dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "cannot change alternate number to %d (error=%i)\n", dev->alt, errCode); return errCode; @@ -926,7 +926,7 @@ static int em28xx_enable_analog_tuner(struct em28xx *dev) ret = media_entity_setup_link(link, flags); if (ret) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Couldn't change link %s->%s to %s. Error %d\n", source->name, sink->name, flags ? "enabled" : "disabled", @@ -958,7 +958,7 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) v4l2->video_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&v4l2->vdev.entity, 1, &v4l2->video_pad); if (ret < 0) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to initialize video media entity!\n"); if (em28xx_vbi_supported(dev)) { @@ -966,7 +966,7 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) ret = media_entity_pads_init(&v4l2->vbi_dev.entity, 1, &v4l2->vbi_pad); if (ret < 0) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to initialize vbi media entity!\n"); } @@ -1000,12 +1000,12 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]); if (ret < 0) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to initialize input pad[%d]!\n", i); ret = media_device_register_entity(dev->media_dev, ent); if (ret < 0) - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to register input entity %d!\n", i); } #endif @@ -2053,7 +2053,7 @@ static int em28xx_v4l2_open(struct file *filp) ret = v4l2_fh_open(filp); if (ret) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: v4l2_fh_open() returned error %d\n", __func__, ret); mutex_unlock(&dev->lock); @@ -2109,7 +2109,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) if (v4l2 == NULL) return 0; - dev_info(&dev->udev->dev, "Closing video extension\n"); + dev_info(&dev->intf->dev, "Closing video extension\n"); mutex_lock(&dev->lock); @@ -2120,17 +2120,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) em28xx_v4l2_media_release(dev); if (video_is_registered(&v4l2->radio_dev)) { - dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); } @@ -2160,7 +2160,7 @@ static int em28xx_v4l2_suspend(struct em28xx *dev) if (!dev->has_video) return 0; - dev_info(&dev->udev->dev, "Suspending video extension\n"); + dev_info(&dev->intf->dev, "Suspending video extension\n"); em28xx_stop_urbs(dev); return 0; } @@ -2173,7 +2173,7 @@ static int em28xx_v4l2_resume(struct em28xx *dev) if (!dev->has_video) return 0; - dev_info(&dev->udev->dev, "Resuming video extension\n"); + dev_info(&dev->intf->dev, "Resuming video extension\n"); /* what do we do here */ return 0; } @@ -2210,7 +2210,7 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_videodbg("setting alternate 0\n"); errCode = usb_set_interface(dev->udev, 0, 0); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "cannot change alternate number to 0 (error=%i)\n", errCode); } @@ -2345,7 +2345,7 @@ static void em28xx_vdev_init(struct em28xx *dev, vfd->tvnorms = 0; snprintf(vfd->name, sizeof(vfd->name), "%s %s", - dev_name(&dev->udev->dev), type_name); + dev_name(&dev->intf->dev), type_name); video_set_drvdata(vfd, dev); } @@ -2429,7 +2429,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) return 0; } - dev_info(&dev->udev->dev, "Registering V4L2 extension\n"); + dev_info(&dev->intf->dev, "Registering V4L2 extension\n"); mutex_lock(&dev->lock); @@ -2445,9 +2445,9 @@ static int em28xx_v4l2_init(struct em28xx *dev) #ifdef CONFIG_MEDIA_CONTROLLER v4l2->v4l2_dev.mdev = dev->media_dev; #endif - ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev); + ret = v4l2_device_register(&dev->intf->dev, &v4l2->v4l2_dev); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "Call to v4l2_device_register() failed!\n"); goto err; } @@ -2532,7 +2532,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Configure audio */ ret = em28xx_audio_setup(dev); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: Error while setting audio - error [%d]!\n", __func__, ret); goto unregister_dev; @@ -2561,7 +2561,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Send a reset to other chips via gpio */ ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n", __func__, ret); goto unregister_dev; @@ -2570,7 +2570,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n", __func__, ret); goto unregister_dev; @@ -2673,7 +2673,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "unable to register video device (error=%i).\n", ret); goto unregister_dev; } @@ -2703,7 +2703,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "unable to register vbi device\n"); goto unregister_dev; } @@ -2715,11 +2715,11 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "can't register radio device\n"); goto unregister_dev; } - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "Registered radio device as %s\n", video_device_node_name(&v4l2->radio_dev)); } @@ -2730,19 +2730,19 @@ static int em28xx_v4l2_init(struct em28xx *dev) #ifdef CONFIG_MEDIA_CONTROLLER ret = v4l2_mc_create_media_graph(dev->media_dev); if (ret) { - dev_err(&dev->udev->dev, + dev_err(&dev->intf->dev, "failed to create media graph\n"); em28xx_v4l2_media_release(dev); goto unregister_dev; } #endif - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 video device registered as %s\n", video_device_node_name(&v4l2->vdev)); if (video_is_registered(&v4l2->vbi_dev)) - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 VBI device registered as %s\n", video_device_node_name(&v4l2->vbi_dev)); @@ -2752,7 +2752,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* initialize videobuf2 stuff */ em28xx_vb2_setup(dev); - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 extension successfully initialized\n"); kref_get(&dev->ref); @@ -2762,19 +2762,19 @@ static int em28xx_v4l2_init(struct em28xx *dev) unregister_dev: if (video_is_registered(&v4l2->radio_dev)) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->radio_dev)); video_unregister_device(&v4l2->radio_dev); } if (video_is_registered(&v4l2->vbi_dev)) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vbi_dev)); video_unregister_device(&v4l2->vbi_dev); } if (video_is_registered(&v4l2->vdev)) { - dev_info(&dev->udev->dev, + dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", video_device_node_name(&v4l2->vdev)); video_unregister_device(&v4l2->vdev); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 3e5ace497a4e..5182b1bf0d15 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -678,6 +678,7 @@ struct em28xx { /* usb transfer */ struct usb_device *udev; /* the usb device */ + struct usb_interface *intf; /* the usb interface */ u8 ifnum; /* number of the assigned usb interface */ u8 analog_ep_isoc; /* address of isoc endpoint for analog */ u8 analog_ep_bulk; /* address of bulk endpoint for analog */ -- cgit v1.2.3 From c6d48134cb2682516ed50ca0cea2675d27d985e8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Dec 2016 14:34:22 -0200 Subject: [media] em28xx: don't store usb_device at struct em28xx Now that we're storing usb_interface at em28xx struct, there's no good reason to keep storing usb_device, as we can get it from usb_interface. So, get rid of it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 23 ++++++++++++++--------- drivers/media/usb/em28xx/em28xx-cards.c | 10 +++++----- drivers/media/usb/em28xx/em28xx-core.c | 29 +++++++++++++++++------------ drivers/media/usb/em28xx/em28xx-dvb.c | 3 ++- drivers/media/usb/em28xx/em28xx-input.c | 14 ++++++++------ drivers/media/usb/em28xx/em28xx-video.c | 9 ++++++--- drivers/media/usb/em28xx/em28xx.h | 1 - 7 files changed, 52 insertions(+), 37 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 7f8601427b7f..7969ddb9e2dd 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -279,6 +279,8 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) if (dev->adev.users == 0) { if (dev->alt == 0 || dev->is_audio_only) { + struct usb_device *udev = interface_to_usbdev(dev->intf); + if (dev->is_audio_only) /* audio is on a separate interface */ dev->alt = 1; @@ -296,7 +298,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) */ dprintk("changing alternate number on interface %d to %d\n", dev->ifnum, dev->alt); - usb_set_interface(dev->udev, dev->ifnum, dev->alt); + usb_set_interface(udev, dev->ifnum, dev->alt); } /* Sets volume, mute, etc */ @@ -714,6 +716,7 @@ static const struct snd_pcm_ops snd_em28xx_pcm_capture = { static void em28xx_audio_free_urb(struct em28xx *dev) { + struct usb_device *udev = interface_to_usbdev(dev->intf); int i; for (i = 0; i < dev->adev.num_urb; i++) { @@ -722,7 +725,7 @@ static void em28xx_audio_free_urb(struct em28xx *dev) if (!urb) continue; - usb_free_coherent(dev->udev, urb->transfer_buffer_length, + usb_free_coherent(udev, urb->transfer_buffer_length, dev->adev.transfer_buffer[i], urb->transfer_dma); @@ -749,6 +752,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) { struct usb_interface *intf; struct usb_endpoint_descriptor *e, *ep = NULL; + struct usb_device *udev = interface_to_usbdev(dev->intf); int i, ep_size, interval, num_urb, npackets; int urb_size, bytes_per_transfer; u8 alt; @@ -758,7 +762,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) else alt = 7; - intf = usb_ifnum_to_if(dev->udev, dev->ifnum); + intf = usb_ifnum_to_if(udev, dev->ifnum); if (intf->num_altsetting <= alt) { dev_err(&dev->intf->dev, "alt %d doesn't exist on interface %d\n", @@ -781,12 +785,12 @@ static int em28xx_audio_urb_init(struct em28xx *dev) return -ENODEV; } - ep_size = em28xx_audio_ep_packet_size(dev->udev, ep); + ep_size = em28xx_audio_ep_packet_size(udev, ep); interval = 1 << (ep->bInterval - 1); dev_info(&dev->intf->dev, "Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", - EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), + EM28XX_EP_AUDIO, usb_speed_string(udev->speed), dev->ifnum, alt, interval, ep_size); /* Calculate the number and size of URBs to better fit the audio samples */ @@ -860,7 +864,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) } dev->adev.urb[i] = urb; - buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC, + buf = usb_alloc_coherent(udev, npackets * ep_size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { dev_err(&dev->intf->dev, @@ -870,9 +874,9 @@ static int em28xx_audio_urb_init(struct em28xx *dev) } dev->adev.transfer_buffer[i] = buf; - urb->dev = dev->udev; + urb->dev = udev; urb->context = dev; - urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO); + urb->pipe = usb_rcvisocpipe(udev, EM28XX_EP_AUDIO); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer = buf; urb->interval = interval; @@ -892,6 +896,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) static int em28xx_audio_init(struct em28xx *dev) { struct em28xx_audio *adev = &dev->adev; + struct usb_device *udev = interface_to_usbdev(dev->intf); struct snd_pcm *pcm; struct snd_card *card; static int devnr; @@ -920,7 +925,7 @@ static int em28xx_audio_init(struct em28xx *dev) spin_lock_init(&adev->slock); adev->sndcard = card; - adev->udev = dev->udev; + adev->udev = udev; err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); if (err < 0) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 56739ce6ce16..23c67494762d 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3188,6 +3188,8 @@ static void em28xx_unregister_media_device(struct em28xx *dev) */ static void em28xx_release_resources(struct em28xx *dev) { + struct usb_device *udev = interface_to_usbdev(dev->intf); + /*FIXME: I2C IR should be disconnected */ mutex_lock(&dev->lock); @@ -3198,7 +3200,7 @@ static void em28xx_release_resources(struct em28xx *dev) em28xx_i2c_unregister(dev, 1); em28xx_i2c_unregister(dev, 0); - usb_put_dev(dev->udev); + usb_put_dev(udev); /* Mark device as unused */ clear_bit(dev->devno, em28xx_devused); @@ -3238,7 +3240,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, int retval; const char *chip_name = NULL; - dev->udev = udev; dev->intf = interface; mutex_init(&dev->ctrl_urb_lock); spin_lock_init(&dev->slock); @@ -3277,9 +3278,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, break; case CHIP_ID_EM2820: chip_name = "em2710/2820"; - if (le16_to_cpu(dev->udev->descriptor.idVendor) - == 0xeb1a) { - __le16 idProd = dev->udev->descriptor.idProduct; + if (le16_to_cpu(udev->descriptor.idVendor) == 0xeb1a) { + __le16 idProd = udev->descriptor.idProduct; if (le16_to_cpu(idProd) == 0x2710) chip_name = "em2710"; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index f1b4681f3c90..19ccff41c7eb 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -82,7 +82,8 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, char *buf, int len) { int ret; - int pipe = usb_rcvctrlpipe(dev->udev, 0); + struct usb_device *udev = interface_to_usbdev(dev->intf); + int pipe = usb_rcvctrlpipe(udev, 0); if (dev->disconnected) return -ENODEV; @@ -97,7 +98,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, len & 0xff, len >> 8); mutex_lock(&dev->ctrl_urb_lock); - ret = usb_control_msg(dev->udev, pipe, req, + ret = usb_control_msg(udev, pipe, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, reg, dev->urb_buf, len, HZ); if (ret < 0) { @@ -154,7 +155,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len) { int ret; - int pipe = usb_sndctrlpipe(dev->udev, 0); + struct usb_device *udev = interface_to_usbdev(dev->intf); + int pipe = usb_sndctrlpipe(udev, 0); if (dev->disconnected) return -ENODEV; @@ -171,7 +173,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, mutex_lock(&dev->ctrl_urb_lock); memcpy(dev->urb_buf, buf, len); - ret = usb_control_msg(dev->udev, pipe, req, + ret = usb_control_msg(udev, pipe, req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, reg, dev->urb_buf, len, HZ); mutex_unlock(&dev->ctrl_urb_lock); @@ -797,6 +799,7 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) { struct urb *urb; struct em28xx_usb_bufs *usb_bufs; + struct usb_device *udev = interface_to_usbdev(dev->intf); int i; em28xx_isocdbg("em28xx: called em28xx_uninit_usb_xfer in mode %d\n", @@ -816,7 +819,7 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) usb_unlink_urb(urb); if (usb_bufs->transfer_buffer[i]) { - usb_free_coherent(dev->udev, + usb_free_coherent(udev, urb->transfer_buffer_length, usb_bufs->transfer_buffer[i], urb->transfer_dma); @@ -870,9 +873,10 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, int num_bufs, int max_pkt_size, int packet_multiplier) { struct em28xx_usb_bufs *usb_bufs; + struct urb *urb; + struct usb_device *udev = interface_to_usbdev(dev->intf); int i; int sb_size, pipe; - struct urb *urb; int j, k; em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode); @@ -937,7 +941,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, } usb_bufs->urb[i] = urb; - usb_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, + usb_bufs->transfer_buffer[i] = usb_alloc_coherent(udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!usb_bufs->transfer_buffer[i]) { dev_err(&dev->intf->dev, @@ -950,20 +954,20 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, memset(usb_bufs->transfer_buffer[i], 0, sb_size); if (xfer_bulk) { /* bulk */ - pipe = usb_rcvbulkpipe(dev->udev, + pipe = usb_rcvbulkpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_bulk : dev->dvb_ep_bulk); - usb_fill_bulk_urb(urb, dev->udev, pipe, + usb_fill_bulk_urb(urb, udev, pipe, usb_bufs->transfer_buffer[i], sb_size, em28xx_irq_callback, dev); urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; } else { /* isoc */ - pipe = usb_rcvisocpipe(dev->udev, + pipe = usb_rcvisocpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_isoc : dev->dvb_ep_isoc); - usb_fill_int_urb(urb, dev->udev, pipe, + usb_fill_int_urb(urb, udev, pipe, usb_bufs->transfer_buffer[i], sb_size, em28xx_irq_callback, dev, 1); urb->transfer_flags = URB_ISO_ASAP | @@ -995,6 +999,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, struct em28xx_dmaqueue *dma_q = &dev->vidq; struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; struct em28xx_usb_bufs *usb_bufs; + struct usb_device *udev = interface_to_usbdev(dev->intf); int i; int rc; int alloc; @@ -1021,7 +1026,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, } if (xfer_bulk) { - rc = usb_clear_halt(dev->udev, usb_bufs->urb[0]->pipe); + rc = usb_clear_halt(udev, usb_bufs->urb[0]->pipe); if (rc < 0) { dev_err(&dev->intf->dev, "failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index d7cfcbe3bf19..75a75dab2e8e 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -198,6 +198,7 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) int rc; struct em28xx_i2c_bus *i2c_bus = dvb->adapter.priv; struct em28xx *dev = i2c_bus->dev; + struct usb_device *udev = interface_to_usbdev(dev->intf); int dvb_max_packet_size, packet_multiplier, dvb_alt; if (dev->dvb_xfer_bulk) { @@ -216,7 +217,7 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) dvb_alt = dev->dvb_alt_isoc; } - usb_set_interface(dev->udev, dev->ifnum, dvb_alt); + usb_set_interface(udev, dev->ifnum, dvb_alt); rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); if (rc < 0) return rc; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 0082ea6d6c08..782ce095c8c5 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -566,6 +566,7 @@ static void em28xx_query_buttons(struct work_struct *work) static int em28xx_register_snapshot_button(struct em28xx *dev) { + struct usb_device *udev = interface_to_usbdev(dev->intf); struct input_dev *input_dev; int err; @@ -574,7 +575,7 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) if (!input_dev) return -ENOMEM; - usb_make_path(dev->udev, dev->snapshot_button_path, + usb_make_path(udev, dev->snapshot_button_path, sizeof(dev->snapshot_button_path)); strlcat(dev->snapshot_button_path, "/sbutton", sizeof(dev->snapshot_button_path)); @@ -586,8 +587,8 @@ static int em28xx_register_snapshot_button(struct em28xx *dev) input_dev->keycodesize = 0; input_dev->keycodemax = 0; input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); - input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); + input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct); input_dev->id.version = 1; input_dev->dev.parent = &dev->intf->dev; @@ -678,6 +679,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) static int em28xx_ir_init(struct em28xx *dev) { + struct usb_device *udev = interface_to_usbdev(dev->intf); struct em28xx_IR *ir; struct rc_dev *rc; int err = -ENOMEM; @@ -799,15 +801,15 @@ static int em28xx_ir_init(struct em28xx *dev) snprintf(ir->name, sizeof(ir->name), "%s IR", dev_name(&dev->intf->dev)); - usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); + usb_make_path(udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); rc->input_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_USB; rc->input_id.version = 1; - rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); - rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); + rc->input_id.vendor = le16_to_cpu(udev->descriptor.idVendor); + rc->input_id.product = le16_to_cpu(udev->descriptor.idProduct); rc->dev.parent = &dev->intf->dev; rc->driver_name = MODULE_NAME; diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 4780f6492329..8d93100334ea 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -360,6 +360,7 @@ static int em28xx_resolution_set(struct em28xx *dev) static int em28xx_set_alternate(struct em28xx *dev) { struct em28xx_v4l2 *v4l2 = dev->v4l2; + struct usb_device *udev = interface_to_usbdev(dev->intf); int errCode; int i; unsigned int min_pkt_size = v4l2->width * 2 + 4; @@ -411,7 +412,7 @@ set_alt: } em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, dev->max_pkt_size); - errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); + errCode = usb_set_interface(udev, dev->ifnum, dev->alt); if (errCode < 0) { dev_err(&dev->intf->dev, "cannot change alternate number to %d (error=%i)\n", @@ -1859,10 +1860,11 @@ static int vidioc_querycap(struct file *file, void *priv, struct video_device *vdev = video_devdata(file); struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; + struct usb_device *udev = interface_to_usbdev(dev->intf); strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); + usb_make_path(udev, cap->bus_info, sizeof(cap->bus_info)); if (vdev->vfl_type == VFL_TYPE_GRABBER) cap->device_caps = V4L2_CAP_READWRITE | @@ -2187,6 +2189,7 @@ static int em28xx_v4l2_close(struct file *filp) { struct em28xx *dev = video_drvdata(filp); struct em28xx_v4l2 *v4l2 = dev->v4l2; + struct usb_device *udev = interface_to_usbdev(dev->intf); int errCode; em28xx_videodbg("users=%d\n", v4l2->users); @@ -2208,7 +2211,7 @@ static int em28xx_v4l2_close(struct file *filp) /* set alternate 0 */ dev->alt = 0; em28xx_videodbg("setting alternate 0\n"); - errCode = usb_set_interface(dev->udev, 0, 0); + errCode = usb_set_interface(udev, 0, 0); if (errCode < 0) { dev_err(&dev->intf->dev, "cannot change alternate number to 0 (error=%i)\n", diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 5182b1bf0d15..ca59e2d4fccf 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -677,7 +677,6 @@ struct em28xx { spinlock_t slock; /* usb transfer */ - struct usb_device *udev; /* the usb device */ struct usb_interface *intf; /* the usb interface */ u8 ifnum; /* number of the assigned usb interface */ u8 analog_ep_isoc; /* address of isoc endpoint for analog */ -- cgit v1.2.3 From 406ff67d5820f592ff2b5ac2643a75f001b1d21f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 8 Dec 2016 20:22:41 -0200 Subject: [media] v4l: tvp5150: Compile tvp5150_link_setup out if !CONFIG_MEDIA_CONTROLLER The function is only referenced as a handler in the tvp5150_sd_media_ops structure, which is only used when CONFIG_MEDIA_CONTROLLER is set. Don't define the function and the structure when the configuration option is unset to avoid an unused function warning. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 6737685d5be5..08384951c9e5 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1013,11 +1013,11 @@ static int tvp5150_enum_frame_size(struct v4l2_subdev *sd, Media entity ops ****************************************************************************/ +#ifdef CONFIG_MEDIA_CONTROLLER static int tvp5150_link_setup(struct media_entity *entity, const struct media_pad *local, const struct media_pad *remote, u32 flags) { -#ifdef CONFIG_MEDIA_CONTROLLER struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct tvp5150 *decoder = to_tvp5150(sd); int i; @@ -1034,7 +1034,6 @@ static int tvp5150_link_setup(struct media_entity *entity, decoder->input = i; tvp5150_selmux(sd); -#endif return 0; } @@ -1042,6 +1041,7 @@ static int tvp5150_link_setup(struct media_entity *entity, static const struct media_entity_operations tvp5150_sd_media_ops = { .link_setup = tvp5150_link_setup, }; +#endif /**************************************************************************** I2C Command -- cgit v1.2.3 From 6e98bee2899549c7482b05b0740bf195493ef9dc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 8 Dec 2016 20:22:42 -0200 Subject: [media] v4l: tvp5150: Don't inline the tvp5150_selmux() function The function is large and called in several places, don't inline it. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 08384951c9e5..febe6833a504 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -258,7 +258,7 @@ static int tvp5150_log_status(struct v4l2_subdev *sd) Basic functions ****************************************************************************/ -static inline void tvp5150_selmux(struct v4l2_subdev *sd) +static void tvp5150_selmux(struct v4l2_subdev *sd) { int opmode = 0; struct tvp5150 *decoder = to_tvp5150(sd); -- cgit v1.2.3 From d183e4efcae8d88a2f252e546978658ca6d273cc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 8 Dec 2016 20:22:43 -0200 Subject: [media] v4l: tvp5150: Add missing break in set control handler A break is missing resulting in the hue control enabling or disabling the decode completely. Fix it. Fixes: c43875f66140 ("[media] tvp5150: replace MEDIA_ENT_F_CONN_TEST by a control") Cc: stable@vger.kernel.org Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index febe6833a504..3a0fe8cc64e9 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -818,6 +818,7 @@ static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl) return 0; case V4L2_CID_HUE: tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val); + break; case V4L2_CID_TEST_PATTERN: decoder->enable = ctrl->val ? false : true; tvp5150_selmux(sd); -- cgit v1.2.3