All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] SMI PCIe driver for DVBSky cards
@ 2015-03-12 23:09 Dirk Nehring
  2015-05-14 16:06 ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 3+ messages in thread
From: Dirk Nehring @ 2015-03-12 23:09 UTC (permalink / raw)
  To: linux-media; +Cc: nibble.max, Dirk Nehring

ported from the manufacturer's source tree, available from
http://dvbsky.net/download/linux/media_build-bst-150211.tar.gz

Signed-off-by: Dirk Nehring <dnehring@gmx.net>
---
 drivers/media/pci/smipcie/Kconfig                  |   1 +
 drivers/media/pci/smipcie/Makefile                 |   3 +
 drivers/media/pci/smipcie/smipcie-ir.c             | 233 +++++++++++++++++++++
 .../pci/smipcie/{smipcie.c => smipcie-main.c}      |  14 +-
 drivers/media/pci/smipcie/smipcie.h                |  19 ++
 5 files changed, 269 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/pci/smipcie/smipcie-ir.c
 rename drivers/media/pci/smipcie/{smipcie.c => smipcie-main.c} (99%)

diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig
index c8de53f..c24641e 100644
--- a/drivers/media/pci/smipcie/Kconfig
+++ b/drivers/media/pci/smipcie/Kconfig
@@ -7,6 +7,7 @@ config DVB_SMIPCIE
 	select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
+	depends on RC_CORE
 	help
 	  Support for cards with SMI PCIe bridge:
 	  - DVBSky S950 V3
diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
index be55481..013bc3f 100644
--- a/drivers/media/pci/smipcie/Makefile
+++ b/drivers/media/pci/smipcie/Makefile
@@ -1,3 +1,6 @@
+
+smipcie-objs	:= smipcie-main.o smipcie-ir.o
+
 obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
 
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c
new file mode 100644
index 0000000..2a32746
--- /dev/null
+++ b/drivers/media/pci/smipcie/smipcie-ir.c
@@ -0,0 +1,233 @@
+/*
+ * SMI PCIe driver for DVBSky cards.
+ *
+ * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "smipcie.h"
+
+static void smi_ir_enableInterrupt(struct smi_rc *ir)
+{
+	struct smi_dev *dev = ir->dev;
+
+	smi_write(MSI_INT_ENA_SET, IR_X_INT);
+}
+
+static void smi_ir_disableInterrupt(struct smi_rc *ir)
+{
+	struct smi_dev *dev = ir->dev;
+
+	smi_write(MSI_INT_ENA_CLR, IR_X_INT);
+}
+
+static void smi_ir_clearInterrupt(struct smi_rc *ir)
+{
+	struct smi_dev *dev = ir->dev;
+
+	smi_write(MSI_INT_STATUS_CLR, IR_X_INT);
+}
+
+static void smi_ir_stop(struct smi_rc *ir)
+{
+	struct smi_dev *dev = ir->dev;
+
+	smi_ir_disableInterrupt(ir);
+	smi_clear(IR_Init_Reg, 0x80);
+}
+
+#define BITS_PER_COMMAND 14
+#define GROUPS_PER_BIT	 2
+#define IR_RC5_MIN_BIT	36
+#define IR_RC5_MAX_BIT	52
+static u32 smi_decode_rc5(u8 *pData, u8 size)
+{
+	u8 index, current_bit, bit_count;
+	u8 group_array[BITS_PER_COMMAND * GROUPS_PER_BIT + 4];
+	u8 group_index = 0;
+	u32 command = 0xFFFFFFFF;
+
+	group_array[group_index++] = 1;
+
+	for (index = 0; index < size; index++) {
+
+		current_bit = (pData[index] & 0x80) ? 1 : 0;
+		bit_count = pData[index] & 0x7f;
+
+		if ((current_bit == 1) && (bit_count >= 2*IR_RC5_MAX_BIT + 1)) {
+			goto process_code;
+		} else if ((bit_count >= IR_RC5_MIN_BIT) &&
+			   (bit_count <= IR_RC5_MAX_BIT)) {
+				group_array[group_index++] = current_bit;
+		} else if ((bit_count > IR_RC5_MAX_BIT) &&
+			   (bit_count <= 2*IR_RC5_MAX_BIT)) {
+				group_array[group_index++] = current_bit;
+				group_array[group_index++] = current_bit;
+		} else {
+			goto invalid_timing;
+		}
+		if (group_index >= BITS_PER_COMMAND*GROUPS_PER_BIT)
+			goto process_code;
+
+		 if ((group_index == BITS_PER_COMMAND*GROUPS_PER_BIT - 1)
+			&& (group_array[group_index-1] == 0)) {
+			group_array[group_index++] = 1;
+			goto process_code;
+		}
+	}
+
+process_code:
+	if (group_index == (BITS_PER_COMMAND*GROUPS_PER_BIT-1))
+		group_array[group_index++] = 1;
+
+	if (group_index == BITS_PER_COMMAND*GROUPS_PER_BIT) {
+		command = 0;
+		for (index = 0; index < (BITS_PER_COMMAND*GROUPS_PER_BIT);
+		     index = index + 2) {
+			if ((group_array[index] == 1) &&
+			    (group_array[index+1] == 0)) {
+				command |= (1 << (BITS_PER_COMMAND -
+						   (index/2) - 1));
+			} else if ((group_array[index] == 0) &&
+				   (group_array[index+1] == 1)) {
+				/* */
+
+			} else {
+				command = 0xFFFFFFFF;
+				goto invalid_timing;
+			}
+		}
+	}
+
+invalid_timing:
+	return command;
+}
+
+static void smi_ir_decode(struct work_struct *work)
+{
+	struct smi_rc *ir = container_of(work, struct smi_rc, work);
+	struct smi_dev *dev = ir->dev;
+	struct rc_dev *rc_dev = ir->rc_dev;
+	u32 dwIRControl, dwIRData, dwIRCode, scancode;
+	u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle;
+
+	dwIRControl = smi_read(IR_Init_Reg);
+	if (dwIRControl & rbIRVld) {
+		ucIRCount = (u8) smi_read(IR_Data_Cnt);
+
+		if (ucIRCount < 4)
+			goto end_ir_decode;
+
+		readLoop = ucIRCount/4;
+		if (ucIRCount % 4)
+			readLoop += 1;
+		for (index = 0; index < readLoop; index++) {
+			dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4));
+
+			ir->irData[index*4 + 0] = (u8)(dwIRData);
+			ir->irData[index*4 + 1] = (u8)(dwIRData >> 8);
+			ir->irData[index*4 + 2] = (u8)(dwIRData >> 16);
+			ir->irData[index*4 + 3] = (u8)(dwIRData >> 24);
+		}
+		dwIRCode = smi_decode_rc5(ir->irData, ucIRCount);
+
+		if (dwIRCode != 0xFFFFFFFF) {
+			rc5_command = dwIRCode & 0x3F;
+			rc5_system = (dwIRCode & 0x7C0) >> 6;
+			toggle = (dwIRCode & 0x800) ? 1 : 0;
+			scancode = rc5_system << 8 | rc5_command;
+			rc_keydown(rc_dev, RC_TYPE_RC5, scancode, toggle);
+		}
+	}
+end_ir_decode:
+	smi_set(IR_Init_Reg, 0x04);
+	smi_ir_enableInterrupt(ir);
+}
+
+/* ir functions call by main driver.*/
+int smi_ir_irq(struct smi_rc *ir, u32 int_status)
+{
+	int handled = 0;
+
+	if (int_status & IR_X_INT) {
+		smi_ir_disableInterrupt(ir);
+		smi_ir_clearInterrupt(ir);
+		schedule_work(&ir->work);
+		handled = 1;
+	}
+	return handled;
+}
+
+void smi_ir_start(struct smi_rc *ir)
+{
+	struct smi_dev *dev = ir->dev;
+
+	smi_write(IR_Idle_Cnt_Low, 0x00140070);
+	msleep(20);
+	smi_set(IR_Init_Reg, 0x90);
+
+	smi_ir_enableInterrupt(ir);
+}
+
+int smi_ir_init(struct smi_dev *dev)
+{
+	int ret;
+	struct rc_dev *rc_dev;
+	struct smi_rc *ir = &dev->ir;
+
+	rc_dev = rc_allocate_device();
+	if (!rc_dev)
+		return -ENOMEM;
+
+	/* init input device */
+	snprintf(ir->input_name, sizeof(ir->input_name), "IR (%s)",
+		 dev->info->name);
+	snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0",
+		 pci_name(dev->pci_dev));
+
+	rc_dev->driver_name = "SMI_PCIe";
+	rc_dev->input_phys = ir->input_phys;
+	rc_dev->input_name = ir->input_name;
+	rc_dev->input_id.bustype = BUS_PCI;
+	rc_dev->input_id.version = 1;
+	rc_dev->input_id.vendor = dev->pci_dev->subsystem_vendor;
+	rc_dev->input_id.product = dev->pci_dev->subsystem_device;
+	rc_dev->dev.parent = &dev->pci_dev->dev;
+
+	rc_dev->driver_type = RC_DRIVER_SCANCODE;
+	rc_dev->map_name = RC_MAP_DVBSKY;
+
+	ir->rc_dev = rc_dev;
+	ir->dev = dev;
+
+	INIT_WORK(&ir->work, smi_ir_decode);
+	smi_ir_disableInterrupt(ir);
+
+	ret = rc_register_device(rc_dev);
+	if (ret)
+		goto ir_err;
+
+	return 0;
+ir_err:
+	rc_free_device(rc_dev);
+	return ret;
+}
+
+void smi_ir_exit(struct smi_dev *dev)
+{
+	struct smi_rc *ir = &dev->ir;
+	struct rc_dev *rc_dev = ir->rc_dev;
+
+	smi_ir_stop(ir);
+	rc_unregister_device(rc_dev);
+	ir->rc_dev = NULL;
+}
diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie-main.c
similarity index 99%
rename from drivers/media/pci/smipcie/smipcie.c
rename to drivers/media/pci/smipcie/smipcie-main.c
index 36c8ed7..88f3268 100644
--- a/drivers/media/pci/smipcie/smipcie.c
+++ b/drivers/media/pci/smipcie/smipcie-main.c
@@ -472,6 +472,7 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
 
 	u32 intr_status = smi_read(MSI_INT_STATUS);
 
+	struct smi_rc *ir = &dev->ir;
 	/* ts0 interrupt.*/
 	if (dev->info->ts_0)
 		handled += smi_port_irq(port0, intr_status);
@@ -484,6 +485,9 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
 }
 
 static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter,
+	/* ir interrupt.*/
+	handled += smi_ir_irq(ir, intr_status);
+
 			struct i2c_board_info *info)
 {
 	struct i2c_client *client;
@@ -994,6 +998,10 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 			goto err_del_port0_attach;
 	}
 
+	ret = smi_ir_init(dev);
+	if (ret < 0)
+		goto err_del_port1_attach;
+
 #ifdef CONFIG_PCI_MSI /* to do msi interrupt.???*/
 	if (pci_msi_enabled())
 		ret = pci_enable_msi(dev->pci_dev);
@@ -1004,10 +1012,13 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	ret = request_irq(dev->pci_dev->irq, smi_irq_handler,
 			   IRQF_SHARED, "SMI_PCIE", dev);
 	if (ret < 0)
-		goto err_del_port1_attach;
+		goto err_del_ir;
 
+	smi_ir_start(&dev->ir);
 	return 0;
 
+err_del_ir:
+	smi_ir_exit(dev);
 err_del_port1_attach:
 	if (dev->info->ts_1)
 		smi_port_detach(&dev->ts_port[1]);
@@ -1016,6 +1027,7 @@ err_del_port0_attach:
 		smi_port_detach(&dev->ts_port[0]);
 err_del_i2c_adaptor:
 	smi_i2c_exit(dev);
+	smi_ir_exit(dev);
 err_pci_iounmap:
 	iounmap(dev->lmmio);
 err_kfree:
diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
index 10cdf20..68cdda2 100644
--- a/drivers/media/pci/smipcie/smipcie.h
+++ b/drivers/media/pci/smipcie/smipcie.h
@@ -234,6 +234,17 @@ struct smi_cfg_info {
 	int fe_1;
 };
 
+struct smi_rc {
+	struct smi_dev *dev;
+	struct rc_dev *rc_dev;
+	char input_phys[64];
+	char input_name[64];
+	struct work_struct work;
+	u8 irData[256];
+
+	int users;
+};
+
 struct smi_port {
 	struct smi_dev *dev;
 	int idx;
@@ -284,6 +295,9 @@ struct smi_dev {
 	/* i2c */
 	struct i2c_adapter i2c_bus[2];
 	struct i2c_algo_bit_data i2c_bit[2];
+
+	/* ir */
+	struct smi_rc ir;
 };
 
 #define smi_read(reg)             readl(dev->lmmio + ((reg)>>2))
@@ -296,4 +310,9 @@ struct smi_dev {
 #define smi_set(reg, bit)          smi_andor((reg), (bit), (bit))
 #define smi_clear(reg, bit)        smi_andor((reg), (bit), 0)
 
+int smi_ir_irq(struct smi_rc *ir, u32 int_status);
+void smi_ir_start(struct smi_rc *ir);
+void smi_ir_exit(struct smi_dev *dev);
+int smi_ir_init(struct smi_dev *dev);
+
 #endif /* #ifndef _SMI_PCIE_H_ */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] SMI PCIe driver for DVBSky cards
  2015-03-12 23:09 [PATCH 1/1] SMI PCIe driver for DVBSky cards Dirk Nehring
@ 2015-05-14 16:06 ` Mauro Carvalho Chehab
  2015-05-15  5:04   ` Nibble Max
  0 siblings, 1 reply; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2015-05-14 16:06 UTC (permalink / raw)
  Cc: Dirk Nehring, linux-media, Max Nibble

Em Fri, 13 Mar 2015 00:09:23 +0100
Dirk Nehring <dnehring@gmx.net> escreveu:

> ported from the manufacturer's source tree, available from
> http://dvbsky.net/download/linux/media_build-bst-150211.tar.gz

The better would be if the author of the remote controller support
to send us the patch or to reply us with his SOB.

Max,

Could you please take care of it?

Thanks!
Mauro

> 
> Signed-off-by: Dirk Nehring <dnehring@gmx.net>
> ---
>  drivers/media/pci/smipcie/Kconfig                  |   1 +
>  drivers/media/pci/smipcie/Makefile                 |   3 +
>  drivers/media/pci/smipcie/smipcie-ir.c             | 233 +++++++++++++++++++++
>  .../pci/smipcie/{smipcie.c => smipcie-main.c}      |  14 +-
>  drivers/media/pci/smipcie/smipcie.h                |  19 ++
>  5 files changed, 269 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/pci/smipcie/smipcie-ir.c
>  rename drivers/media/pci/smipcie/{smipcie.c => smipcie-main.c} (99%)
> 
> diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig
> index c8de53f..c24641e 100644
> --- a/drivers/media/pci/smipcie/Kconfig
> +++ b/drivers/media/pci/smipcie/Kconfig
> @@ -7,6 +7,7 @@ config DVB_SMIPCIE
>  	select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
> +	depends on RC_CORE
>  	help
>  	  Support for cards with SMI PCIe bridge:
>  	  - DVBSky S950 V3
> diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
> index be55481..013bc3f 100644
> --- a/drivers/media/pci/smipcie/Makefile
> +++ b/drivers/media/pci/smipcie/Makefile
> @@ -1,3 +1,6 @@
> +
> +smipcie-objs	:= smipcie-main.o smipcie-ir.o
> +
>  obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
>  
>  ccflags-y += -Idrivers/media/tuners
> diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c
> new file mode 100644
> index 0000000..2a32746
> --- /dev/null
> +++ b/drivers/media/pci/smipcie/smipcie-ir.c
> @@ -0,0 +1,233 @@
> +/*
> + * SMI PCIe driver for DVBSky cards.
> + *
> + * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
> + *
> + *    This program is free software; you can redistribute it and/or modify
> + *    it under the terms of the GNU General Public License as published by
> + *    the Free Software Foundation; either version 2 of the License, or
> + *    (at your option) any later version.
> + *
> + *    This program is distributed in the hope that it will be useful,
> + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *    GNU General Public License for more details.
> + */
> +
> +#include "smipcie.h"
> +
> +static void smi_ir_enableInterrupt(struct smi_rc *ir)
> +{
> +	struct smi_dev *dev = ir->dev;
> +
> +	smi_write(MSI_INT_ENA_SET, IR_X_INT);
> +}
> +
> +static void smi_ir_disableInterrupt(struct smi_rc *ir)
> +{
> +	struct smi_dev *dev = ir->dev;
> +
> +	smi_write(MSI_INT_ENA_CLR, IR_X_INT);
> +}
> +
> +static void smi_ir_clearInterrupt(struct smi_rc *ir)
> +{
> +	struct smi_dev *dev = ir->dev;
> +
> +	smi_write(MSI_INT_STATUS_CLR, IR_X_INT);
> +}
> +
> +static void smi_ir_stop(struct smi_rc *ir)
> +{
> +	struct smi_dev *dev = ir->dev;
> +
> +	smi_ir_disableInterrupt(ir);
> +	smi_clear(IR_Init_Reg, 0x80);
> +}
> +
> +#define BITS_PER_COMMAND 14
> +#define GROUPS_PER_BIT	 2
> +#define IR_RC5_MIN_BIT	36
> +#define IR_RC5_MAX_BIT	52
> +static u32 smi_decode_rc5(u8 *pData, u8 size)
> +{
> +	u8 index, current_bit, bit_count;
> +	u8 group_array[BITS_PER_COMMAND * GROUPS_PER_BIT + 4];
> +	u8 group_index = 0;
> +	u32 command = 0xFFFFFFFF;
> +
> +	group_array[group_index++] = 1;
> +
> +	for (index = 0; index < size; index++) {
> +
> +		current_bit = (pData[index] & 0x80) ? 1 : 0;
> +		bit_count = pData[index] & 0x7f;
> +
> +		if ((current_bit == 1) && (bit_count >= 2*IR_RC5_MAX_BIT + 1)) {
> +			goto process_code;
> +		} else if ((bit_count >= IR_RC5_MIN_BIT) &&
> +			   (bit_count <= IR_RC5_MAX_BIT)) {
> +				group_array[group_index++] = current_bit;
> +		} else if ((bit_count > IR_RC5_MAX_BIT) &&
> +			   (bit_count <= 2*IR_RC5_MAX_BIT)) {
> +				group_array[group_index++] = current_bit;
> +				group_array[group_index++] = current_bit;
> +		} else {
> +			goto invalid_timing;
> +		}
> +		if (group_index >= BITS_PER_COMMAND*GROUPS_PER_BIT)
> +			goto process_code;
> +
> +		 if ((group_index == BITS_PER_COMMAND*GROUPS_PER_BIT - 1)
> +			&& (group_array[group_index-1] == 0)) {
> +			group_array[group_index++] = 1;
> +			goto process_code;
> +		}
> +	}
> +
> +process_code:
> +	if (group_index == (BITS_PER_COMMAND*GROUPS_PER_BIT-1))
> +		group_array[group_index++] = 1;
> +
> +	if (group_index == BITS_PER_COMMAND*GROUPS_PER_BIT) {
> +		command = 0;
> +		for (index = 0; index < (BITS_PER_COMMAND*GROUPS_PER_BIT);
> +		     index = index + 2) {
> +			if ((group_array[index] == 1) &&
> +			    (group_array[index+1] == 0)) {
> +				command |= (1 << (BITS_PER_COMMAND -
> +						   (index/2) - 1));
> +			} else if ((group_array[index] == 0) &&
> +				   (group_array[index+1] == 1)) {
> +				/* */
> +
> +			} else {
> +				command = 0xFFFFFFFF;
> +				goto invalid_timing;
> +			}
> +		}
> +	}
> +
> +invalid_timing:
> +	return command;
> +}
> +
> +static void smi_ir_decode(struct work_struct *work)
> +{
> +	struct smi_rc *ir = container_of(work, struct smi_rc, work);
> +	struct smi_dev *dev = ir->dev;
> +	struct rc_dev *rc_dev = ir->rc_dev;
> +	u32 dwIRControl, dwIRData, dwIRCode, scancode;
> +	u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle;
> +
> +	dwIRControl = smi_read(IR_Init_Reg);
> +	if (dwIRControl & rbIRVld) {
> +		ucIRCount = (u8) smi_read(IR_Data_Cnt);
> +
> +		if (ucIRCount < 4)
> +			goto end_ir_decode;
> +
> +		readLoop = ucIRCount/4;
> +		if (ucIRCount % 4)
> +			readLoop += 1;
> +		for (index = 0; index < readLoop; index++) {
> +			dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4));
> +
> +			ir->irData[index*4 + 0] = (u8)(dwIRData);
> +			ir->irData[index*4 + 1] = (u8)(dwIRData >> 8);
> +			ir->irData[index*4 + 2] = (u8)(dwIRData >> 16);
> +			ir->irData[index*4 + 3] = (u8)(dwIRData >> 24);
> +		}
> +		dwIRCode = smi_decode_rc5(ir->irData, ucIRCount);
> +
> +		if (dwIRCode != 0xFFFFFFFF) {
> +			rc5_command = dwIRCode & 0x3F;
> +			rc5_system = (dwIRCode & 0x7C0) >> 6;
> +			toggle = (dwIRCode & 0x800) ? 1 : 0;
> +			scancode = rc5_system << 8 | rc5_command;
> +			rc_keydown(rc_dev, RC_TYPE_RC5, scancode, toggle);
> +		}
> +	}
> +end_ir_decode:
> +	smi_set(IR_Init_Reg, 0x04);
> +	smi_ir_enableInterrupt(ir);
> +}
> +
> +/* ir functions call by main driver.*/
> +int smi_ir_irq(struct smi_rc *ir, u32 int_status)
> +{
> +	int handled = 0;
> +
> +	if (int_status & IR_X_INT) {
> +		smi_ir_disableInterrupt(ir);
> +		smi_ir_clearInterrupt(ir);
> +		schedule_work(&ir->work);
> +		handled = 1;
> +	}
> +	return handled;
> +}
> +
> +void smi_ir_start(struct smi_rc *ir)
> +{
> +	struct smi_dev *dev = ir->dev;
> +
> +	smi_write(IR_Idle_Cnt_Low, 0x00140070);
> +	msleep(20);
> +	smi_set(IR_Init_Reg, 0x90);
> +
> +	smi_ir_enableInterrupt(ir);
> +}
> +
> +int smi_ir_init(struct smi_dev *dev)
> +{
> +	int ret;
> +	struct rc_dev *rc_dev;
> +	struct smi_rc *ir = &dev->ir;
> +
> +	rc_dev = rc_allocate_device();
> +	if (!rc_dev)
> +		return -ENOMEM;
> +
> +	/* init input device */
> +	snprintf(ir->input_name, sizeof(ir->input_name), "IR (%s)",
> +		 dev->info->name);
> +	snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0",
> +		 pci_name(dev->pci_dev));
> +
> +	rc_dev->driver_name = "SMI_PCIe";
> +	rc_dev->input_phys = ir->input_phys;
> +	rc_dev->input_name = ir->input_name;
> +	rc_dev->input_id.bustype = BUS_PCI;
> +	rc_dev->input_id.version = 1;
> +	rc_dev->input_id.vendor = dev->pci_dev->subsystem_vendor;
> +	rc_dev->input_id.product = dev->pci_dev->subsystem_device;
> +	rc_dev->dev.parent = &dev->pci_dev->dev;
> +
> +	rc_dev->driver_type = RC_DRIVER_SCANCODE;
> +	rc_dev->map_name = RC_MAP_DVBSKY;
> +
> +	ir->rc_dev = rc_dev;
> +	ir->dev = dev;
> +
> +	INIT_WORK(&ir->work, smi_ir_decode);
> +	smi_ir_disableInterrupt(ir);
> +
> +	ret = rc_register_device(rc_dev);
> +	if (ret)
> +		goto ir_err;
> +
> +	return 0;
> +ir_err:
> +	rc_free_device(rc_dev);
> +	return ret;
> +}
> +
> +void smi_ir_exit(struct smi_dev *dev)
> +{
> +	struct smi_rc *ir = &dev->ir;
> +	struct rc_dev *rc_dev = ir->rc_dev;
> +
> +	smi_ir_stop(ir);
> +	rc_unregister_device(rc_dev);
> +	ir->rc_dev = NULL;
> +}
> diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie-main.c
> similarity index 99%
> rename from drivers/media/pci/smipcie/smipcie.c
> rename to drivers/media/pci/smipcie/smipcie-main.c
> index 36c8ed7..88f3268 100644
> --- a/drivers/media/pci/smipcie/smipcie.c
> +++ b/drivers/media/pci/smipcie/smipcie-main.c
> @@ -472,6 +472,7 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
>  
>  	u32 intr_status = smi_read(MSI_INT_STATUS);
>  
> +	struct smi_rc *ir = &dev->ir;
>  	/* ts0 interrupt.*/
>  	if (dev->info->ts_0)
>  		handled += smi_port_irq(port0, intr_status);
> @@ -484,6 +485,9 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
>  }
>  
>  static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter,
> +	/* ir interrupt.*/
> +	handled += smi_ir_irq(ir, intr_status);
> +
>  			struct i2c_board_info *info)
>  {
>  	struct i2c_client *client;
> @@ -994,6 +998,10 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  			goto err_del_port0_attach;
>  	}
>  
> +	ret = smi_ir_init(dev);
> +	if (ret < 0)
> +		goto err_del_port1_attach;
> +
>  #ifdef CONFIG_PCI_MSI /* to do msi interrupt.???*/
>  	if (pci_msi_enabled())
>  		ret = pci_enable_msi(dev->pci_dev);
> @@ -1004,10 +1012,13 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	ret = request_irq(dev->pci_dev->irq, smi_irq_handler,
>  			   IRQF_SHARED, "SMI_PCIE", dev);
>  	if (ret < 0)
> -		goto err_del_port1_attach;
> +		goto err_del_ir;
>  
> +	smi_ir_start(&dev->ir);
>  	return 0;
>  
> +err_del_ir:
> +	smi_ir_exit(dev);
>  err_del_port1_attach:
>  	if (dev->info->ts_1)
>  		smi_port_detach(&dev->ts_port[1]);
> @@ -1016,6 +1027,7 @@ err_del_port0_attach:
>  		smi_port_detach(&dev->ts_port[0]);
>  err_del_i2c_adaptor:
>  	smi_i2c_exit(dev);
> +	smi_ir_exit(dev);
>  err_pci_iounmap:
>  	iounmap(dev->lmmio);
>  err_kfree:
> diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
> index 10cdf20..68cdda2 100644
> --- a/drivers/media/pci/smipcie/smipcie.h
> +++ b/drivers/media/pci/smipcie/smipcie.h
> @@ -234,6 +234,17 @@ struct smi_cfg_info {
>  	int fe_1;
>  };
>  
> +struct smi_rc {
> +	struct smi_dev *dev;
> +	struct rc_dev *rc_dev;
> +	char input_phys[64];
> +	char input_name[64];
> +	struct work_struct work;
> +	u8 irData[256];
> +
> +	int users;
> +};
> +
>  struct smi_port {
>  	struct smi_dev *dev;
>  	int idx;
> @@ -284,6 +295,9 @@ struct smi_dev {
>  	/* i2c */
>  	struct i2c_adapter i2c_bus[2];
>  	struct i2c_algo_bit_data i2c_bit[2];
> +
> +	/* ir */
> +	struct smi_rc ir;
>  };
>  
>  #define smi_read(reg)             readl(dev->lmmio + ((reg)>>2))
> @@ -296,4 +310,9 @@ struct smi_dev {
>  #define smi_set(reg, bit)          smi_andor((reg), (bit), (bit))
>  #define smi_clear(reg, bit)        smi_andor((reg), (bit), 0)
>  
> +int smi_ir_irq(struct smi_rc *ir, u32 int_status);
> +void smi_ir_start(struct smi_rc *ir);
> +void smi_ir_exit(struct smi_dev *dev);
> +int smi_ir_init(struct smi_dev *dev);
> +
>  #endif /* #ifndef _SMI_PCIE_H_ */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Re: [PATCH 1/1] SMI PCIe driver for DVBSky cards
  2015-05-14 16:06 ` Mauro Carvalho Chehab
@ 2015-05-15  5:04   ` Nibble Max
  0 siblings, 0 replies; 3+ messages in thread
From: Nibble Max @ 2015-05-15  5:04 UTC (permalink / raw)
  To: Dirk Nehring; +Cc: Mauro Carvalho Chehab, linux-media

Hello,

Just find a minor issue to do "smi_ir_exit".

Best Regards,
Max

On 2015-05-15 00:06:33, Mauro Carvalho Chehab <mchehab@osg.samsung.com> wrote:
>Em Fri, 13 Mar 2015 00:09:23 +0100
>Dirk Nehring <dnehring@gmx.net> escreveu:
>
>> ported from the manufacturer's source tree, available from
>> http://dvbsky.net/download/linux/media_build-bst-150211.tar.gz
>
>The better would be if the author of the remote controller support
>to send us the patch or to reply us with his SOB.
>
>Max,
>
>Could you please take care of it?
>
>Thanks!
>Mauro
>
>> 
>> Signed-off-by: Dirk Nehring <dnehring@gmx.net>
>> ---
>>  drivers/media/pci/smipcie/Kconfig                  |   1 +
>>  drivers/media/pci/smipcie/Makefile                 |   3 +
>>  drivers/media/pci/smipcie/smipcie-ir.c             | 233 +++++++++++++++++++++
>>  .../pci/smipcie/{smipcie.c => smipcie-main.c}      |  14 +-
>>  drivers/media/pci/smipcie/smipcie.h                |  19 ++
>>  5 files changed, 269 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/media/pci/smipcie/smipcie-ir.c
>>  rename drivers/media/pci/smipcie/{smipcie.c => smipcie-main.c} (99%)
>> 
>> diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig
>> index c8de53f..c24641e 100644
>> --- a/drivers/media/pci/smipcie/Kconfig
>> +++ b/drivers/media/pci/smipcie/Kconfig
>> @@ -7,6 +7,7 @@ config DVB_SMIPCIE
>>  	select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
>>  	select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT
>>  	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
>> +	depends on RC_CORE
>>  	help
>>  	  Support for cards with SMI PCIe bridge:
>>  	  - DVBSky S950 V3
>> diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
>> index be55481..013bc3f 100644
>> --- a/drivers/media/pci/smipcie/Makefile
>> +++ b/drivers/media/pci/smipcie/Makefile
>> @@ -1,3 +1,6 @@
>> +
>> +smipcie-objs	:= smipcie-main.o smipcie-ir.o
>> +
>>  obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
>>  
>>  ccflags-y += -Idrivers/media/tuners
>> diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c
>> new file mode 100644
>> index 0000000..2a32746
>> --- /dev/null
>> +++ b/drivers/media/pci/smipcie/smipcie-ir.c
>> @@ -0,0 +1,233 @@
>> +/*
>> + * SMI PCIe driver for DVBSky cards.
>> + *
>> + * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
>> + *
>> + *    This program is free software; you can redistribute it and/or modify
>> + *    it under the terms of the GNU General Public License as published by
>> + *    the Free Software Foundation; either version 2 of the License, or
>> + *    (at your option) any later version.
>> + *
>> + *    This program is distributed in the hope that it will be useful,
>> + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *    GNU General Public License for more details.
>> + */
>> +
>> +#include "smipcie.h"
>> +
>> +static void smi_ir_enableInterrupt(struct smi_rc *ir)
>> +{
>> +	struct smi_dev *dev = ir->dev;
>> +
>> +	smi_write(MSI_INT_ENA_SET, IR_X_INT);
>> +}
>> +
>> +static void smi_ir_disableInterrupt(struct smi_rc *ir)
>> +{
>> +	struct smi_dev *dev = ir->dev;
>> +
>> +	smi_write(MSI_INT_ENA_CLR, IR_X_INT);
>> +}
>> +
>> +static void smi_ir_clearInterrupt(struct smi_rc *ir)
>> +{
>> +	struct smi_dev *dev = ir->dev;
>> +
>> +	smi_write(MSI_INT_STATUS_CLR, IR_X_INT);
>> +}
>> +
>> +static void smi_ir_stop(struct smi_rc *ir)
>> +{
>> +	struct smi_dev *dev = ir->dev;
>> +
>> +	smi_ir_disableInterrupt(ir);
>> +	smi_clear(IR_Init_Reg, 0x80);
>> +}
>> +
>> +#define BITS_PER_COMMAND 14
>> +#define GROUPS_PER_BIT	 2
>> +#define IR_RC5_MIN_BIT	36
>> +#define IR_RC5_MAX_BIT	52
>> +static u32 smi_decode_rc5(u8 *pData, u8 size)
>> +{
>> +	u8 index, current_bit, bit_count;
>> +	u8 group_array[BITS_PER_COMMAND * GROUPS_PER_BIT + 4];
>> +	u8 group_index = 0;
>> +	u32 command = 0xFFFFFFFF;
>> +
>> +	group_array[group_index++] = 1;
>> +
>> +	for (index = 0; index < size; index++) {
>> +
>> +		current_bit = (pData[index] & 0x80) ? 1 : 0;
>> +		bit_count = pData[index] & 0x7f;
>> +
>> +		if ((current_bit == 1) && (bit_count >= 2*IR_RC5_MAX_BIT + 1)) {
>> +			goto process_code;
>> +		} else if ((bit_count >= IR_RC5_MIN_BIT) &&
>> +			   (bit_count <= IR_RC5_MAX_BIT)) {
>> +				group_array[group_index++] = current_bit;
>> +		} else if ((bit_count > IR_RC5_MAX_BIT) &&
>> +			   (bit_count <= 2*IR_RC5_MAX_BIT)) {
>> +				group_array[group_index++] = current_bit;
>> +				group_array[group_index++] = current_bit;
>> +		} else {
>> +			goto invalid_timing;
>> +		}
>> +		if (group_index >= BITS_PER_COMMAND*GROUPS_PER_BIT)
>> +			goto process_code;
>> +
>> +		 if ((group_index == BITS_PER_COMMAND*GROUPS_PER_BIT - 1)
>> +			&& (group_array[group_index-1] == 0)) {
>> +			group_array[group_index++] = 1;
>> +			goto process_code;
>> +		}
>> +	}
>> +
>> +process_code:
>> +	if (group_index == (BITS_PER_COMMAND*GROUPS_PER_BIT-1))
>> +		group_array[group_index++] = 1;
>> +
>> +	if (group_index == BITS_PER_COMMAND*GROUPS_PER_BIT) {
>> +		command = 0;
>> +		for (index = 0; index < (BITS_PER_COMMAND*GROUPS_PER_BIT);
>> +		     index = index + 2) {
>> +			if ((group_array[index] == 1) &&
>> +			    (group_array[index+1] == 0)) {
>> +				command |= (1 << (BITS_PER_COMMAND -
>> +						   (index/2) - 1));
>> +			} else if ((group_array[index] == 0) &&
>> +				   (group_array[index+1] == 1)) {
>> +				/* */
>> +
>> +			} else {
>> +				command = 0xFFFFFFFF;
>> +				goto invalid_timing;
>> +			}
>> +		}
>> +	}
>> +
>> +invalid_timing:
>> +	return command;
>> +}
>> +
>> +static void smi_ir_decode(struct work_struct *work)
>> +{
>> +	struct smi_rc *ir = container_of(work, struct smi_rc, work);
>> +	struct smi_dev *dev = ir->dev;
>> +	struct rc_dev *rc_dev = ir->rc_dev;
>> +	u32 dwIRControl, dwIRData, dwIRCode, scancode;
>> +	u8 index, ucIRCount, readLoop, rc5_command, rc5_system, toggle;
>> +
>> +	dwIRControl = smi_read(IR_Init_Reg);
>> +	if (dwIRControl & rbIRVld) {
>> +		ucIRCount = (u8) smi_read(IR_Data_Cnt);
>> +
>> +		if (ucIRCount < 4)
>> +			goto end_ir_decode;
>> +
>> +		readLoop = ucIRCount/4;
>> +		if (ucIRCount % 4)
>> +			readLoop += 1;
>> +		for (index = 0; index < readLoop; index++) {
>> +			dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index*4));
>> +
>> +			ir->irData[index*4 + 0] = (u8)(dwIRData);
>> +			ir->irData[index*4 + 1] = (u8)(dwIRData >> 8);
>> +			ir->irData[index*4 + 2] = (u8)(dwIRData >> 16);
>> +			ir->irData[index*4 + 3] = (u8)(dwIRData >> 24);
>> +		}
>> +		dwIRCode = smi_decode_rc5(ir->irData, ucIRCount);
>> +
>> +		if (dwIRCode != 0xFFFFFFFF) {
>> +			rc5_command = dwIRCode & 0x3F;
>> +			rc5_system = (dwIRCode & 0x7C0) >> 6;
>> +			toggle = (dwIRCode & 0x800) ? 1 : 0;
>> +			scancode = rc5_system << 8 | rc5_command;
>> +			rc_keydown(rc_dev, RC_TYPE_RC5, scancode, toggle);
>> +		}
>> +	}
>> +end_ir_decode:
>> +	smi_set(IR_Init_Reg, 0x04);
>> +	smi_ir_enableInterrupt(ir);
>> +}
>> +
>> +/* ir functions call by main driver.*/
>> +int smi_ir_irq(struct smi_rc *ir, u32 int_status)
>> +{
>> +	int handled = 0;
>> +
>> +	if (int_status & IR_X_INT) {
>> +		smi_ir_disableInterrupt(ir);
>> +		smi_ir_clearInterrupt(ir);
>> +		schedule_work(&ir->work);
>> +		handled = 1;
>> +	}
>> +	return handled;
>> +}
>> +
>> +void smi_ir_start(struct smi_rc *ir)
>> +{
>> +	struct smi_dev *dev = ir->dev;
>> +
>> +	smi_write(IR_Idle_Cnt_Low, 0x00140070);
>> +	msleep(20);
>> +	smi_set(IR_Init_Reg, 0x90);
>> +
>> +	smi_ir_enableInterrupt(ir);
>> +}
>> +
>> +int smi_ir_init(struct smi_dev *dev)
>> +{
>> +	int ret;
>> +	struct rc_dev *rc_dev;
>> +	struct smi_rc *ir = &dev->ir;
>> +
>> +	rc_dev = rc_allocate_device();
>> +	if (!rc_dev)
>> +		return -ENOMEM;
>> +
>> +	/* init input device */
>> +	snprintf(ir->input_name, sizeof(ir->input_name), "IR (%s)",
>> +		 dev->info->name);
>> +	snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0",
>> +		 pci_name(dev->pci_dev));
>> +
>> +	rc_dev->driver_name = "SMI_PCIe";
>> +	rc_dev->input_phys = ir->input_phys;
>> +	rc_dev->input_name = ir->input_name;
>> +	rc_dev->input_id.bustype = BUS_PCI;
>> +	rc_dev->input_id.version = 1;
>> +	rc_dev->input_id.vendor = dev->pci_dev->subsystem_vendor;
>> +	rc_dev->input_id.product = dev->pci_dev->subsystem_device;
>> +	rc_dev->dev.parent = &dev->pci_dev->dev;
>> +
>> +	rc_dev->driver_type = RC_DRIVER_SCANCODE;
>> +	rc_dev->map_name = RC_MAP_DVBSKY;
>> +
>> +	ir->rc_dev = rc_dev;
>> +	ir->dev = dev;
>> +
>> +	INIT_WORK(&ir->work, smi_ir_decode);
>> +	smi_ir_disableInterrupt(ir);
>> +
>> +	ret = rc_register_device(rc_dev);
>> +	if (ret)
>> +		goto ir_err;
>> +
>> +	return 0;
>> +ir_err:
>> +	rc_free_device(rc_dev);
>> +	return ret;
>> +}
>> +
>> +void smi_ir_exit(struct smi_dev *dev)
>> +{
>> +	struct smi_rc *ir = &dev->ir;
>> +	struct rc_dev *rc_dev = ir->rc_dev;
>> +
>> +	smi_ir_stop(ir);
>> +	rc_unregister_device(rc_dev);
>> +	ir->rc_dev = NULL;
>> +}
>> diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie-main.c
>> similarity index 99%
>> rename from drivers/media/pci/smipcie/smipcie.c
>> rename to drivers/media/pci/smipcie/smipcie-main.c
>> index 36c8ed7..88f3268 100644
>> --- a/drivers/media/pci/smipcie/smipcie.c
>> +++ b/drivers/media/pci/smipcie/smipcie-main.c
>> @@ -472,6 +472,7 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
>>  
>>  	u32 intr_status = smi_read(MSI_INT_STATUS);
>>  
>> +	struct smi_rc *ir = &dev->ir;
>>  	/* ts0 interrupt.*/
>>  	if (dev->info->ts_0)
>>  		handled += smi_port_irq(port0, intr_status);
>> @@ -484,6 +485,9 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id)
>>  }
>>  
>>  static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter,
>> +	/* ir interrupt.*/
>> +	handled += smi_ir_irq(ir, intr_status);
>> +
>>  			struct i2c_board_info *info)
>>  {
>>  	struct i2c_client *client;
>> @@ -994,6 +998,10 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>  			goto err_del_port0_attach;
>>  	}
>>  
>> +	ret = smi_ir_init(dev);
>> +	if (ret < 0)
>> +		goto err_del_port1_attach;
>> +
>>  #ifdef CONFIG_PCI_MSI /* to do msi interrupt.???*/
>>  	if (pci_msi_enabled())
>>  		ret = pci_enable_msi(dev->pci_dev);
>> @@ -1004,10 +1012,13 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>  	ret = request_irq(dev->pci_dev->irq, smi_irq_handler,
>>  			   IRQF_SHARED, "SMI_PCIE", dev);
>>  	if (ret < 0)
>> -		goto err_del_port1_attach;
>> +		goto err_del_ir;
>>  
>> +	smi_ir_start(&dev->ir);
>>  	return 0;
>>  
>> +err_del_ir:
>> +	smi_ir_exit(dev);
>>  err_del_port1_attach:
>>  	if (dev->info->ts_1)
>>  		smi_port_detach(&dev->ts_port[1]);
>> @@ -1016,6 +1027,7 @@ err_del_port0_attach:
>>  		smi_port_detach(&dev->ts_port[0]);
>>  err_del_i2c_adaptor:
>>  	smi_i2c_exit(dev);
>> +	smi_ir_exit(dev);

no need to do "smi_ir_exit" again.
It should place in "static void smi_remove(struct pci_dev *pdev)" function.

>>  err_pci_iounmap:
>>  	iounmap(dev->lmmio);
>>  err_kfree:
>> diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
>> index 10cdf20..68cdda2 100644
>> --- a/drivers/media/pci/smipcie/smipcie.h
>> +++ b/drivers/media/pci/smipcie/smipcie.h
>> @@ -234,6 +234,17 @@ struct smi_cfg_info {
>>  	int fe_1;
>>  };
>>  
>> +struct smi_rc {
>> +	struct smi_dev *dev;
>> +	struct rc_dev *rc_dev;
>> +	char input_phys[64];
>> +	char input_name[64];
>> +	struct work_struct work;
>> +	u8 irData[256];
>> +
>> +	int users;
>> +};
>> +
>>  struct smi_port {
>>  	struct smi_dev *dev;
>>  	int idx;
>> @@ -284,6 +295,9 @@ struct smi_dev {
>>  	/* i2c */
>>  	struct i2c_adapter i2c_bus[2];
>>  	struct i2c_algo_bit_data i2c_bit[2];
>> +
>> +	/* ir */
>> +	struct smi_rc ir;
>>  };
>>  
>>  #define smi_read(reg)             readl(dev->lmmio + ((reg)>>2))
>> @@ -296,4 +310,9 @@ struct smi_dev {
>>  #define smi_set(reg, bit)          smi_andor((reg), (bit), (bit))
>>  #define smi_clear(reg, bit)        smi_andor((reg), (bit), 0)
>>  
>> +int smi_ir_irq(struct smi_rc *ir, u32 int_status);
>> +void smi_ir_start(struct smi_rc *ir);
>> +void smi_ir_exit(struct smi_dev *dev);
>> +int smi_ir_init(struct smi_dev *dev);
>> +
>>  #endif /* #ifndef _SMI_PCIE_H_ */


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-05-15  5:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-12 23:09 [PATCH 1/1] SMI PCIe driver for DVBSky cards Dirk Nehring
2015-05-14 16:06 ` Mauro Carvalho Chehab
2015-05-15  5:04   ` Nibble Max

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.