From 50ad58f9dc11ebdf7d66253dd1f4cd3f6642749d Mon Sep 17 00:00:00 2001 From: Shilpa P Date: Sat, 3 Dec 2016 05:02:01 -0200 Subject: [media] staging: Replaced BUG_ON with warnings Don't crash the Kernel for driver errors Signed-off-by: Shilpa P Acked-by: Allen Pais Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 37bd439..5696982 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -1534,7 +1534,11 @@ static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i, if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) return 0; - BUG_ON((index+2) >= BCM2048_MAX_RDS_RT); + if ((index + 2) >= BCM2048_MAX_RDS_RT) { + dev_err(&bdev->client->dev, + "Incorrect index = %d\n", index); + return 0; + } if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_C) { @@ -1557,7 +1561,11 @@ static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i, if (crc == BCM2048_RDS_CRC_UNRECOVARABLE) return; - BUG_ON((index+4) >= BCM2048_MAX_RDS_RT); + if ((index + 4) >= BCM2048_MAX_RDS_RT) { + dev_err(&bdev->client->dev, + "Incorrect index = %d\n", index); + return; + } if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) == BCM2048_RDS_BLOCK_D) -- cgit v1.1 From b2a4ab7268a65bf59385e9a5cdfd4b2f1eaf6c31 Mon Sep 17 00:00:00 2001 From: Avraham Shukron Date: Thu, 9 Feb 2017 14:57:55 -0200 Subject: [media] staging: omap4iss: fix multiline comment style Fixed multi-line comments to their preferred style (First line empty) Signed-off-by: Avraham Shukron Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_video.c | 38 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index bb0e3b4..e21811a 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -128,7 +128,8 @@ static unsigned int iss_video_mbus_to_pix(const struct iss_video *video, pix->width = mbus->width; pix->height = mbus->height; - /* Skip the last format in the loop so that it will be selected if no + /* + * Skip the last format in the loop so that it will be selected if no * match is found. */ for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) { @@ -138,7 +139,8 @@ static unsigned int iss_video_mbus_to_pix(const struct iss_video *video, min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8; - /* Clamp the requested bytes per line value. If the maximum bytes per + /* + * Clamp the requested bytes per line value. If the maximum bytes per * line value is zero, the module doesn't support user configurable line * sizes. Override the requested value with the minimum in that case. */ @@ -172,7 +174,8 @@ static void iss_video_pix_to_mbus(const struct v4l2_pix_format *pix, mbus->width = pix->width; mbus->height = pix->height; - /* Skip the last format in the loop so that it will be selected if no + /* + * Skip the last format in the loop so that it will be selected if no * match is found. */ for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) { @@ -360,7 +363,8 @@ static void iss_video_buf_queue(struct vb2_buffer *vb) spin_lock_irqsave(&video->qlock, flags); - /* Mark the buffer is faulty and give it back to the queue immediately + /* + * Mark the buffer is faulty and give it back to the queue immediately * if the video node has registered an error. vb2 will perform the same * check when preparing the buffer, but that is inherently racy, so we * need to handle the race condition with an authoritative check here. @@ -443,7 +447,8 @@ struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video) buf->vb.vb2_buf.timestamp = ktime_get_ns(); - /* Do frame number propagation only if this is the output video node. + /* + * Do frame number propagation only if this is the output video node. * Frame number either comes from the CSI receivers or it gets * incremented here if H3A is not active. * Note: There is no guarantee that the output buffer will finish @@ -605,7 +610,8 @@ iss_video_set_format(struct file *file, void *fh, struct v4l2_format *format) mutex_lock(&video->mutex); - /* Fill the bytesperline and sizeimage fields by converting to media bus + /* + * Fill the bytesperline and sizeimage fields by converting to media bus * format and back to pixel format. */ iss_video_pix_to_mbus(&format->fmt.pix, &fmt); @@ -678,8 +684,9 @@ iss_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) if (subdev == NULL) return -EINVAL; - /* Try the get selection operation first and fallback to get format if not - * implemented. + /* + * Try the get selection operation first and fallback to get format if + * not implemented. */ sdsel.pad = pad; ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); @@ -867,7 +874,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) mutex_lock(&video->stream_lock); - /* Start streaming on the pipeline. No link touching an entity in the + /* + * Start streaming on the pipeline. No link touching an entity in the * pipeline can be activated or deactivated once streaming is started. */ pipe = entity->pipe @@ -895,7 +903,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) while ((entity = media_graph_walk_next(&graph))) media_entity_enum_set(&pipe->ent_enum, entity); - /* Verify that the currently configured format matches the output of + /* + * Verify that the currently configured format matches the output of * the connected subdev. */ ret = iss_video_check_format(video, vfh); @@ -905,7 +914,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) video->bpl_padding = ret; video->bpl_value = vfh->format.fmt.pix.bytesperline; - /* Find the ISS video node connected at the far end of the pipeline and + /* + * Find the ISS video node connected at the far end of the pipeline and * update the pipeline. */ far_end = iss_video_far_end(video); @@ -930,7 +940,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) pipe->state |= state; spin_unlock_irqrestore(&pipe->lock, flags); - /* Set the maximum time per frame as the value requested by userspace. + /* + * Set the maximum time per frame as the value requested by userspace. * This is a soft limit that can be overridden if the hardware doesn't * support the request limit. */ @@ -946,7 +957,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) if (ret < 0) goto err_iss_video_check_format; - /* In sensor-to-memory mode, the stream can be started synchronously + /* + * In sensor-to-memory mode, the stream can be started synchronously * to the stream on command. In memory-to-memory mode, it will be * started when buffers are queued on both the input and output. */ -- cgit v1.1 From 5dfaacb2d6a48c4505db43cebc2575923a7f0e2a Mon Sep 17 00:00:00 2001 From: Avraham Shukron Date: Thu, 9 Feb 2017 15:01:57 -0200 Subject: [media] staging: omap4iss: fix coding style issue Broke argument list so that it won't exceed 80 characters Signed-off-by: Avraham Shukron Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index e21811a..0bac582 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -301,7 +301,8 @@ iss_video_check_format(struct iss_video *video, struct iss_video_fh *vfh) static int iss_video_queue_setup(struct vb2_queue *vq, unsigned int *count, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) + unsigned int sizes[], + struct device *alloc_devs[]) { struct iss_video_fh *vfh = vb2_get_drv_priv(vq); struct iss_video *video = vfh->video; -- cgit v1.1 From 733e009c37b6caa219d7057838582d1259c4554f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 1 Mar 2017 20:50:03 -0300 Subject: [media] Staging: media: radio-bcm2048: remove incorrect __exit markups Even if bus is not hot-pluggable, devices can be unbound from the driver via sysfs, so we should not be using __exit annotations on remove() methods. The only exception is drivers registered with platform_driver_probe() which specifically disables sysfs bind/unbind attributes. Signed-off-by: Dmitry Torokhov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index ddf7b9d..375c617 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2642,7 +2642,7 @@ exit: return err; } -static int __exit bcm2048_i2c_driver_remove(struct i2c_client *client) +static int bcm2048_i2c_driver_remove(struct i2c_client *client) { struct bcm2048_device *bdev = i2c_get_clientdata(client); @@ -2681,7 +2681,7 @@ static struct i2c_driver bcm2048_i2c_driver = { .name = BCM2048_DRIVER_NAME, }, .probe = bcm2048_i2c_driver_probe, - .remove = __exit_p(bcm2048_i2c_driver_remove), + .remove = bcm2048_i2c_driver_remove, .id_table = bcm2048_id, }; -- cgit v1.1 From 5cd6522c5b1df51f22f3b83f5548989a64ab44f5 Mon Sep 17 00:00:00 2001 From: Derek Robson Date: Fri, 10 Feb 2017 22:42:38 -0200 Subject: [media] staging: lirc: use octal instead of symbolic permission Changed permissions to octal across whole driver Found by checkpatch Signed-off-by: Derek Robson Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sasem.c | 2 +- drivers/staging/media/lirc/lirc_sir.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index b0c176e..ac69fe1 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -158,7 +158,7 @@ static int debug; MODULE_AUTHOR(MOD_AUTHOR); MODULE_DESCRIPTION(MOD_DESC); MODULE_LICENSE("GPL"); -module_param(debug, int, S_IRUGO | S_IWUSR); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); static void delete_context(struct sasem_context *context) diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index c6c3de9..e498ae8 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -826,14 +826,14 @@ MODULE_AUTHOR("Milan Pikula"); #endif MODULE_LICENSE("GPL"); -module_param(io, int, S_IRUGO); +module_param(io, int, 0444); MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); -module_param(irq, int, S_IRUGO); +module_param(irq, int, 0444); MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); -module_param(threshold, int, S_IRUGO); +module_param(threshold, int, 0444); MODULE_PARM_DESC(threshold, "space detection threshold (3)"); -module_param(debug, bool, S_IRUGO | S_IWUSR); +module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Enable debugging messages"); -- cgit v1.1 From cf9ed9aa5b0c196b796d2728218e3c06b0f42d90 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 25 Mar 2017 07:31:57 -0300 Subject: [media] staging: sir: fill in missing fields and fix probe Some fields are left blank. Cc: stable@vger.kernel.org # v4.11 Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index e498ae8..9905990 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -227,6 +227,7 @@ static int init_chrdev(void) if (!rcdev) return -ENOMEM; + rcdev->input_name = "SIR IrDA port"; rcdev->input_phys = KBUILD_MODNAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; @@ -234,6 +235,7 @@ static int init_chrdev(void) rcdev->input_id.version = 0x0100; rcdev->tx_ir = sir_tx_ir; rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rcdev->driver_name = KBUILD_MODNAME; rcdev->map_name = RC_MAP_RC6_MCE; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->dev.parent = &sir_ir_dev->dev; @@ -740,7 +742,13 @@ static int init_sir_ir(void) static int sir_ir_probe(struct platform_device *dev) { - return 0; + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + + return init_sir_ir(); } static int sir_ir_remove(struct platform_device *dev) @@ -780,18 +788,8 @@ static int __init sir_ir_init(void) goto pdev_add_fail; } - retval = init_chrdev(); - if (retval < 0) - goto fail; - - retval = init_sir_ir(); - if (retval) - goto fail; - return 0; -fail: - platform_device_del(sir_ir_dev); pdev_add_fail: platform_device_put(sir_ir_dev); pdev_alloc_fail: -- cgit v1.1 From 402e7b63df726c37d3741aeec5d149b409be5143 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 7 Mar 2017 16:13:15 -0300 Subject: [media] staging: sir: remove unselectable Tekram and Actisys Support for these sir ports is not compiled in by default, it has to be enabled by manually defining LIRC_TEKRAM, LIRC_SIR_ACTISYS_ACT200L or LIRC_SIR_ACTISYS_ACT220L somewhere. This cannot be done from Kconfig at all so remove them from the driver. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 348 +--------------------------------- 1 file changed, 3 insertions(+), 345 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 9905990..e223fa9 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -1,5 +1,5 @@ /* - * LIRC SIR driver, (C) 2000 Milan Pikula + * IR SIR driver, (C) 2000 Milan Pikula * * sir_ir - Device driver for use with SIR (serial infra red) * mode of IrDA on many notebooks. @@ -17,20 +17,6 @@ * 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 - * - * - * 2000/09/16 Frank Przybylski : - * added timeout and relaxed pulse detection, removed gap bug - * - * 2000/12/15 Christoph Bartelmus : - * added support for Tekram Irmate 210 (sending does not work yet, - * kind of disappointing that nobody was able to implement that - * before), - * major clean-up - * - * 2001/02/27 Christoph Bartelmus : - * added support for StrongARM SA1100 embedded microprocessor - * parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -61,62 +47,18 @@ #include /* SECTION: Definitions */ - -/*** Tekram dongle ***/ -#ifdef LIRC_SIR_TEKRAM -/* stolen from kernel source */ -/* definitions for Tekram dongle */ -#define TEKRAM_115200 0x00 -#define TEKRAM_57600 0x01 -#define TEKRAM_38400 0x02 -#define TEKRAM_19200 0x03 -#define TEKRAM_9600 0x04 -#define TEKRAM_2400 0x08 - -#define TEKRAM_PW 0x10 /* Pulse select bit */ - -/* 10bit * 1s/115200bit in milliseconds = 87ms*/ -#define TIME_CONST (10000000ul/115200ul) - -#endif - -#ifdef LIRC_SIR_ACTISYS_ACT200L -static void init_act200(void); -#elif defined(LIRC_SIR_ACTISYS_ACT220L) -static void init_act220(void); -#endif - #define PULSE '[' -#ifndef LIRC_SIR_TEKRAM /* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ #define TIME_CONST (9000000ul/115200ul) -#endif - /* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */ #define SIR_TIMEOUT (HZ*5/100) -#ifndef LIRC_ON_SA1100 -#ifndef LIRC_IRQ -#define LIRC_IRQ 4 -#endif -#ifndef LIRC_PORT -/* for external dongles, default to com1 */ -#if defined(LIRC_SIR_ACTISYS_ACT200L) || \ - defined(LIRC_SIR_ACTISYS_ACT220L) || \ - defined(LIRC_SIR_TEKRAM) -#define LIRC_PORT 0x3f8 -#else /* onboard sir ports are typically com3 */ -#define LIRC_PORT 0x3e8 -#endif -#endif - -static int io = LIRC_PORT; -static int irq = LIRC_IRQ; +static int io = 0x3e8; +static int irq = 4; static int threshold = 3; -#endif static DEFINE_SPINLOCK(timer_lock); static struct timer_list timerlist; @@ -392,71 +334,6 @@ static int init_hardware(void) spin_lock_irqsave(&hardware_lock, flags); /* reset UART */ -#if defined(LIRC_SIR_TEKRAM) - /* disable FIFO */ - soutp(UART_FCR, - UART_FCR_CLEAR_RCVR| - UART_FCR_CLEAR_XMIT| - UART_FCR_TRIGGER_1); - - /* 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))); - - /* Set DLAB 1. */ - soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); - - /* Set divisor to 12 => 9600 Baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 12); - - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - /* power supply */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - safe_udelay(50*1000); - - /* -DTR low -> reset PIC */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); - udelay(1*1000); - - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - udelay(100); - - - /* -RTS low -> send control byte */ - soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); - udelay(7); - soutp(UART_TX, TEKRAM_115200|TEKRAM_PW); - - /* one byte takes ~1042 usec to transmit at 9600,8N1 */ - udelay(1500); - - /* back to normal operation */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - udelay(50); - - udelay(1500); - - /* read previous control byte */ - pr_info("0x%02x\n", sinp(UART_RX)); - - /* 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, 8 Bit */ - soutp(UART_LCR, UART_LCR_WLEN8); - /* enable interrupts */ - soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); -#else outb(0, io + UART_MCR); outb(0, io + UART_IER); /* init UART */ @@ -472,12 +349,6 @@ static int init_hardware(void) outb(UART_IER_RDI, io + UART_IER); /* turn on UART */ outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR); -#ifdef LIRC_SIR_ACTISYS_ACT200L - init_act200(); -#elif defined(LIRC_SIR_ACTISYS_ACT220L) - init_act220(); -#endif -#endif spin_unlock_irqrestore(&hardware_lock, flags); return 0; } @@ -526,208 +397,6 @@ static void drop_port(void) release_region(io, 8); } -#ifdef LIRC_SIR_ACTISYS_ACT200L -/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */ -/* some code borrowed from Linux IRDA driver */ - -/* Register 0: Control register #1 */ -#define ACT200L_REG0 0x00 -#define ACT200L_TXEN 0x01 /* Enable transmitter */ -#define ACT200L_RXEN 0x02 /* Enable receiver */ -#define ACT200L_ECHO 0x08 /* Echo control chars */ - -/* Register 1: Control register #2 */ -#define ACT200L_REG1 0x10 -#define ACT200L_LODB 0x01 /* Load new baud rate count value */ -#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */ - -/* Register 3: Transmit mode register #2 */ -#define ACT200L_REG3 0x30 -#define ACT200L_B0 0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ -#define ACT200L_B1 0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ -#define ACT200L_CHSY 0x04 /* StartBit Synced 0=bittime, 1=startbit */ - -/* Register 4: Output Power register */ -#define ACT200L_REG4 0x40 -#define ACT200L_OP0 0x01 /* Enable LED1C output */ -#define ACT200L_OP1 0x02 /* Enable LED2C output */ -#define ACT200L_BLKR 0x04 - -/* Register 5: Receive Mode register */ -#define ACT200L_REG5 0x50 -#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */ - /*.. other various IRDA bit modes, and TV remote modes..*/ - -/* Register 6: Receive Sensitivity register #1 */ -#define ACT200L_REG6 0x60 -#define ACT200L_RS0 0x01 /* receive threshold bit 0 */ -#define ACT200L_RS1 0x02 /* receive threshold bit 1 */ - -/* Register 7: Receive Sensitivity register #2 */ -#define ACT200L_REG7 0x70 -#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */ - -/* Register 8,9: Baud Rate Divider register #1,#2 */ -#define ACT200L_REG8 0x80 -#define ACT200L_REG9 0x90 - -#define ACT200L_2400 0x5f -#define ACT200L_9600 0x17 -#define ACT200L_19200 0x0b -#define ACT200L_38400 0x05 -#define ACT200L_57600 0x03 -#define ACT200L_115200 0x01 - -/* Register 13: Control register #3 */ -#define ACT200L_REG13 0xd0 -#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */ - -/* Register 15: Status register */ -#define ACT200L_REG15 0xf0 - -/* Register 21: Control register #4 */ -#define ACT200L_REG21 0x50 -#define ACT200L_EXCK 0x02 /* Disable clock output driver */ -#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */ - -static void init_act200(void) -{ - int i; - __u8 control[] = { - ACT200L_REG15, - ACT200L_REG13 | ACT200L_SHDW, - ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, - ACT200L_REG13, - ACT200L_REG7 | ACT200L_ENPOS, - ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1, - ACT200L_REG5 | ACT200L_RWIDL, - ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR, - ACT200L_REG3 | ACT200L_B0, - ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN, - ACT200L_REG8 | (ACT200L_115200 & 0x0f), - ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f), - ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE - }; - - /* Set DLAB 1. */ - soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8); - - /* Set divisor to 12 => 9600 Baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 12); - - /* Set DLAB 0. */ - soutp(UART_LCR, UART_LCR_WLEN8); - /* Set divisor to 12 => 9600 Baud */ - - /* power supply */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - for (i = 0; i < 50; i++) - safe_udelay(1000); - - /* Reset the dongle : set RTS low for 25 ms */ - soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); - for (i = 0; i < 25; i++) - udelay(1000); - - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - udelay(100); - - /* Clear DTR and set RTS to enter command mode */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); - udelay(7); - - /* send out the control register settings for 115K 7N1 SIR operation */ - for (i = 0; i < sizeof(control); i++) { - soutp(UART_TX, control[i]); - /* one byte takes ~1042 usec to transmit at 9600,8N1 */ - udelay(1500); - } - - /* back to normal operation */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - udelay(50); - - udelay(1500); - soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); - - /* Set DLAB 1. */ - soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); - - /* Set divisor to 1 => 115200 Baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 1); - - /* Set DLAB 0. */ - soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); - - /* Set DLAB 0, 7 Bit */ - soutp(UART_LCR, UART_LCR_WLEN7); - - /* enable interrupts */ - soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); -} -#endif - -#ifdef LIRC_SIR_ACTISYS_ACT220L -/* - * Derived from linux IrDA driver (net/irda/actisys.c) - * Drop me a mail for any kind of comment: maxx@spaceboyz.net - */ - -void init_act220(void) -{ - int i; - - /* DLAB 1 */ - soutp(UART_LCR, UART_LCR_DLAB|UART_LCR_WLEN7); - - /* 9600 baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 12); - - /* DLAB 0 */ - soutp(UART_LCR, UART_LCR_WLEN7); - - /* reset the dongle, set DTR low for 10us */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); - udelay(10); - - /* back to normal (still 9600) */ - soutp(UART_MCR, UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2); - - /* - * send RTS pulses until we reach 115200 - * i hope this is really the same for act220l/act220l+ - */ - for (i = 0; i < 3; i++) { - udelay(10); - /* set RTS low for 10 us */ - soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); - udelay(10); - /* set RTS high for 10 us */ - soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); - } - - /* back to normal operation */ - udelay(1500); /* better safe than sorry ;) */ - - /* Set DLAB 1. */ - soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); - - /* Set divisor to 1 => 115200 Baud */ - soutp(UART_DLM, 0); - soutp(UART_DLL, 1); - - /* Set DLAB 0, 7 Bit */ - /* The dongle doesn't seem to have any problems with operation at 7N1 */ - soutp(UART_LCR, UART_LCR_WLEN7); - - /* enable interrupts */ - soutp(UART_IER, UART_IER_RDI); -} -#endif - static int init_sir_ir(void) { int retval; @@ -809,19 +478,8 @@ static void __exit sir_ir_exit(void) module_init(sir_ir_init); module_exit(sir_ir_exit); -#ifdef LIRC_SIR_TEKRAM -MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210"); -MODULE_AUTHOR("Christoph Bartelmus"); -#elif defined(LIRC_SIR_ACTISYS_ACT200L) -MODULE_DESCRIPTION("LIRC driver for Actisys Act200L"); -MODULE_AUTHOR("Karl Bongers"); -#elif defined(LIRC_SIR_ACTISYS_ACT220L) -MODULE_DESCRIPTION("LIRC driver for Actisys Act220L(+)"); -MODULE_AUTHOR("Jan Roemisch"); -#else MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); MODULE_AUTHOR("Milan Pikula"); -#endif MODULE_LICENSE("GPL"); module_param(io, int, 0444); -- cgit v1.1 From 43371f6b327f9fbf1df057be7ce057a0fd841e4c Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 7 Mar 2017 16:25:45 -0300 Subject: [media] staging: sir: fix checkpatch strict warnings Make the code more readable and clean up the includes list. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 45 +++++++---------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index e223fa9..1362900 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -8,52 +8,28 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include -#include -#include -#include #include -#include #include #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include -#include - #include /* SECTION: Definitions */ #define PULSE '[' /* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ -#define TIME_CONST (9000000ul/115200ul) +#define TIME_CONST (9000000ul / 115200ul) /* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */ -#define SIR_TIMEOUT (HZ*5/100) +#define SIR_TIMEOUT (HZ * 5 / 100) /* onboard sir ports are typically com3 */ static int io = 0x3e8; @@ -103,7 +79,7 @@ static inline void soutp(int offset, int value) #ifndef MAX_UDELAY_MS #define MAX_UDELAY_US 5000 #else -#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#define MAX_UDELAY_US (MAX_UDELAY_MS * 1000) #endif static void safe_udelay(unsigned long usecs) @@ -227,18 +203,13 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) int iir, lsr; while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { - switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */ + switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */ case UART_IIR_MSI: - (void) inb(io + UART_MSR); + (void)inb(io + UART_MSR); break; case UART_IIR_RLSI: - (void) inb(io + UART_LSR); - break; case UART_IIR_THRI: -#if 0 - if (lsr & UART_LSR_THRE) /* FIFO is empty */ - outb(data, io + UART_TX) -#endif + (void)inb(io + UART_LSR); break; case UART_IIR_RDI: /* avoid interference with timer */ @@ -279,7 +250,7 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) * the other case is timeout */ add_read_queue(last_value, - delt-TIME_CONST); + delt - TIME_CONST); last_value = data; last = curr_time; last = ktime_sub_us(last, @@ -348,7 +319,7 @@ static int init_hardware(void) /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ outb(UART_IER_RDI, io + UART_IER); /* turn on UART */ - outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR); + outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR); spin_unlock_irqrestore(&hardware_lock, flags); return 0; } -- cgit v1.1 From 19bc4e05fa9600a62051de637d0b1fda5585da64 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 7 Mar 2017 17:01:48 -0300 Subject: [media] staging: sir: use usleep_range() rather than busy looping usleep_range() is perfect for this. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 1362900..e21f163 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -76,21 +76,6 @@ static inline void soutp(int offset, int value) outb(value, io + offset); } -#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) -{ - while (usecs > MAX_UDELAY_US) { - udelay(MAX_UDELAY_US); - usecs -= MAX_UDELAY_US; - } - udelay(usecs); -} - /* SECTION: Communication with user-space */ static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf, unsigned int count) @@ -281,7 +266,7 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) static void send_space(unsigned long len) { - safe_udelay(len); + usleep_range(len, len + 25); } static void send_pulse(unsigned long len) -- cgit v1.1 From 4d7cf7ec84a84b4950d8fb36c627771d38058300 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 25 Mar 2017 07:41:39 -0300 Subject: [media] staging: sir: remove unnecessary messages No need to warn when kmalloc fails. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index e21f163..181ac63 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -49,8 +49,6 @@ static struct platform_device *sir_ir_dev; static DEFINE_SPINLOCK(hardware_lock); -static bool debug; - /* SECTION: Prototypes */ /* Communication with user-space */ @@ -361,7 +359,6 @@ static int init_sir_ir(void) if (retval < 0) return retval; init_hardware(); - pr_info("Installed.\n"); return 0; } @@ -394,24 +391,18 @@ static int __init sir_ir_init(void) int retval; retval = platform_driver_register(&sir_ir_driver); - if (retval) { - pr_err("Platform driver register failed!\n"); - return -ENODEV; - } + if (retval) + return retval; sir_ir_dev = platform_device_alloc("sir_ir", 0); if (!sir_ir_dev) { - pr_err("Platform device alloc failed!\n"); retval = -ENOMEM; goto pdev_alloc_fail; } retval = platform_device_add(sir_ir_dev); - if (retval) { - pr_err("Platform device add failed!\n"); - retval = -ENODEV; + if (retval) goto pdev_add_fail; - } return 0; @@ -428,7 +419,6 @@ static void __exit sir_ir_exit(void) drop_port(); platform_device_unregister(sir_ir_dev); platform_driver_unregister(&sir_ir_driver); - pr_info("Uninstalled.\n"); } module_init(sir_ir_init); @@ -446,6 +436,3 @@ MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); module_param(threshold, int, 0444); MODULE_PARM_DESC(threshold, "space detection threshold (3)"); - -module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, "Enable debugging messages"); -- cgit v1.1 From 8c7c6cad6aee5013694120a2b2907c530c08a245 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 25 Mar 2017 08:45:38 -0300 Subject: [media] staging: sir: make sure we are ready to receive interrupts Ensure that the timer is ready before we request interrupts. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_sir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 181ac63..e12ec50 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -325,6 +325,8 @@ static int init_port(void) { int retval; + setup_timer(&timerlist, sir_timeout, 0); + /* get I/O port access and IRQ line */ if (!request_region(io, 8, KBUILD_MODNAME)) { pr_err("i/o port 0x%.4x already in use.\n", io); @@ -339,8 +341,6 @@ static int init_port(void) } pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq); - setup_timer(&timerlist, sir_timeout, 0); - return 0; } -- cgit v1.1 From e66267161971155a8b4756b4e17f2f2f82b9f842 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 7 Mar 2017 17:07:59 -0300 Subject: [media] rc: promote lirc_sir out of staging Rename lirc_sir to sir_ir in the process. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/Kconfig | 6 - drivers/staging/media/lirc/Makefile | 1 - drivers/staging/media/lirc/lirc_sir.c | 438 ---------------------------------- 3 files changed, 445 deletions(-) delete mode 100644 drivers/staging/media/lirc/lirc_sir.c (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig index bc67da2..e020651 100644 --- a/drivers/staging/media/lirc/Kconfig +++ b/drivers/staging/media/lirc/Kconfig @@ -18,12 +18,6 @@ config LIRC_SASEM help Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module -config LIRC_SIR - tristate "Built-in SIR IrDA port" - depends on RC_CORE - help - Driver for the SIR IrDA port - config LIRC_ZILOG tristate "Zilog/Hauppauge IR Transmitter" depends on LIRC && I2C diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile index 28740c9..70f2237 100644 --- a/drivers/staging/media/lirc/Makefile +++ b/drivers/staging/media/lirc/Makefile @@ -4,5 +4,4 @@ # Each configuration option enables a list of files. obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o -obj-$(CONFIG_LIRC_SIR) += lirc_sir.o obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c deleted file mode 100644 index e12ec50..0000000 --- a/drivers/staging/media/lirc/lirc_sir.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * IR SIR driver, (C) 2000 Milan Pikula - * - * sir_ir - Device driver for use with SIR (serial infra red) - * mode of IrDA on many notebooks. - * - * 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. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include - -#include - -/* SECTION: Definitions */ -#define PULSE '[' - -/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ -#define TIME_CONST (9000000ul / 115200ul) - -/* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */ -#define SIR_TIMEOUT (HZ * 5 / 100) - -/* onboard sir ports are typically com3 */ -static int io = 0x3e8; -static int irq = 4; -static int threshold = 3; - -static DEFINE_SPINLOCK(timer_lock); -static struct timer_list timerlist; -/* time of last signal change detected */ -static ktime_t last; -/* time of last UART data ready interrupt */ -static ktime_t last_intr_time; -static int last_value; -static struct rc_dev *rcdev; - -static struct platform_device *sir_ir_dev; - -static DEFINE_SPINLOCK(hardware_lock); - -/* SECTION: Prototypes */ - -/* Communication with user-space */ -static void add_read_queue(int flag, unsigned long val); -static int init_chrdev(void); -/* Hardware */ -static irqreturn_t sir_interrupt(int irq, void *dev_id); -static void send_space(unsigned long len); -static void send_pulse(unsigned long len); -static int init_hardware(void); -static void drop_hardware(void); -/* Initialisation */ -static int init_port(void); -static void drop_port(void); - -static inline unsigned int sinp(int offset) -{ - return inb(io + offset); -} - -static inline void soutp(int offset, int value) -{ - outb(value, io + offset); -} - -/* SECTION: Communication with user-space */ -static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf, - unsigned int count) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < count;) { - if (tx_buf[i]) - send_pulse(tx_buf[i]); - i++; - if (i >= count) - break; - if (tx_buf[i]) - send_space(tx_buf[i]); - i++; - } - local_irq_restore(flags); - - return count; -} - -static void add_read_queue(int flag, unsigned long val) -{ - DEFINE_IR_RAW_EVENT(ev); - - pr_debug("add flag %d with val %lu\n", flag, val); - - /* - * statistically, pulses are ~TIME_CONST/2 too long. we could - * maybe make this more exact, but this is good enough - */ - if (flag) { - /* pulse */ - if (val > TIME_CONST / 2) - val -= TIME_CONST / 2; - else /* should not ever happen */ - val = 1; - ev.pulse = true; - } else { - val += TIME_CONST / 2; - } - ev.duration = US_TO_NS(val); - - ir_raw_event_store_with_filter(rcdev, &ev); -} - -static int init_chrdev(void) -{ - rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW); - if (!rcdev) - return -ENOMEM; - - rcdev->input_name = "SIR IrDA port"; - 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->tx_ir = sir_tx_ir; - rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; - rcdev->driver_name = KBUILD_MODNAME; - rcdev->map_name = RC_MAP_RC6_MCE; - rcdev->timeout = IR_DEFAULT_TIMEOUT; - rcdev->dev.parent = &sir_ir_dev->dev; - - return devm_rc_register_device(&sir_ir_dev->dev, rcdev); -} - -/* SECTION: Hardware */ -static void sir_timeout(unsigned long data) -{ - /* - * if last received signal was a pulse, but receiving stopped - * within the 9 bit frame, we need to finish this pulse and - * simulate a signal change to from pulse to space. Otherwise - * upper layers will receive two sequences next time. - */ - - unsigned long flags; - unsigned long pulse_end; - - /* avoid interference with interrupt */ - spin_lock_irqsave(&timer_lock, flags); - if (last_value) { - /* clear unread bits in UART and restart */ - outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); - /* determine 'virtual' pulse end: */ - pulse_end = min_t(unsigned long, - ktime_us_delta(last, last_intr_time), - IR_MAX_DURATION); - dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n", - last_value, pulse_end); - add_read_queue(last_value, pulse_end); - last_value = 0; - last = last_intr_time; - } - spin_unlock_irqrestore(&timer_lock, flags); - ir_raw_event_handle(rcdev); -} - -static irqreturn_t sir_interrupt(int irq, void *dev_id) -{ - unsigned char data; - ktime_t curr_time; - static unsigned long delt; - unsigned long deltintr; - unsigned long flags; - int iir, lsr; - - while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { - switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */ - case UART_IIR_MSI: - (void)inb(io + UART_MSR); - break; - case UART_IIR_RLSI: - case UART_IIR_THRI: - (void)inb(io + UART_LSR); - break; - case UART_IIR_RDI: - /* avoid interference with timer */ - spin_lock_irqsave(&timer_lock, flags); - do { - del_timer(&timerlist); - data = inb(io + UART_RX); - curr_time = ktime_get(); - delt = min_t(unsigned long, - ktime_us_delta(last, curr_time), - IR_MAX_DURATION); - deltintr = min_t(unsigned long, - ktime_us_delta(last_intr_time, - curr_time), - IR_MAX_DURATION); - dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n", - deltintr, (int)data); - /* - * if nothing came in last X cycles, - * it was gap - */ - if (deltintr > TIME_CONST * threshold) { - if (last_value) { - dev_dbg(&sir_ir_dev->dev, "GAP\n"); - /* simulate signal change */ - add_read_queue(last_value, - delt - - deltintr); - last_value = 0; - last = last_intr_time; - delt = deltintr; - } - } - data = 1; - if (data ^ last_value) { - /* - * deltintr > 2*TIME_CONST, remember? - * the other case is timeout - */ - add_read_queue(last_value, - delt - TIME_CONST); - last_value = data; - last = curr_time; - last = ktime_sub_us(last, - TIME_CONST); - } - last_intr_time = curr_time; - if (data) { - /* - * start timer for end of - * sequence detection - */ - timerlist.expires = jiffies + - SIR_TIMEOUT; - add_timer(&timerlist); - } - - lsr = inb(io + UART_LSR); - } while (lsr & UART_LSR_DR); /* data ready */ - spin_unlock_irqrestore(&timer_lock, flags); - break; - default: - break; - } - } - ir_raw_event_handle(rcdev); - return IRQ_RETVAL(IRQ_HANDLED); -} - -static void send_space(unsigned long len) -{ - usleep_range(len, len + 25); -} - -static void send_pulse(unsigned long len) -{ - long bytes_out = len / TIME_CONST; - - if (bytes_out == 0) - bytes_out++; - - while (bytes_out--) { - outb(PULSE, io + UART_TX); - /* FIXME treba seriozne cakanie z char/serial.c */ - while (!(inb(io + UART_LSR) & UART_LSR_THRE)) - ; - } -} - -static int init_hardware(void) -{ - unsigned long flags; - - spin_lock_irqsave(&hardware_lock, flags); - /* reset UART */ - outb(0, io + UART_MCR); - outb(0, io + UART_IER); - /* init UART */ - /* set DLAB, speed = 115200 */ - outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR); - outb(1, io + UART_DLL); outb(0, io + UART_DLM); - /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */ - outb(UART_LCR_WLEN7, io + UART_LCR); - /* FIFO operation */ - outb(UART_FCR_ENABLE_FIFO, io + UART_FCR); - /* interrupts */ - /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ - outb(UART_IER_RDI, io + UART_IER); - /* turn on UART */ - outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR); - spin_unlock_irqrestore(&hardware_lock, flags); - return 0; -} - -static void drop_hardware(void) -{ - unsigned long flags; - - spin_lock_irqsave(&hardware_lock, flags); - - /* turn off interrupts */ - outb(0, io + UART_IER); - - spin_unlock_irqrestore(&hardware_lock, flags); -} - -/* SECTION: Initialisation */ - -static int init_port(void) -{ - int retval; - - setup_timer(&timerlist, sir_timeout, 0); - - /* get I/O port access and IRQ line */ - if (!request_region(io, 8, KBUILD_MODNAME)) { - pr_err("i/o port 0x%.4x already in use.\n", io); - return -EBUSY; - } - retval = request_irq(irq, sir_interrupt, 0, - KBUILD_MODNAME, NULL); - if (retval < 0) { - release_region(io, 8); - pr_err("IRQ %d already in use.\n", irq); - return retval; - } - pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq); - - return 0; -} - -static void drop_port(void) -{ - free_irq(irq, NULL); - del_timer_sync(&timerlist); - release_region(io, 8); -} - -static int init_sir_ir(void) -{ - int retval; - - retval = init_port(); - if (retval < 0) - return retval; - init_hardware(); - return 0; -} - -static int sir_ir_probe(struct platform_device *dev) -{ - int retval; - - retval = init_chrdev(); - if (retval < 0) - return retval; - - return init_sir_ir(); -} - -static int sir_ir_remove(struct platform_device *dev) -{ - return 0; -} - -static struct platform_driver sir_ir_driver = { - .probe = sir_ir_probe, - .remove = sir_ir_remove, - .driver = { - .name = "sir_ir", - }, -}; - -static int __init sir_ir_init(void) -{ - int retval; - - retval = platform_driver_register(&sir_ir_driver); - if (retval) - return retval; - - sir_ir_dev = platform_device_alloc("sir_ir", 0); - if (!sir_ir_dev) { - retval = -ENOMEM; - goto pdev_alloc_fail; - } - - retval = platform_device_add(sir_ir_dev); - if (retval) - goto pdev_add_fail; - - return 0; - -pdev_add_fail: - platform_device_put(sir_ir_dev); -pdev_alloc_fail: - platform_driver_unregister(&sir_ir_driver); - return retval; -} - -static void __exit sir_ir_exit(void) -{ - drop_hardware(); - drop_port(); - platform_device_unregister(sir_ir_dev); - platform_driver_unregister(&sir_ir_driver); -} - -module_init(sir_ir_init); -module_exit(sir_ir_exit); - -MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); -MODULE_AUTHOR("Milan Pikula"); -MODULE_LICENSE("GPL"); - -module_param(io, int, 0444); -MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); - -module_param(irq, int, 0444); -MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); - -module_param(threshold, int, 0444); -MODULE_PARM_DESC(threshold, "space detection threshold (3)"); -- cgit v1.1 From 51bb3fd788cb6be773d1d4ede43b18bcc053bb2f Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 7 Mar 2017 17:09:11 -0300 Subject: [media] staging: lirc_sasem: remove This driver was merged in 2010 and never had the necessary work done to promote it out of staging (port to rc-core), so remove it. I have not managed to track down the hardware. If anyone has the hardware and would like a driver for it, please contact me and hopefully we can work together to write a new driver. Signed-off-by: Sean Young Cc: Oliver Stabel Cc: Tim Davies Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/Kconfig | 6 - drivers/staging/media/lirc/Makefile | 1 - drivers/staging/media/lirc/lirc_sasem.c | 899 -------------------------------- 3 files changed, 906 deletions(-) delete mode 100644 drivers/staging/media/lirc/lirc_sasem.c (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig index e020651..3e350a9 100644 --- a/drivers/staging/media/lirc/Kconfig +++ b/drivers/staging/media/lirc/Kconfig @@ -12,12 +12,6 @@ menuconfig LIRC_STAGING if LIRC_STAGING -config LIRC_SASEM - tristate "Sasem USB IR Remote" - depends on LIRC && USB - help - Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module - config LIRC_ZILOG tristate "Zilog/Hauppauge IR Transmitter" depends on LIRC && I2C diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile index 70f2237..6655624 100644 --- a/drivers/staging/media/lirc/Makefile +++ b/drivers/staging/media/lirc/Makefile @@ -3,5 +3,4 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c deleted file mode 100644 index ac69fe1..0000000 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * lirc_sasem.c - USB remote support for LIRC - * Version 0.5 - * - * Copyright (C) 2004-2005 Oliver Stabel - * Tim Davies - * - * This driver was derived from: - * Venky Raju - * "lirc_imon - "LIRC/VFD driver for Ahanix/Soundgraph IMON IR/VFD" - * Paul Miller 's 2003-2004 - * "lirc_atiusb - USB remote support for LIRC" - * Culver Consulting Services 's 2003 - * "Sasem OnAir VFD/IR USB driver" - * - * - * NOTE - The LCDproc iMon driver should work with this module. More info at - * http://www.frogstorm.info/sasem - */ - -/* - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MOD_AUTHOR "Oliver Stabel , " \ - "Tim Davies " -#define MOD_DESC "USB Driver for Sasem Remote Controller V1.1" -#define MOD_NAME "lirc_sasem" -#define MOD_VERSION "0.5" - -#define VFD_MINOR_BASE 144 /* Same as LCD */ -#define DEVICE_NAME "lcd%d" - -#define BUF_CHUNK_SIZE 8 -#define BUF_SIZE 128 - -#define IOCTL_LCD_CONTRAST 1 - -/*** P R O T O T Y P E S ***/ - -/* USB Callback prototypes */ -static int sasem_probe(struct usb_interface *interface, - const struct usb_device_id *id); -static void sasem_disconnect(struct usb_interface *interface); -static void usb_rx_callback(struct urb *urb); -static void usb_tx_callback(struct urb *urb); - -/* VFD file_operations function prototypes */ -static int vfd_open(struct inode *inode, struct file *file); -static long vfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static int vfd_close(struct inode *inode, struct file *file); -static ssize_t vfd_write(struct file *file, const char __user *buf, - size_t n_bytes, loff_t *pos); - -/* LIRC driver function prototypes */ -static int ir_open(void *data); -static void ir_close(void *data); - -/*** G L O B A L S ***/ -#define SASEM_DATA_BUF_SZ 32 - -struct sasem_context { - struct usb_device *dev; - int vfd_isopen; /* VFD port has been opened */ - unsigned int vfd_contrast; /* VFD contrast */ - int ir_isopen; /* IR port has been opened */ - int dev_present; /* USB device presence */ - struct mutex ctx_lock; /* to lock this object */ - wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ - - struct lirc_driver *driver; - struct usb_endpoint_descriptor *rx_endpoint; - struct usb_endpoint_descriptor *tx_endpoint; - struct urb *rx_urb; - struct urb *tx_urb; - unsigned char usb_rx_buf[8]; - unsigned char usb_tx_buf[8]; - - struct tx_t { - unsigned char data_buf[SASEM_DATA_BUF_SZ]; /* user data - * buffer - */ - struct completion finished; /* wait for write to finish */ - atomic_t busy; /* write in progress */ - int status; /* status of tx completion */ - } tx; - - /* for dealing with repeat codes (wish there was a toggle bit!) */ - ktime_t presstime; - char lastcode[8]; - int codesaved; -}; - -/* VFD file operations */ -static const struct file_operations vfd_fops = { - .owner = THIS_MODULE, - .open = &vfd_open, - .write = vfd_write, - .unlocked_ioctl = &vfd_ioctl, - .release = &vfd_close, - .llseek = noop_llseek, -}; - -/* USB Device ID for Sasem USB Control Board */ -static struct usb_device_id sasem_usb_id_table[] = { - /* Sasem USB Control Board */ - { USB_DEVICE(0x11ba, 0x0101) }, - /* Terminating entry */ - {} -}; - -/* USB Device data */ -static struct usb_driver sasem_driver = { - .name = MOD_NAME, - .probe = sasem_probe, - .disconnect = sasem_disconnect, - .id_table = sasem_usb_id_table, -}; - -static struct usb_class_driver sasem_class = { - .name = DEVICE_NAME, - .fops = &vfd_fops, - .minor_base = VFD_MINOR_BASE, -}; - -/* to prevent races between open() and disconnect() */ -static DEFINE_MUTEX(disconnect_lock); - -static int debug; - - -/*** M O D U L E C O D E ***/ -MODULE_AUTHOR(MOD_AUTHOR); -MODULE_DESCRIPTION(MOD_DESC); -MODULE_LICENSE("GPL"); -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); - -static void delete_context(struct sasem_context *context) -{ - usb_free_urb(context->tx_urb); /* VFD */ - usb_free_urb(context->rx_urb); /* IR */ - lirc_buffer_free(context->driver->rbuf); - kfree(context->driver->rbuf); - kfree(context->driver); - kfree(context); -} - -static void deregister_from_lirc(struct sasem_context *context) -{ - int retval; - int minor = context->driver->minor; - - retval = lirc_unregister_driver(minor); - if (retval) - dev_err(&context->dev->dev, - "%s: unable to deregister from lirc (%d)\n", - __func__, retval); - else - dev_info(&context->dev->dev, - "Deregistered Sasem driver (minor:%d)\n", minor); -} - -/** - * Called when the VFD device (e.g. /dev/usb/lcd) - * is opened by the application. - */ -static int vfd_open(struct inode *inode, struct file *file) -{ - struct usb_interface *interface; - struct sasem_context *context = NULL; - int subminor; - int retval = 0; - - /* prevent races with disconnect */ - mutex_lock(&disconnect_lock); - - subminor = iminor(inode); - interface = usb_find_interface(&sasem_driver, subminor); - if (!interface) { - pr_err("%s: could not find interface for minor %d\n", - __func__, subminor); - retval = -ENODEV; - goto exit; - } - context = usb_get_intfdata(interface); - - if (!context) { - dev_err(&interface->dev, "no context found for minor %d\n", - subminor); - retval = -ENODEV; - goto exit; - } - - mutex_lock(&context->ctx_lock); - - if (context->vfd_isopen) { - dev_err(&interface->dev, - "%s: VFD port is already open", __func__); - retval = -EBUSY; - } else { - context->vfd_isopen = 1; - file->private_data = context; - dev_info(&interface->dev, "VFD port opened\n"); - } - - mutex_unlock(&context->ctx_lock); - -exit: - mutex_unlock(&disconnect_lock); - return retval; -} - -/** - * Called when the VFD device (e.g. /dev/usb/lcd) - * is closed by the application. - */ -static long vfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct sasem_context *context; - - context = (struct sasem_context *) file->private_data; - - if (!context) { - pr_err("%s: no context for device\n", __func__); - return -ENODEV; - } - - mutex_lock(&context->ctx_lock); - - switch (cmd) { - case IOCTL_LCD_CONTRAST: - if (arg > 1000) - arg = 1000; - context->vfd_contrast = (unsigned int)arg; - break; - default: - pr_info("Unknown IOCTL command\n"); - mutex_unlock(&context->ctx_lock); - return -ENOIOCTLCMD; /* not supported */ - } - - mutex_unlock(&context->ctx_lock); - return 0; -} - -/** - * Called when the VFD device (e.g. /dev/usb/lcd) - * is closed by the application. - */ -static int vfd_close(struct inode *inode, struct file *file) -{ - struct sasem_context *context = NULL; - int retval = 0; - - context = (struct sasem_context *) file->private_data; - - if (!context) { - pr_err("%s: no context for device\n", __func__); - return -ENODEV; - } - - mutex_lock(&context->ctx_lock); - - if (!context->vfd_isopen) { - dev_err(&context->dev->dev, "%s: VFD is not open\n", __func__); - retval = -EIO; - } else { - context->vfd_isopen = 0; - dev_info(&context->dev->dev, "VFD port closed\n"); - if (!context->dev_present && !context->ir_isopen) { - /* Device disconnected before close and IR port is - * not open. If IR port is open, context will be - * deleted by ir_close. - */ - mutex_unlock(&context->ctx_lock); - delete_context(context); - return retval; - } - } - - mutex_unlock(&context->ctx_lock); - return retval; -} - -/** - * Sends a packet to the VFD. - */ -static int send_packet(struct sasem_context *context) -{ - unsigned int pipe; - int interval = 0; - int retval = 0; - - pipe = usb_sndintpipe(context->dev, - context->tx_endpoint->bEndpointAddress); - interval = context->tx_endpoint->bInterval; - - usb_fill_int_urb(context->tx_urb, context->dev, pipe, - context->usb_tx_buf, sizeof(context->usb_tx_buf), - usb_tx_callback, context, interval); - - context->tx_urb->actual_length = 0; - - init_completion(&context->tx.finished); - atomic_set(&context->tx.busy, 1); - - retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); - if (retval) { - atomic_set(&context->tx.busy, 0); - dev_err(&context->dev->dev, "error submitting urb (%d)\n", - retval); - } else { - /* Wait for transmission to complete (or abort) */ - mutex_unlock(&context->ctx_lock); - wait_for_completion(&context->tx.finished); - mutex_lock(&context->ctx_lock); - - retval = context->tx.status; - if (retval) - dev_err(&context->dev->dev, - "packet tx failed (%d)\n", retval); - } - - return retval; -} - -/** - * Writes data to the VFD. The Sasem VFD is 2x16 characters - * and requires data in 9 consecutive USB interrupt packets, - * each packet carrying 8 bytes. - */ -static ssize_t vfd_write(struct file *file, const char __user *buf, - size_t n_bytes, loff_t *pos) -{ - int i; - int retval = 0; - struct sasem_context *context; - int *data_buf = NULL; - - context = (struct sasem_context *) file->private_data; - if (!context) { - pr_err("%s: no context for device\n", __func__); - return -ENODEV; - } - - mutex_lock(&context->ctx_lock); - - if (!context->dev_present) { - pr_err("%s: no Sasem device present\n", __func__); - retval = -ENODEV; - goto exit; - } - - if (n_bytes <= 0 || n_bytes > SASEM_DATA_BUF_SZ) { - dev_err(&context->dev->dev, "%s: invalid payload size\n", - __func__); - retval = -EINVAL; - goto exit; - } - - data_buf = memdup_user(buf, n_bytes); - if (IS_ERR(data_buf)) { - mutex_unlock(&context->ctx_lock); - return PTR_ERR(data_buf); - } - - memcpy(context->tx.data_buf, data_buf, n_bytes); - - /* Pad with spaces */ - for (i = n_bytes; i < SASEM_DATA_BUF_SZ; ++i) - context->tx.data_buf[i] = ' '; - - /* Nine 8 byte packets to be sent */ - /* NOTE: "\x07\x01\0\0\0\0\0\0" or "\x0c\0\0\0\0\0\0\0" - * will clear the VFD - */ - for (i = 0; i < 9; i++) { - switch (i) { - case 0: - memcpy(context->usb_tx_buf, "\x07\0\0\0\0\0\0\0", 8); - context->usb_tx_buf[1] = (context->vfd_contrast) ? - (0x2B - (context->vfd_contrast - 1) / 250) - : 0x2B; - break; - case 1: - memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); - break; - case 2: - memcpy(context->usb_tx_buf, "\x0b\x01\0\0\0\0\0\0", 8); - break; - case 3: - memcpy(context->usb_tx_buf, context->tx.data_buf, 8); - break; - case 4: - memcpy(context->usb_tx_buf, - context->tx.data_buf + 8, 8); - break; - case 5: - memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); - break; - case 6: - memcpy(context->usb_tx_buf, "\x0b\x02\0\0\0\0\0\0", 8); - break; - case 7: - memcpy(context->usb_tx_buf, - context->tx.data_buf + 16, 8); - break; - case 8: - memcpy(context->usb_tx_buf, - context->tx.data_buf + 24, 8); - break; - } - retval = send_packet(context); - if (retval) { - dev_err(&context->dev->dev, - "send packet failed for packet #%d\n", i); - goto exit; - } - } -exit: - - mutex_unlock(&context->ctx_lock); - kfree(data_buf); - - return (!retval) ? n_bytes : retval; -} - -/** - * Callback function for USB core API: transmit data - */ -static void usb_tx_callback(struct urb *urb) -{ - struct sasem_context *context; - - if (!urb) - return; - context = (struct sasem_context *) urb->context; - if (!context) - return; - - context->tx.status = urb->status; - - /* notify waiters that write has finished */ - atomic_set(&context->tx.busy, 0); - complete(&context->tx.finished); -} - -/** - * Called by lirc_dev when the application opens /dev/lirc - */ -static int ir_open(void *data) -{ - int retval = 0; - struct sasem_context *context; - - /* prevent races with disconnect */ - mutex_lock(&disconnect_lock); - - context = data; - - mutex_lock(&context->ctx_lock); - - if (context->ir_isopen) { - dev_err(&context->dev->dev, "%s: IR port is already open\n", - __func__); - retval = -EBUSY; - goto exit; - } - - usb_fill_int_urb(context->rx_urb, context->dev, - usb_rcvintpipe(context->dev, - context->rx_endpoint->bEndpointAddress), - context->usb_rx_buf, sizeof(context->usb_rx_buf), - usb_rx_callback, context, context->rx_endpoint->bInterval); - - retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); - - if (retval) - dev_err(&context->dev->dev, - "usb_submit_urb failed for ir_open (%d)\n", retval); - else { - context->ir_isopen = 1; - dev_info(&context->dev->dev, "IR port opened\n"); - } - -exit: - mutex_unlock(&context->ctx_lock); - - mutex_unlock(&disconnect_lock); - return retval; -} - -/** - * Called by lirc_dev when the application closes /dev/lirc - */ -static void ir_close(void *data) -{ - struct sasem_context *context; - - context = data; - if (!context) { - pr_err("%s: no context for device\n", __func__); - return; - } - - mutex_lock(&context->ctx_lock); - - usb_kill_urb(context->rx_urb); - context->ir_isopen = 0; - pr_info("IR port closed\n"); - - if (!context->dev_present) { - - /* - * Device disconnected while IR port was - * still open. Driver was not deregistered - * at disconnect time, so do it now. - */ - deregister_from_lirc(context); - if (!context->vfd_isopen) { - mutex_unlock(&context->ctx_lock); - delete_context(context); - return; - } - /* If VFD port is open, context will be deleted by vfd_close */ - } - - mutex_unlock(&context->ctx_lock); -} - -/** - * Process the incoming packet - */ -static void incoming_packet(struct sasem_context *context, - struct urb *urb) -{ - int len = urb->actual_length; - unsigned char *buf = urb->transfer_buffer; - u64 ns; - ktime_t kt; - - if (len != 8) { - dev_warn(&context->dev->dev, - "%s: invalid incoming packet size (%d)\n", - __func__, len); - return; - } - - if (debug) - dev_info(&context->dev->dev, "Incoming data: %*ph\n", len, buf); - /* - * Lirc could deal with the repeat code, but we really need to block it - * if it arrives too late. Otherwise we could repeat the wrong code. - */ - - /* get the time since the last button press */ - kt = ktime_get(); - ns = ktime_to_ns(ktime_sub(kt, context->presstime)); - - if (memcmp(buf, "\x08\0\0\0\0\0\0\0", 8) == 0) { - /* - * the repeat code is being sent, so we copy - * the old code to LIRC - */ - - /* - * NOTE: Only if the last code was less than 250ms ago - * - no one should be able to push another (undetected) button - * in that time and then get a false repeat of the previous - * press but it is long enough for a genuine repeat - */ - if ((ns < 250 * NSEC_PER_MSEC) && (context->codesaved != 0)) { - memcpy(buf, &context->lastcode, 8); - context->presstime = kt; - } - } else { - /* save the current valid code for repeats */ - memcpy(&context->lastcode, buf, 8); - /* - * set flag to signal a valid code was save; - * just for safety reasons - */ - context->codesaved = 1; - context->presstime = kt; - } - - lirc_buffer_write(context->driver->rbuf, buf); - wake_up(&context->driver->rbuf->wait_poll); -} - -/** - * Callback function for USB core API: receive data - */ -static void usb_rx_callback(struct urb *urb) -{ - struct sasem_context *context; - - if (!urb) - return; - context = (struct sasem_context *) urb->context; - if (!context) - return; - - switch (urb->status) { - case -ENOENT: /* usbcore unlink successful! */ - return; - - case 0: - if (context->ir_isopen) - incoming_packet(context, urb); - break; - - default: - dev_warn(&urb->dev->dev, "%s: status (%d): ignored", - __func__, urb->status); - break; - } - - usb_submit_urb(context->rx_urb, GFP_ATOMIC); -} - -/** - * Callback function for USB core API: Probe - */ -static int sasem_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *dev = NULL; - struct usb_host_interface *iface_desc = NULL; - struct usb_endpoint_descriptor *rx_endpoint = NULL; - struct usb_endpoint_descriptor *tx_endpoint = NULL; - struct urb *rx_urb = NULL; - struct urb *tx_urb = NULL; - struct lirc_driver *driver = NULL; - struct lirc_buffer *rbuf = NULL; - int lirc_minor = 0; - int num_endpoints; - int retval = 0; - int vfd_ep_found; - int ir_ep_found; - int alloc_status; - struct sasem_context *context = NULL; - int i; - - dev_info(&interface->dev, "%s: found Sasem device\n", __func__); - - - dev = usb_get_dev(interface_to_usbdev(interface)); - iface_desc = interface->cur_altsetting; - num_endpoints = iface_desc->desc.bNumEndpoints; - - /* - * Scan the endpoint list and set: - * first input endpoint = IR endpoint - * first output endpoint = VFD endpoint - */ - - ir_ep_found = 0; - vfd_ep_found = 0; - - for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { - - struct usb_endpoint_descriptor *ep; - - ep = &iface_desc->endpoint [i].desc; - - if (!ir_ep_found && - usb_endpoint_is_int_in(ep)) { - - rx_endpoint = ep; - ir_ep_found = 1; - if (debug) - dev_info(&interface->dev, - "%s: found IR endpoint\n", __func__); - - } else if (!vfd_ep_found && - usb_endpoint_is_int_out(ep)) { - tx_endpoint = ep; - vfd_ep_found = 1; - if (debug) - dev_info(&interface->dev, - "%s: found VFD endpoint\n", __func__); - } - } - - /* Input endpoint is mandatory */ - if (!ir_ep_found) { - dev_err(&interface->dev, - "%s: no valid input (IR) endpoint found.\n", __func__); - retval = -ENODEV; - goto exit; - } - - if (!vfd_ep_found) - dev_info(&interface->dev, - "%s: no valid output (VFD) endpoint found.\n", - __func__); - - - /* Allocate memory */ - alloc_status = 0; - - context = kzalloc(sizeof(*context), GFP_KERNEL); - if (!context) { - alloc_status = 1; - goto alloc_status_switch; - } - driver = kzalloc(sizeof(*driver), GFP_KERNEL); - if (!driver) { - alloc_status = 2; - goto alloc_status_switch; - } - rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL); - if (!rbuf) { - alloc_status = 3; - goto alloc_status_switch; - } - if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { - dev_err(&interface->dev, - "%s: lirc_buffer_init failed\n", __func__); - alloc_status = 4; - goto alloc_status_switch; - } - rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rx_urb) { - alloc_status = 5; - goto alloc_status_switch; - } - if (vfd_ep_found) { - tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tx_urb) { - alloc_status = 6; - goto alloc_status_switch; - } - } - - mutex_init(&context->ctx_lock); - - strcpy(driver->name, MOD_NAME); - driver->minor = -1; - driver->code_length = 64; - driver->sample_rate = 0; - driver->features = LIRC_CAN_REC_LIRCCODE; - driver->data = context; - driver->rbuf = rbuf; - driver->set_use_inc = ir_open; - driver->set_use_dec = ir_close; - driver->dev = &interface->dev; - driver->owner = THIS_MODULE; - - mutex_lock(&context->ctx_lock); - - lirc_minor = lirc_register_driver(driver); - if (lirc_minor < 0) { - dev_err(&interface->dev, - "%s: lirc_register_driver failed\n", __func__); - alloc_status = 7; - retval = lirc_minor; - goto unlock; - } else - dev_info(&interface->dev, - "%s: Registered Sasem driver (minor:%d)\n", - __func__, lirc_minor); - - /* Needed while unregistering! */ - driver->minor = lirc_minor; - - context->dev = dev; - context->dev_present = 1; - context->rx_endpoint = rx_endpoint; - context->rx_urb = rx_urb; - if (vfd_ep_found) { - context->tx_endpoint = tx_endpoint; - context->tx_urb = tx_urb; - context->vfd_contrast = 1000; /* range 0 - 1000 */ - } - context->driver = driver; - - usb_set_intfdata(interface, context); - - if (vfd_ep_found) { - - if (debug) - dev_info(&interface->dev, - "Registering VFD with sysfs\n"); - if (usb_register_dev(interface, &sasem_class)) - /* Not a fatal error, so ignore */ - dev_info(&interface->dev, - "%s: could not get a minor number for VFD\n", - __func__); - } - - dev_info(&interface->dev, - "%s: Sasem device on usb<%d:%d> initialized\n", - __func__, dev->bus->busnum, dev->devnum); -unlock: - mutex_unlock(&context->ctx_lock); - -alloc_status_switch: - switch (alloc_status) { - - case 7: - if (vfd_ep_found) - usb_free_urb(tx_urb); - case 6: - usb_free_urb(rx_urb); - /* fall-through */ - case 5: - lirc_buffer_free(rbuf); - /* fall-through */ - case 4: - kfree(rbuf); - /* fall-through */ - case 3: - kfree(driver); - /* fall-through */ - case 2: - kfree(context); - context = NULL; - /* fall-through */ - case 1: - if (retval == 0) - retval = -ENOMEM; - } - -exit: - return retval; -} - -/** - * Callback function for USB core API: disconnect - */ -static void sasem_disconnect(struct usb_interface *interface) -{ - struct sasem_context *context; - - /* prevent races with ir_open()/vfd_open() */ - mutex_lock(&disconnect_lock); - - context = usb_get_intfdata(interface); - mutex_lock(&context->ctx_lock); - - dev_info(&interface->dev, "%s: Sasem device disconnected\n", - __func__); - - usb_set_intfdata(interface, NULL); - context->dev_present = 0; - - /* Stop reception */ - usb_kill_urb(context->rx_urb); - - /* Abort ongoing write */ - if (atomic_read(&context->tx.busy)) { - - usb_kill_urb(context->tx_urb); - wait_for_completion(&context->tx.finished); - } - - /* De-register from lirc_dev if IR port is not open */ - if (!context->ir_isopen) - deregister_from_lirc(context); - - usb_deregister_dev(interface, &sasem_class); - - mutex_unlock(&context->ctx_lock); - - if (!context->ir_isopen && !context->vfd_isopen) - delete_context(context); - - mutex_unlock(&disconnect_lock); -} - -module_usb_driver(sasem_driver); -- cgit v1.1 From 2524490c8900e9b0747b16f070de58c8850793e8 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Fri, 24 Mar 2017 13:47:53 -0300 Subject: [media] staging: st-cec: Use cec_get_drvdata() Use helper function to get driver private data from CEC adapter. Signed-off-by: Jose Abreu Cc: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/st-cec/stih-cec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c index 3c25638..521206d 100644 --- a/drivers/staging/media/st-cec/stih-cec.c +++ b/drivers/staging/media/st-cec/stih-cec.c @@ -133,7 +133,7 @@ struct stih_cec { static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable) { - struct stih_cec *cec = adap->priv; + struct stih_cec *cec = cec_get_drvdata(adap); if (enable) { /* The doc says (input TCLK_PERIOD * CEC_CLK_DIV) = 0.1ms */ @@ -189,7 +189,7 @@ static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable) static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr) { - struct stih_cec *cec = adap->priv; + struct stih_cec *cec = cec_get_drvdata(adap); u32 reg = readl(cec->regs + CEC_ADDR_TABLE); reg |= 1 << logical_addr; @@ -205,7 +205,7 @@ static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr) static int stih_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { - struct stih_cec *cec = adap->priv; + struct stih_cec *cec = cec_get_drvdata(adap); int i; /* Copy message into registers */ -- cgit v1.1 From 91f6d55d70708ac3c5b8ede4b8943d701a19889e Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Fri, 24 Mar 2017 13:47:54 -0300 Subject: [media] staging: s5p-cec: Use cec_get_drvdata() Use helper function to get driver private data from CEC adapter. Signed-off-by: Jose Abreu Cc: Kamil Debski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/s5p-cec/s5p_cec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 2a07968..a30b80a 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -37,7 +37,7 @@ MODULE_PARM_DESC(debug, "debug level (0-2)"); static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) { - struct s5p_cec_dev *cec = adap->priv; + struct s5p_cec_dev *cec = cec_get_drvdata(adap); if (enable) { pm_runtime_get_sync(cec->dev); @@ -61,7 +61,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) { - struct s5p_cec_dev *cec = adap->priv; + struct s5p_cec_dev *cec = cec_get_drvdata(adap); s5p_cec_set_addr(cec, addr); return 0; @@ -70,7 +70,7 @@ static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { - struct s5p_cec_dev *cec = adap->priv; + struct s5p_cec_dev *cec = cec_get_drvdata(adap); /* * Unclear if 0 retries are allowed by the hardware, so have 1 as -- cgit v1.1 From fc4e009c6c986a8cc717dc070d65ccb60d7de91a Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Tue, 3 Jan 2017 12:54:56 -0200 Subject: [media] stih-cec: add CEC notifier support By using the CEC notifier framework there is no longer any reason to manually set the physical address. This was the one blocking issue that prevented this driver from going out of staging, so do this move as well. Signed-off-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/st-cec/Kconfig | 8 - drivers/staging/media/st-cec/Makefile | 1 - drivers/staging/media/st-cec/TODO | 7 - drivers/staging/media/st-cec/stih-cec.c | 379 -------------------------------- 6 files changed, 398 deletions(-) delete mode 100644 drivers/staging/media/st-cec/Kconfig delete mode 100644 drivers/staging/media/st-cec/Makefile delete mode 100644 drivers/staging/media/st-cec/TODO delete mode 100644 drivers/staging/media/st-cec/stih-cec.c (limited to 'drivers/staging') diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index abd0e2d..28088de 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -34,6 +34,4 @@ source "drivers/staging/media/s5p-cec/Kconfig" # Keep LIRC at the end, as it has sub-menus source "drivers/staging/media/lirc/Kconfig" -source "drivers/staging/media/st-cec/Kconfig" - endif diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index dc89325..75e47dc 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -5,4 +5,3 @@ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_VIDEO_BCM2835) += platform/bcm2835/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ -obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += st-cec/ diff --git a/drivers/staging/media/st-cec/Kconfig b/drivers/staging/media/st-cec/Kconfig deleted file mode 100644 index c04283d..0000000 --- a/drivers/staging/media/st-cec/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -config VIDEO_STI_HDMI_CEC - tristate "STMicroelectronics STiH4xx HDMI CEC driver" - 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. - CEC bus is present in the HDMI connector and enables communication - between compatible devices. diff --git a/drivers/staging/media/st-cec/Makefile b/drivers/staging/media/st-cec/Makefile deleted file mode 100644 index f07905e..0000000 --- a/drivers/staging/media/st-cec/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += stih-cec.o diff --git a/drivers/staging/media/st-cec/TODO b/drivers/staging/media/st-cec/TODO deleted file mode 100644 index c612897..0000000 --- a/drivers/staging/media/st-cec/TODO +++ /dev/null @@ -1,7 +0,0 @@ -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. diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c deleted file mode 100644 index 521206d..0000000 --- a/drivers/staging/media/st-cec/stih-cec.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * drivers/staging/media/st-cec/stih-cec.c - * - * STIH4xx CEC driver - * Copyright (C) STMicroelectronic SA 2016 - * - * 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 - -#define CEC_NAME "stih-cec" - -/* CEC registers */ -#define CEC_CLK_DIV 0x0 -#define CEC_CTRL 0x4 -#define CEC_IRQ_CTRL 0x8 -#define CEC_STATUS 0xC -#define CEC_EXT_STATUS 0x10 -#define CEC_TX_CTRL 0x14 -#define CEC_FREE_TIME_THRESH 0x18 -#define CEC_BIT_TOUT_THRESH 0x1C -#define CEC_BIT_PULSE_THRESH 0x20 -#define CEC_DATA 0x24 -#define CEC_TX_ARRAY_CTRL 0x28 -#define CEC_CTRL2 0x2C -#define CEC_TX_ERROR_STS 0x30 -#define CEC_ADDR_TABLE 0x34 -#define CEC_DATA_ARRAY_CTRL 0x38 -#define CEC_DATA_ARRAY_STATUS 0x3C -#define CEC_TX_DATA_BASE 0x40 -#define CEC_TX_DATA_TOP 0x50 -#define CEC_TX_DATA_SIZE 0x1 -#define CEC_RX_DATA_BASE 0x54 -#define CEC_RX_DATA_TOP 0x64 -#define CEC_RX_DATA_SIZE 0x1 - -/* CEC_CTRL2 */ -#define CEC_LINE_INACTIVE_EN BIT(0) -#define CEC_AUTO_BUS_ERR_EN BIT(1) -#define CEC_STOP_ON_ARB_ERR_EN BIT(2) -#define CEC_TX_REQ_WAIT_EN BIT(3) - -/* CEC_DATA_ARRAY_CTRL */ -#define CEC_TX_ARRAY_EN BIT(0) -#define CEC_RX_ARRAY_EN BIT(1) -#define CEC_TX_ARRAY_RESET BIT(2) -#define CEC_RX_ARRAY_RESET BIT(3) -#define CEC_TX_N_OF_BYTES_IRQ_EN BIT(4) -#define CEC_TX_STOP_ON_NACK BIT(7) - -/* CEC_TX_ARRAY_CTRL */ -#define CEC_TX_N_OF_BYTES 0x1F -#define CEC_TX_START BIT(5) -#define CEC_TX_AUTO_SOM_EN BIT(6) -#define CEC_TX_AUTO_EOM_EN BIT(7) - -/* CEC_IRQ_CTRL */ -#define CEC_TX_DONE_IRQ_EN BIT(0) -#define CEC_ERROR_IRQ_EN BIT(2) -#define CEC_RX_DONE_IRQ_EN BIT(3) -#define CEC_RX_SOM_IRQ_EN BIT(4) -#define CEC_RX_EOM_IRQ_EN BIT(5) -#define CEC_FREE_TIME_IRQ_EN BIT(6) -#define CEC_PIN_STS_IRQ_EN BIT(7) - -/* CEC_CTRL */ -#define CEC_IN_FILTER_EN BIT(0) -#define CEC_PWR_SAVE_EN BIT(1) -#define CEC_EN BIT(4) -#define CEC_ACK_CTRL BIT(5) -#define CEC_RX_RESET_EN BIT(6) -#define CEC_IGNORE_RX_ERROR BIT(7) - -/* CEC_STATUS */ -#define CEC_TX_DONE_STS BIT(0) -#define CEC_TX_ACK_GET_STS BIT(1) -#define CEC_ERROR_STS BIT(2) -#define CEC_RX_DONE_STS BIT(3) -#define CEC_RX_SOM_STS BIT(4) -#define CEC_RX_EOM_STS BIT(5) -#define CEC_FREE_TIME_IRQ_STS BIT(6) -#define CEC_PIN_STS BIT(7) -#define CEC_SBIT_TOUT_STS BIT(8) -#define CEC_DBIT_TOUT_STS BIT(9) -#define CEC_LPULSE_ERROR_STS BIT(10) -#define CEC_HPULSE_ERROR_STS BIT(11) -#define CEC_TX_ERROR BIT(12) -#define CEC_TX_ARB_ERROR BIT(13) -#define CEC_RX_ERROR_MIN BIT(14) -#define CEC_RX_ERROR_MAX BIT(15) - -/* Signal free time in bit periods (2.4ms) */ -#define CEC_PRESENT_INIT_SFT 7 -#define CEC_NEW_INIT_SFT 5 -#define CEC_RETRANSMIT_SFT 3 - -/* 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_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)) - -/* Constants for CEC_BIT_PULSE_THRESH register */ -#define CEC_BIT_LPULSE_03MS BIT(1) -#define CEC_BIT_HPULSE_03MS BIT(3) - -/* Constants for CEC_DATA_ARRAY_STATUS register */ -#define CEC_RX_N_OF_BYTES 0x1F -#define CEC_TX_N_OF_BYTES_SENT BIT(5) -#define CEC_RX_OVERRUN BIT(6) - -struct stih_cec { - struct cec_adapter *adap; - struct device *dev; - struct clk *clk; - void __iomem *regs; - int irq; - u32 irq_status; -}; - -static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable) -{ - struct stih_cec *cec = cec_get_drvdata(adap); - - if (enable) { - /* The doc says (input TCLK_PERIOD * CEC_CLK_DIV) = 0.1ms */ - unsigned long clk_freq = clk_get_rate(cec->clk); - u32 cec_clk_div = clk_freq / 10000; - - writel(cec_clk_div, cec->regs + CEC_CLK_DIV); - - /* Configuration of the durations activating a timeout */ - writel(CEC_SBIT_TOUT_47MS | (CEC_DBIT_TOUT_28MS << 4), - cec->regs + CEC_BIT_TOUT_THRESH); - - /* Configuration of the smallest allowed duration for pulses */ - writel(CEC_BIT_LPULSE_03MS | CEC_BIT_HPULSE_03MS, - cec->regs + CEC_BIT_PULSE_THRESH); - - /* Minimum received bit period threshold */ - writel(BIT(5) | BIT(7), cec->regs + CEC_TX_CTRL); - - /* Configuration of transceiver data arrays */ - writel(CEC_TX_ARRAY_EN | CEC_RX_ARRAY_EN | CEC_TX_STOP_ON_NACK, - cec->regs + CEC_DATA_ARRAY_CTRL); - - /* Configuration of the control bits for CEC Transceiver */ - writel(CEC_IN_FILTER_EN | CEC_EN | CEC_RX_RESET_EN, - cec->regs + CEC_CTRL); - - /* Clear logical addresses */ - writel(0, cec->regs + CEC_ADDR_TABLE); - - /* Clear the status register */ - writel(0x0, cec->regs + CEC_STATUS); - - /* Enable the interrupts */ - writel(CEC_TX_DONE_IRQ_EN | CEC_RX_DONE_IRQ_EN | - CEC_RX_SOM_IRQ_EN | CEC_RX_EOM_IRQ_EN | - CEC_ERROR_IRQ_EN, - cec->regs + CEC_IRQ_CTRL); - - } else { - /* Clear logical addresses */ - writel(0, cec->regs + CEC_ADDR_TABLE); - - /* Clear the status register */ - writel(0x0, cec->regs + CEC_STATUS); - - /* Disable the interrupts */ - writel(0, cec->regs + CEC_IRQ_CTRL); - } - - return 0; -} - -static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr) -{ - struct stih_cec *cec = cec_get_drvdata(adap); - u32 reg = readl(cec->regs + CEC_ADDR_TABLE); - - reg |= 1 << logical_addr; - - if (logical_addr == CEC_LOG_ADDR_INVALID) - reg = 0; - - writel(reg, cec->regs + CEC_ADDR_TABLE); - - return 0; -} - -static int stih_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg) -{ - struct stih_cec *cec = cec_get_drvdata(adap); - int i; - - /* Copy message into registers */ - for (i = 0; i < msg->len; i++) - writeb(msg->msg[i], cec->regs + CEC_TX_DATA_BASE + i); - - /* Start transmission, configure hardware to add start and stop bits - * Signal free time is handled by the hardware - */ - writel(CEC_TX_AUTO_SOM_EN | CEC_TX_AUTO_EOM_EN | CEC_TX_START | - msg->len, cec->regs + CEC_TX_ARRAY_CTRL); - - return 0; -} - -static void stih_tx_done(struct stih_cec *cec, u32 status) -{ - if (status & CEC_TX_ERROR) { - cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR, 0, 0, 0, 1); - return; - } - - if (status & CEC_TX_ARB_ERROR) { - cec_transmit_done(cec->adap, - CEC_TX_STATUS_ARB_LOST, 1, 0, 0, 0); - return; - } - - if (!(status & CEC_TX_ACK_GET_STS)) { - cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK, 0, 1, 0, 0); - return; - } - - cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); -} - -static void stih_rx_done(struct stih_cec *cec, u32 status) -{ - struct cec_msg msg = {}; - u8 i; - - if (status & CEC_RX_ERROR_MIN) - return; - - if (status & CEC_RX_ERROR_MAX) - return; - - msg.len = readl(cec->regs + CEC_DATA_ARRAY_STATUS) & 0x1f; - - if (!msg.len) - return; - - if (msg.len > 16) - msg.len = 16; - - for (i = 0; i < msg.len; i++) - msg.msg[i] = readl(cec->regs + CEC_RX_DATA_BASE + i); - - cec_received_msg(cec->adap, &msg); -} - -static irqreturn_t stih_cec_irq_handler_thread(int irq, void *priv) -{ - struct stih_cec *cec = priv; - - if (cec->irq_status & CEC_TX_DONE_STS) - stih_tx_done(cec, cec->irq_status); - - if (cec->irq_status & CEC_RX_DONE_STS) - stih_rx_done(cec, cec->irq_status); - - cec->irq_status = 0; - - return IRQ_HANDLED; -} - -static irqreturn_t stih_cec_irq_handler(int irq, void *priv) -{ - struct stih_cec *cec = priv; - - cec->irq_status = readl(cec->regs + CEC_STATUS); - writel(cec->irq_status, cec->regs + CEC_STATUS); - - return IRQ_WAKE_THREAD; -} - -static const struct cec_adap_ops sti_cec_adap_ops = { - .adap_enable = stih_cec_adap_enable, - .adap_log_addr = stih_cec_adap_log_addr, - .adap_transmit = stih_cec_adap_transmit, -}; - -static int stih_cec_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct resource *res; - struct stih_cec *cec; - int ret; - - cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL); - if (!cec) - return -ENOMEM; - - cec->dev = dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cec->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(cec->regs)) - return PTR_ERR(cec->regs); - - cec->irq = platform_get_irq(pdev, 0); - if (cec->irq < 0) - return cec->irq; - - ret = devm_request_threaded_irq(dev, cec->irq, stih_cec_irq_handler, - stih_cec_irq_handler_thread, 0, - pdev->name, cec); - if (ret) - return ret; - - cec->clk = devm_clk_get(dev, "cec-clk"); - if (IS_ERR(cec->clk)) { - dev_err(dev, "Cannot get cec clock\n"); - return PTR_ERR(cec->clk); - } - - 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); - ret = PTR_ERR_OR_ZERO(cec->adap); - if (ret) - return ret; - - ret = cec_register_adapter(cec->adap, &pdev->dev); - if (ret) { - cec_delete_adapter(cec->adap); - return ret; - } - - platform_set_drvdata(pdev, cec); - return 0; -} - -static int stih_cec_remove(struct platform_device *pdev) -{ - return 0; -} - -static const struct of_device_id stih_cec_match[] = { - { - .compatible = "st,stih-cec", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, stih_cec_match); - -static struct platform_driver stih_cec_pdrv = { - .probe = stih_cec_probe, - .remove = stih_cec_remove, - .driver = { - .name = CEC_NAME, - .of_match_table = stih_cec_match, - }, -}; - -module_platform_driver(stih_cec_pdrv); - -MODULE_AUTHOR("Benjamin Gaignard "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("STIH4xx CEC driver"); -- cgit v1.1 From a93d429b51fbd5c3406bd1bc1f2bdf5f009d098b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 13 Dec 2016 12:37:16 -0200 Subject: [media] s5p-cec: add cec-notifier support, move out of staging By using the CEC notifier framework there is no longer any reason to manually set the physical address. This was the one blocking issue that prevented this driver from going out of staging, so do this move as well. Update the bindings documenting the new hdmi phandle and update exynos4.dtsi accordingly. Tested with my Odroid U3. Signed-off-by: Hans Verkuil Tested-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski CC: linux-samsung-soc@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/s5p-cec/Kconfig | 9 - drivers/staging/media/s5p-cec/Makefile | 2 - drivers/staging/media/s5p-cec/TODO | 7 - drivers/staging/media/s5p-cec/exynos_hdmi_cec.h | 37 --- .../staging/media/s5p-cec/exynos_hdmi_cecctrl.c | 208 --------------- drivers/staging/media/s5p-cec/regs-cec.h | 96 ------- drivers/staging/media/s5p-cec/s5p_cec.c | 280 --------------------- drivers/staging/media/s5p-cec/s5p_cec.h | 76 ------ 10 files changed, 718 deletions(-) delete mode 100644 drivers/staging/media/s5p-cec/Kconfig delete mode 100644 drivers/staging/media/s5p-cec/Makefile delete mode 100644 drivers/staging/media/s5p-cec/TODO delete mode 100644 drivers/staging/media/s5p-cec/exynos_hdmi_cec.h delete mode 100644 drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c delete mode 100644 drivers/staging/media/s5p-cec/regs-cec.h delete mode 100644 drivers/staging/media/s5p-cec/s5p_cec.c delete mode 100644 drivers/staging/media/s5p-cec/s5p_cec.h (limited to 'drivers/staging') diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 28088de..8ed8202 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -29,8 +29,6 @@ source "drivers/staging/media/omap4iss/Kconfig" source "drivers/staging/media/platform/bcm2835/Kconfig" -source "drivers/staging/media/s5p-cec/Kconfig" - # Keep LIRC at the end, as it has sub-menus source "drivers/staging/media/lirc/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 75e47dc..3a6adea 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/ -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_VIDEO_BCM2835) += platform/bcm2835/ diff --git a/drivers/staging/media/s5p-cec/Kconfig b/drivers/staging/media/s5p-cec/Kconfig deleted file mode 100644 index 7a3489d..0000000 --- a/drivers/staging/media/s5p-cec/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config VIDEO_SAMSUNG_S5P_CEC - tristate "Samsung S5P CEC driver" - depends on VIDEO_DEV && MEDIA_CEC_SUPPORT && (ARCH_EXYNOS || COMPILE_TEST) - ---help--- - This is a driver for Samsung S5P HDMI CEC interface. It uses the - generic CEC framework interface. - CEC bus is present in the HDMI connector and enables communication - between compatible devices. - diff --git a/drivers/staging/media/s5p-cec/Makefile b/drivers/staging/media/s5p-cec/Makefile deleted file mode 100644 index 0e2cf45..0000000 --- a/drivers/staging/media/s5p-cec/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec.o -s5p-cec-y += s5p_cec.o exynos_hdmi_cecctrl.o diff --git a/drivers/staging/media/s5p-cec/TODO b/drivers/staging/media/s5p-cec/TODO deleted file mode 100644 index 64f21ba..0000000 --- a/drivers/staging/media/s5p-cec/TODO +++ /dev/null @@ -1,7 +0,0 @@ -This driver requires that userspace sets the physical address. -However, this should be passed on from the corresponding -Samsung 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. diff --git a/drivers/staging/media/s5p-cec/exynos_hdmi_cec.h b/drivers/staging/media/s5p-cec/exynos_hdmi_cec.h deleted file mode 100644 index 7d94535..0000000 --- a/drivers/staging/media/s5p-cec/exynos_hdmi_cec.h +++ /dev/null @@ -1,37 +0,0 @@ -/* drivers/media/platform/s5p-cec/exynos_hdmi_cec.h - * - * Copyright (c) 2010, 2014 Samsung Electronics - * http://www.samsung.com/ - * - * Header file for interface of Samsung Exynos hdmi cec hardware - * - * 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. - */ - -#ifndef _EXYNOS_HDMI_CEC_H_ -#define _EXYNOS_HDMI_CEC_H_ __FILE__ - -#include -#include "s5p_cec.h" - -void s5p_cec_set_divider(struct s5p_cec_dev *cec); -void s5p_cec_enable_rx(struct s5p_cec_dev *cec); -void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec); -void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec); -void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec); -void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec); -void s5p_cec_reset(struct s5p_cec_dev *cec); -void s5p_cec_tx_reset(struct s5p_cec_dev *cec); -void s5p_cec_rx_reset(struct s5p_cec_dev *cec); -void s5p_cec_threshold(struct s5p_cec_dev *cec); -void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data, - size_t count, u8 retries); -void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr); -u32 s5p_cec_get_status(struct s5p_cec_dev *cec); -void s5p_clr_pending_tx(struct s5p_cec_dev *cec); -void s5p_clr_pending_rx(struct s5p_cec_dev *cec); -void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer); - -#endif /* _EXYNOS_HDMI_CEC_H_ */ diff --git a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c deleted file mode 100644 index 1edf667..0000000 --- a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c +++ /dev/null @@ -1,208 +0,0 @@ -/* drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c - * - * Copyright (c) 2009, 2014 Samsung Electronics - * http://www.samsung.com/ - * - * cec ftn file for Samsung TVOUT driver - * - * 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. - */ - -#include -#include - -#include "exynos_hdmi_cec.h" -#include "regs-cec.h" - -#define S5P_HDMI_FIN 24000000 -#define CEC_DIV_RATIO 320000 - -#define CEC_MESSAGE_BROADCAST_MASK 0x0F -#define CEC_MESSAGE_BROADCAST 0x0F -#define CEC_FILTER_THRESHOLD 0x15 - -void s5p_cec_set_divider(struct s5p_cec_dev *cec) -{ - u32 div_ratio, div_val; - unsigned int reg; - - div_ratio = S5P_HDMI_FIN / CEC_DIV_RATIO - 1; - - if (regmap_read(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, ®)) { - dev_err(cec->dev, "failed to read phy control\n"); - return; - } - - reg = (reg & ~(0x3FF << 16)) | (div_ratio << 16); - - if (regmap_write(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, reg)) { - dev_err(cec->dev, "failed to write phy control\n"); - return; - } - - div_val = CEC_DIV_RATIO * 0.00005 - 1; - - writeb(0x0, cec->reg + S5P_CEC_DIVISOR_3); - writeb(0x0, cec->reg + S5P_CEC_DIVISOR_2); - writeb(0x0, cec->reg + S5P_CEC_DIVISOR_1); - writeb(div_val, cec->reg + S5P_CEC_DIVISOR_0); -} - -void s5p_cec_enable_rx(struct s5p_cec_dev *cec) -{ - u8 reg; - - reg = readb(cec->reg + S5P_CEC_RX_CTRL); - reg |= S5P_CEC_RX_CTRL_ENABLE; - writeb(reg, cec->reg + S5P_CEC_RX_CTRL); -} - -void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec) -{ - u8 reg; - - reg = readb(cec->reg + S5P_CEC_IRQ_MASK); - reg |= S5P_CEC_IRQ_RX_DONE; - reg |= S5P_CEC_IRQ_RX_ERROR; - writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); -} - -void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec) -{ - u8 reg; - - reg = readb(cec->reg + S5P_CEC_IRQ_MASK); - reg &= ~S5P_CEC_IRQ_RX_DONE; - reg &= ~S5P_CEC_IRQ_RX_ERROR; - writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); -} - -void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec) -{ - u8 reg; - - reg = readb(cec->reg + S5P_CEC_IRQ_MASK); - reg |= S5P_CEC_IRQ_TX_DONE; - reg |= S5P_CEC_IRQ_TX_ERROR; - writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); -} - -void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec) -{ - u8 reg; - - reg = readb(cec->reg + S5P_CEC_IRQ_MASK); - reg &= ~S5P_CEC_IRQ_TX_DONE; - reg &= ~S5P_CEC_IRQ_TX_ERROR; - writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); -} - -void s5p_cec_reset(struct s5p_cec_dev *cec) -{ - u8 reg; - - writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL); - writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL); - - reg = readb(cec->reg + 0xc4); - reg &= ~0x1; - writeb(reg, cec->reg + 0xc4); -} - -void s5p_cec_tx_reset(struct s5p_cec_dev *cec) -{ - writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL); -} - -void s5p_cec_rx_reset(struct s5p_cec_dev *cec) -{ - u8 reg; - - writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL); - - reg = readb(cec->reg + 0xc4); - reg &= ~0x1; - writeb(reg, cec->reg + 0xc4); -} - -void s5p_cec_threshold(struct s5p_cec_dev *cec) -{ - writeb(CEC_FILTER_THRESHOLD, cec->reg + S5P_CEC_RX_FILTER_TH); - writeb(0, cec->reg + S5P_CEC_RX_FILTER_CTRL); -} - -void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data, - size_t count, u8 retries) -{ - int i = 0; - u8 reg; - - while (i < count) { - writeb(data[i], cec->reg + (S5P_CEC_TX_BUFF0 + (i * 4))); - i++; - } - - writeb(count, cec->reg + S5P_CEC_TX_BYTES); - reg = readb(cec->reg + S5P_CEC_TX_CTRL); - reg |= S5P_CEC_TX_CTRL_START; - reg &= ~0x70; - reg |= retries << 4; - - if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) { - dev_dbg(cec->dev, "Broadcast"); - reg |= S5P_CEC_TX_CTRL_BCAST; - } else { - dev_dbg(cec->dev, "No Broadcast"); - reg &= ~S5P_CEC_TX_CTRL_BCAST; - } - - writeb(reg, cec->reg + S5P_CEC_TX_CTRL); - dev_dbg(cec->dev, "cec-tx: cec count (%zu): %*ph", count, - (int)count, data); -} - -void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr) -{ - writeb(addr & 0x0F, cec->reg + S5P_CEC_LOGIC_ADDR); -} - -u32 s5p_cec_get_status(struct s5p_cec_dev *cec) -{ - u32 status = 0; - - status = readb(cec->reg + S5P_CEC_STATUS_0); - status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8; - status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16; - status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24; - - dev_dbg(cec->dev, "status = 0x%x!\n", status); - - return status; -} - -void s5p_clr_pending_tx(struct s5p_cec_dev *cec) -{ - writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR, - cec->reg + S5P_CEC_IRQ_CLEAR); -} - -void s5p_clr_pending_rx(struct s5p_cec_dev *cec) -{ - writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR, - cec->reg + S5P_CEC_IRQ_CLEAR); -} - -void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer) -{ - u32 i = 0; - char debug[40]; - - while (i < size) { - buffer[i] = readb(cec->reg + S5P_CEC_RX_BUFF0 + (i * 4)); - sprintf(debug + i * 2, "%02x ", buffer[i]); - i++; - } - dev_dbg(cec->dev, "cec-rx: cec size(%d): %s", size, debug); -} diff --git a/drivers/staging/media/s5p-cec/regs-cec.h b/drivers/staging/media/s5p-cec/regs-cec.h deleted file mode 100644 index b2e7e12..0000000 --- a/drivers/staging/media/s5p-cec/regs-cec.h +++ /dev/null @@ -1,96 +0,0 @@ -/* drivers/media/platform/s5p-cec/regs-cec.h - * - * Copyright (c) 2010 Samsung Electronics - * http://www.samsung.com/ - * - * register header file for Samsung TVOUT driver - * - * 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. - */ - -#ifndef __EXYNOS_REGS__H -#define __EXYNOS_REGS__H - -/* - * Register part - */ -#define S5P_CEC_STATUS_0 (0x0000) -#define S5P_CEC_STATUS_1 (0x0004) -#define S5P_CEC_STATUS_2 (0x0008) -#define S5P_CEC_STATUS_3 (0x000C) -#define S5P_CEC_IRQ_MASK (0x0010) -#define S5P_CEC_IRQ_CLEAR (0x0014) -#define S5P_CEC_LOGIC_ADDR (0x0020) -#define S5P_CEC_DIVISOR_0 (0x0030) -#define S5P_CEC_DIVISOR_1 (0x0034) -#define S5P_CEC_DIVISOR_2 (0x0038) -#define S5P_CEC_DIVISOR_3 (0x003C) - -#define S5P_CEC_TX_CTRL (0x0040) -#define S5P_CEC_TX_BYTES (0x0044) -#define S5P_CEC_TX_STAT0 (0x0060) -#define S5P_CEC_TX_STAT1 (0x0064) -#define S5P_CEC_TX_BUFF0 (0x0080) -#define S5P_CEC_TX_BUFF1 (0x0084) -#define S5P_CEC_TX_BUFF2 (0x0088) -#define S5P_CEC_TX_BUFF3 (0x008C) -#define S5P_CEC_TX_BUFF4 (0x0090) -#define S5P_CEC_TX_BUFF5 (0x0094) -#define S5P_CEC_TX_BUFF6 (0x0098) -#define S5P_CEC_TX_BUFF7 (0x009C) -#define S5P_CEC_TX_BUFF8 (0x00A0) -#define S5P_CEC_TX_BUFF9 (0x00A4) -#define S5P_CEC_TX_BUFF10 (0x00A8) -#define S5P_CEC_TX_BUFF11 (0x00AC) -#define S5P_CEC_TX_BUFF12 (0x00B0) -#define S5P_CEC_TX_BUFF13 (0x00B4) -#define S5P_CEC_TX_BUFF14 (0x00B8) -#define S5P_CEC_TX_BUFF15 (0x00BC) - -#define S5P_CEC_RX_CTRL (0x00C0) -#define S5P_CEC_RX_STAT0 (0x00E0) -#define S5P_CEC_RX_STAT1 (0x00E4) -#define S5P_CEC_RX_BUFF0 (0x0100) -#define S5P_CEC_RX_BUFF1 (0x0104) -#define S5P_CEC_RX_BUFF2 (0x0108) -#define S5P_CEC_RX_BUFF3 (0x010C) -#define S5P_CEC_RX_BUFF4 (0x0110) -#define S5P_CEC_RX_BUFF5 (0x0114) -#define S5P_CEC_RX_BUFF6 (0x0118) -#define S5P_CEC_RX_BUFF7 (0x011C) -#define S5P_CEC_RX_BUFF8 (0x0120) -#define S5P_CEC_RX_BUFF9 (0x0124) -#define S5P_CEC_RX_BUFF10 (0x0128) -#define S5P_CEC_RX_BUFF11 (0x012C) -#define S5P_CEC_RX_BUFF12 (0x0130) -#define S5P_CEC_RX_BUFF13 (0x0134) -#define S5P_CEC_RX_BUFF14 (0x0138) -#define S5P_CEC_RX_BUFF15 (0x013C) - -#define S5P_CEC_RX_FILTER_CTRL (0x0180) -#define S5P_CEC_RX_FILTER_TH (0x0184) - -/* - * Bit definition part - */ -#define S5P_CEC_IRQ_TX_DONE (1<<0) -#define S5P_CEC_IRQ_TX_ERROR (1<<1) -#define S5P_CEC_IRQ_RX_DONE (1<<4) -#define S5P_CEC_IRQ_RX_ERROR (1<<5) - -#define S5P_CEC_TX_CTRL_START (1<<0) -#define S5P_CEC_TX_CTRL_BCAST (1<<1) -#define S5P_CEC_TX_CTRL_RETRY (0x04<<4) -#define S5P_CEC_TX_CTRL_RESET (1<<7) - -#define S5P_CEC_RX_CTRL_ENABLE (1<<0) -#define S5P_CEC_RX_CTRL_RESET (1<<7) - -#define S5P_CEC_LOGIC_ADDR_MASK (0xF) - -/* PMU Registers for PHY */ -#define EXYNOS_HDMI_PHY_CONTROL 0x700 - -#endif /* __EXYNOS_REGS__H */ diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c deleted file mode 100644 index a30b80a..0000000 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ /dev/null @@ -1,280 +0,0 @@ -/* drivers/media/platform/s5p-cec/s5p_cec.c - * - * Samsung S5P CEC driver - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * 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 driver is based on the "cec interface driver for exynos soc" by - * SangPil Moon. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "exynos_hdmi_cec.h" -#include "regs-cec.h" -#include "s5p_cec.h" - -#define CEC_NAME "s5p-cec" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "debug level (0-2)"); - -static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) -{ - struct s5p_cec_dev *cec = cec_get_drvdata(adap); - - if (enable) { - pm_runtime_get_sync(cec->dev); - - s5p_cec_reset(cec); - - s5p_cec_set_divider(cec); - s5p_cec_threshold(cec); - - s5p_cec_unmask_tx_interrupts(cec); - s5p_cec_unmask_rx_interrupts(cec); - s5p_cec_enable_rx(cec); - } else { - s5p_cec_mask_tx_interrupts(cec); - s5p_cec_mask_rx_interrupts(cec); - pm_runtime_disable(cec->dev); - } - - return 0; -} - -static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) -{ - struct s5p_cec_dev *cec = cec_get_drvdata(adap); - - s5p_cec_set_addr(cec, addr); - return 0; -} - -static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg) -{ - struct s5p_cec_dev *cec = cec_get_drvdata(adap); - - /* - * Unclear if 0 retries are allowed by the hardware, so have 1 as - * the minimum. - */ - s5p_cec_copy_packet(cec, msg->msg, msg->len, max(1, attempts - 1)); - return 0; -} - -static irqreturn_t s5p_cec_irq_handler(int irq, void *priv) -{ - struct s5p_cec_dev *cec = priv; - u32 status = 0; - - status = s5p_cec_get_status(cec); - - dev_dbg(cec->dev, "irq received\n"); - - if (status & CEC_STATUS_TX_DONE) { - if (status & CEC_STATUS_TX_ERROR) { - dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n"); - cec->tx = STATE_ERROR; - } else { - dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n"); - cec->tx = STATE_DONE; - } - s5p_clr_pending_tx(cec); - } - - if (status & CEC_STATUS_RX_DONE) { - if (status & CEC_STATUS_RX_ERROR) { - dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n"); - s5p_cec_rx_reset(cec); - s5p_cec_enable_rx(cec); - } else { - dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n"); - if (cec->rx != STATE_IDLE) - dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); - cec->rx = STATE_BUSY; - cec->msg.len = status >> 24; - cec->msg.rx_status = CEC_RX_STATUS_OK; - s5p_cec_get_rx_buf(cec, cec->msg.len, - cec->msg.msg); - cec->rx = STATE_DONE; - s5p_cec_enable_rx(cec); - } - /* Clear interrupt pending bit */ - s5p_clr_pending_rx(cec); - } - return IRQ_WAKE_THREAD; -} - -static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv) -{ - struct s5p_cec_dev *cec = priv; - - dev_dbg(cec->dev, "irq processing thread\n"); - switch (cec->tx) { - case STATE_DONE: - cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); - cec->tx = STATE_IDLE; - break; - case STATE_ERROR: - cec_transmit_done(cec->adap, - CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR, - 0, 0, 0, 1); - cec->tx = STATE_IDLE; - break; - case STATE_BUSY: - dev_err(cec->dev, "state set to busy, this should not occur here\n"); - break; - default: - break; - } - - switch (cec->rx) { - case STATE_DONE: - cec_received_msg(cec->adap, &cec->msg); - cec->rx = STATE_IDLE; - break; - default: - break; - } - - return IRQ_HANDLED; -} - -static const struct cec_adap_ops s5p_cec_adap_ops = { - .adap_enable = s5p_cec_adap_enable, - .adap_log_addr = s5p_cec_adap_log_addr, - .adap_transmit = s5p_cec_adap_transmit, -}; - -static int s5p_cec_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct resource *res; - struct s5p_cec_dev *cec; - int ret; - - cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL); - if (!cec) - return -ENOMEM; - - cec->dev = dev; - - cec->irq = platform_get_irq(pdev, 0); - if (cec->irq < 0) - return cec->irq; - - ret = devm_request_threaded_irq(dev, cec->irq, s5p_cec_irq_handler, - s5p_cec_irq_handler_thread, 0, pdev->name, cec); - if (ret) - return ret; - - cec->clk = devm_clk_get(dev, "hdmicec"); - if (IS_ERR(cec->clk)) - return PTR_ERR(cec->clk); - - cec->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,syscon-phandle"); - if (IS_ERR(cec->pmu)) - return -EPROBE_DEFER; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cec->reg = devm_ioremap_resource(dev, res); - if (IS_ERR(cec->reg)) - return PTR_ERR(cec->reg); - - 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); - ret = PTR_ERR_OR_ZERO(cec->adap); - if (ret) - return ret; - ret = cec_register_adapter(cec->adap, &pdev->dev); - if (ret) { - cec_delete_adapter(cec->adap); - return ret; - } - - platform_set_drvdata(pdev, cec); - pm_runtime_enable(dev); - - dev_dbg(dev, "successfuly probed\n"); - return 0; -} - -static int s5p_cec_remove(struct platform_device *pdev) -{ - struct s5p_cec_dev *cec = platform_get_drvdata(pdev); - - cec_unregister_adapter(cec->adap); - pm_runtime_disable(&pdev->dev); - return 0; -} - -static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev) -{ - struct s5p_cec_dev *cec = dev_get_drvdata(dev); - - clk_disable_unprepare(cec->clk); - return 0; -} - -static int __maybe_unused s5p_cec_runtime_resume(struct device *dev) -{ - struct s5p_cec_dev *cec = dev_get_drvdata(dev); - int ret; - - ret = clk_prepare_enable(cec->clk); - if (ret < 0) - return ret; - return 0; -} - -static const struct dev_pm_ops s5p_cec_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(s5p_cec_runtime_suspend, s5p_cec_runtime_resume, - NULL) -}; - -static const struct of_device_id s5p_cec_match[] = { - { - .compatible = "samsung,s5p-cec", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, s5p_cec_match); - -static struct platform_driver s5p_cec_pdrv = { - .probe = s5p_cec_probe, - .remove = s5p_cec_remove, - .driver = { - .name = CEC_NAME, - .of_match_table = s5p_cec_match, - .pm = &s5p_cec_pm_ops, - }, -}; - -module_platform_driver(s5p_cec_pdrv); - -MODULE_AUTHOR("Kamil Debski "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Samsung S5P CEC driver"); diff --git a/drivers/staging/media/s5p-cec/s5p_cec.h b/drivers/staging/media/s5p-cec/s5p_cec.h deleted file mode 100644 index 03732c1..0000000 --- a/drivers/staging/media/s5p-cec/s5p_cec.h +++ /dev/null @@ -1,76 +0,0 @@ -/* drivers/media/platform/s5p-cec/s5p_cec.h - * - * Samsung S5P HDMI CEC driver - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _S5P_CEC_H_ -#define _S5P_CEC_H_ __FILE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "exynos_hdmi_cec.h" -#include "regs-cec.h" -#include "s5p_cec.h" - -#define CEC_NAME "s5p-cec" - -#define CEC_STATUS_TX_RUNNING (1 << 0) -#define CEC_STATUS_TX_TRANSFERRING (1 << 1) -#define CEC_STATUS_TX_DONE (1 << 2) -#define CEC_STATUS_TX_ERROR (1 << 3) -#define CEC_STATUS_TX_BYTES (0xFF << 8) -#define CEC_STATUS_RX_RUNNING (1 << 16) -#define CEC_STATUS_RX_RECEIVING (1 << 17) -#define CEC_STATUS_RX_DONE (1 << 18) -#define CEC_STATUS_RX_ERROR (1 << 19) -#define CEC_STATUS_RX_BCAST (1 << 20) -#define CEC_STATUS_RX_BYTES (0xFF << 24) - -#define CEC_WORKER_TX_DONE (1 << 0) -#define CEC_WORKER_RX_MSG (1 << 1) - -/* CEC Rx buffer size */ -#define CEC_RX_BUFF_SIZE 16 -/* CEC Tx buffer size */ -#define CEC_TX_BUFF_SIZE 16 - -enum cec_state { - STATE_IDLE, - STATE_BUSY, - STATE_DONE, - STATE_ERROR -}; - -struct s5p_cec_dev { - struct cec_adapter *adap; - struct clk *clk; - struct device *dev; - struct mutex lock; - struct regmap *pmu; - int irq; - void __iomem *reg; - - enum cec_state rx; - enum cec_state tx; - struct cec_msg msg; -}; - -#endif /* _S5P_CEC_H_ */ -- cgit v1.1 From eef04f82783d6cc712c899cff81e56c384dc06ac Mon Sep 17 00:00:00 2001 From: Nikola Jelic Date: Sat, 8 Apr 2017 12:44:41 -0300 Subject: [media] media: bcm2048: fix several macros Some of the macros didn't use the parenthesis around the parameters when used in the body of the macro. Signed-off-by: Nikola Jelic Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 375c617..38f72d0 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -177,12 +177,12 @@ #define BCM2048_FREQDEV_UNIT 10000 #define BCM2048_FREQV4L2_MULTI 625 -#define dev_to_v4l2(f) ((f * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI) -#define v4l2_to_dev(f) ((f * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT) +#define dev_to_v4l2(f) (((f) * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI) +#define v4l2_to_dev(f) (((f) * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT) -#define msb(x) ((u8)((u16)x >> 8)) -#define lsb(x) ((u8)((u16)x & 0x00FF)) -#define compose_u16(msb, lsb) (((u16)msb << 8) | lsb) +#define msb(x) ((u8)((u16)(x) >> 8)) +#define lsb(x) ((u8)((u16)(x) & 0x00FF)) +#define compose_u16(msb, lsb) (((u16)(msb) << 8) | (lsb)) #define BCM2048_DEFAULT_POWERING_DELAY 20 #define BCM2048_DEFAULT_REGION 0x02 @@ -2016,7 +2016,7 @@ static ssize_t bcm2048_##prop##_read(struct device *dev, \ if (!bdev) \ return -ENODEV; \ \ - out = kzalloc(size + 1, GFP_KERNEL); \ + out = kzalloc((size) + 1, GFP_KERNEL); \ if (!out) \ return -ENOMEM; \ \ -- cgit v1.1 From 21f9f2ef7c12dcefbdadaf96382bf547f84f23b3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 17 Feb 2017 14:17:30 -0200 Subject: [media] Staging: media/lirc: don't call put_ir_rx on rx twice There is an exit path where rx is kfree'd on put_ir_rx and then a jump to label out_put_xx will again kfree it with another call to put_ir_rx. Fix this by adding a new label that avoids this 2nd call to put_ir_rx for this specific case. Detected with CoverityScan, CID#145119 ("Use after free") Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_zilog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index e4a533b..2473552 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -1597,7 +1597,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, NULL); put_ir_rx(rx, true); ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; - goto out_put_xx; + goto out_put_tx; } /* Proceed only if the Tx client is also ready */ @@ -1637,6 +1637,7 @@ out_ok: out_put_xx: if (rx != NULL) put_ir_rx(rx, true); +out_put_tx: if (tx != NULL) put_ir_tx(tx, true); out_put_ir: -- cgit v1.1 From a1aae088e7f9dbd97164bbacc2b624d9bacd98a3 Mon Sep 17 00:00:00 2001 From: simran singhal Date: Fri, 10 Mar 2017 02:13:12 -0300 Subject: [media] staging: lirc_zilog: Clean up tests if NULL returned on failure Some functions like kmalloc/kzalloc return NULL on failure. When NULL represents failure, !x is commonly used. This was done using Coccinelle: @@ expression *e; identifier l1; @@ e = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\)(...); ... - e == NULL + !e Signed-off-by: simran singhal Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_zilog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 2473552..8ce1db0 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -1475,7 +1475,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir = get_ir_device_by_adapter(adap); if (ir == NULL) { ir = kzalloc(sizeof(struct IR), GFP_KERNEL); - if (ir == NULL) { + if (!ir) { ret = -ENOMEM; goto out_no_ir; } @@ -1515,7 +1515,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Set up a struct IR_tx instance */ tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); - if (tx == NULL) { + if (!tx) { ret = -ENOMEM; goto out_put_xx; } @@ -1559,7 +1559,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Set up a struct IR_rx instance */ rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); - if (rx == NULL) { + if (!rx) { ret = -ENOMEM; goto out_put_xx; } -- cgit v1.1 From c762efd323ca5ba9c6dbcf8975cb6f46a27a2fff Mon Sep 17 00:00:00 2001 From: Arushi Singhal Date: Wed, 22 Mar 2017 01:26:09 -0300 Subject: [media] staging: media: omap4iss: Replace a bit shift by a use of BIT This patch replaces bit shifting on 1 with the BIT(x) macro. This was done with coccinelle: @@ constant c; @@ -1 << c +BIT(c) Signed-off-by: Arushi Singhal Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipe.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index f71d5f2..f6acc54 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1268,7 +1268,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) snprintf(name, sizeof(name), "CSI2%s", subname); snprintf(sd->name, sizeof(sd->name), "OMAP4 ISS %s", name); - sd->grp_id = 1 << 16; /* group ID for iss subdevs */ + sd->grp_id = BIT(16); /* group ID for iss subdevs */ v4l2_set_subdevdata(sd, csi2); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index d38782e..d86ef8a 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -508,7 +508,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe) v4l2_subdev_init(sd, &ipipe_v4l2_ops); sd->internal_ops = &ipipe_v4l2_internal_ops; strlcpy(sd->name, "OMAP4 ISS ISP IPIPE", sizeof(sd->name)); - sd->grp_id = 1 << 16; /* group ID for iss subdevs */ + sd->grp_id = BIT(16); /* group ID for iss subdevs */ v4l2_set_subdevdata(sd, ipipe); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 23de833..cb88b2b 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -739,7 +739,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) v4l2_subdev_init(sd, &ipipeif_v4l2_ops); sd->internal_ops = &ipipeif_v4l2_internal_ops; strlcpy(sd->name, "OMAP4 ISS ISP IPIPEIF", sizeof(sd->name)); - sd->grp_id = 1 << 16; /* group ID for iss subdevs */ + sd->grp_id = BIT(16); /* group ID for iss subdevs */ v4l2_set_subdevdata(sd, ipipeif); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index f1d352c..4bbfa20 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -782,7 +782,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) v4l2_subdev_init(sd, &resizer_v4l2_ops); sd->internal_ops = &resizer_v4l2_internal_ops; strlcpy(sd->name, "OMAP4 ISS ISP resizer", sizeof(sd->name)); - sd->grp_id = 1 << 16; /* group ID for iss subdevs */ + sd->grp_id = BIT(16); /* group ID for iss subdevs */ v4l2_set_subdevdata(sd, resizer); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -- cgit v1.1