* [PATCH 4/7] adding sharp s921 ISDB-T driver
@ 2008-10-22 21:07 Markus Rechberger
2008-10-24 17:37 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 2+ messages in thread
From: Markus Rechberger @ 2008-10-22 21:07 UTC (permalink / raw)
To: Linux Kernel Mailing List, em28xx
Cc: acano, Andre Kelmanson, Bouwsma Barry, Dan Kreiser, Frank Neuber,
Jelle de Jong, John Stowers, Lukas Kuna, Stefan Vonolfen,
Stephan Berberig, Thomas Giesecke, Vitaly Wool, Zhenyu Wang
[-- Attachment #1: Type: text/plain, Size: 424 bytes --]
s921_module.c:
wrapper for the dvb frontend interface
s921_core.c:
core s921 1seg ISDB-T driver, everything is set to auto as much as possible
in order to not require certain parameters which currently cannot be passed
to the ISDB-T chip.
ISDB-T support can be tested using dvbscan, dvbstream/snoop and mplayer
Tested 1seg H264/aac stream with this driver using a custom linux
ISDB-T player
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: em28xx-04.diff --]
[-- Type: text/x-diff; name=em28xx-04.diff, Size: 26584 bytes --]
commit d5b043e16bae972c4fae8bec76d6ba11bcdffe74
Author: Markus Rechberger <mrechberger@sundtek.de>
Date: Wed Oct 22 22:08:23 2008 +0200
adding sharp s921 ISDB-T driver
s921_module.c:
wrapper for the dvb frontend interface
s921_core.c:
core s921 1seg ISDB-T driver, everything is set to auto as much as possible
in order to not require certain parameters which currently cannot be passed
to the ISDB-T chip.
ISDB-T support can be tested using dvbscan, dvbstream/snoop and mplayer
Tested 1seg H264/aac stream with this driver using a custom linux ISDB-T player
Signed-off-by: Markus Rechberger <mrechberger@sundtek.de>
diff --git a/drivers/media/video/empia/sharp/Makefile b/drivers/media/video/empia/sharp/Makefile
new file mode 100644
index 0000000..5105611
--- /dev/null
+++ b/drivers/media/video/empia/sharp/Makefile
@@ -0,0 +1,3 @@
+s921-objs := s921_module.o s921_core.o
+
+obj-m += s921.o
diff --git a/drivers/media/video/empia/sharp/s921_core.c b/drivers/media/video/empia/sharp/s921_core.c
new file mode 100644
index 0000000..1a72717
--- /dev/null
+++ b/drivers/media/video/empia/sharp/s921_core.c
@@ -0,0 +1,586 @@
+/*
+ * Driver for Sharp s921 driver
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "s921_core.h"
+
+static int s921_isdb_init(struct s921_isdb_t *dev);
+static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
+static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
+static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
+
+static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
+ 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
+ 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
+ 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
+ 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
+ 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
+ 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
+ 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
+ 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
+ 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
+ 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
+ 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
+ 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
+ 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
+ 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
+ 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
+ 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
+ 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
+ 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
+ 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
+ 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
+ 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
+ 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
+ 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
+ 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
+ 0xf8, 0xd7 };
+
+static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
+ 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
+ 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
+ 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
+ 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
+ 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
+ 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
+ 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
+ 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
+ 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
+ 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
+ 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
+ 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
+ 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
+ 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
+ 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
+ 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
+
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
+ switch(cmd) {
+ case ISDB_T_CMD_INIT:
+ s921_isdb_init(dev);
+ break;
+ case ISDB_T_CMD_SET_PARAM:
+ s921_isdb_set_parameters(dev, data);
+ break;
+ case ISDB_T_CMD_TUNE:
+ s921_isdb_tune(dev, data);
+ break;
+ case ISDB_T_CMD_GET_STATUS:
+ s921_isdb_get_status(dev, data);
+ break;
+ default:
+ printk("unhandled command\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int s921_isdb_init(struct s921_isdb_t *dev) {
+ unsigned int i;
+ unsigned int ret;
+ printk("isdb_init\n");
+ for (i = 0; i < sizeof(init_table); i+=2) {
+ ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
+ if (ret != 0) {
+ printk("i2c write failed\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
+
+ int ret;
+ /* auto is sufficient for now, lateron this should be reflected in an extra interface */
+
+#if 0
+ u8 mod_b2 = 0;
+ u8 mod_b3 = 0;
+ u8 mod_b4 = 0;
+ u8 mod_b5 = 0;
+ u8 mod_b6 = 0;
+ u8 mod_b7 = 0;
+ u8 mod_b8 = 0;
+ /* LAYER A Setup */
+
+ switch (params->layer_a_carrier_modulation) {
+ case ISDB_T_LA_CM_DQPSK:
+ mod_b3 |= 0<<5;
+ break;
+ case ISDB_T_LA_CM_QPSK:
+ mod_b3 |= 1<<5;
+ break;
+ case ISDB_T_LA_CM_16QAM:
+ mod_b3 |= 2<<5;
+ break;
+ case ISDB_T_LA_CM_64QAM:
+ mod_b3 |= 3<<5;
+ break;
+ case ISDB_T_LA_CM_NOLAYER:
+ mod_b3 |= 7<<5;
+ break;
+ default:
+ printk("invalid carrier modulation\n");
+ return -EINVAL;
+ }
+
+ switch(params->layer_a_code_rate) {
+ case ISDB_T_LA_CR_1_2:
+ mod_b3 |= 0<<2;
+ break;
+ case ISDB_T_LA_CR_2_3:
+ mod_b3 |= 1<<2;
+ break;
+ case ISDB_T_LA_CR_3_4:
+ mod_b3 |= 2<<2;
+ break;
+ case ISDB_T_LA_CR_5_6:
+ mod_b3 |= 3<<2;
+ break;
+ case ISDB_T_LA_CR_7_8:
+ mod_b3 |= 4<<2;
+ break;
+ default:
+ printk("invalid coderate\n");
+ return -EINVAL;
+ }
+
+ switch (params->layer_a_mode) {
+ case ISDB_T_LA_MODE_1:
+ switch(params->layer_a_time_interleave) {
+ case ISDB_T_LA_TI_0:
+ mod_b3 |= 0;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_4:
+ mod_b3 |= 1;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_8:
+ mod_b3 |= 2;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_16:
+ mod_b3 |= 3;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_32:
+ mod_b3 |= 0;
+ mod_b4 |= 1<<7;
+ break;
+ default:
+ printk("invalid layer a time interleave\n");
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LA_MODE_2:
+ switch(params->layer_a_time_interleave) {
+ case ISDB_T_LA_TI_0:
+ mod_b3 |= 0;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_2:
+ mod_b3 |= 1;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_4:
+ mod_b3 |= 2;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_8:
+ mod_b3 |= 3;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_16:
+ mod_b3 |= 0;
+ mod_b4 |= 1<<7;
+ break;
+ default:
+
+ printk("invalid layer a time interleave\n");
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LA_MODE_3:
+ switch(params->layer_a_time_interleave) {
+ case ISDB_T_LA_TI_0:
+ mod_b3 |= 0;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_1:
+ mod_b3 |= 1;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_2:
+ mod_b3 |= 2;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_4:
+ mod_b3 |= 3;
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LA_TI_8:
+ mod_b3 |= 0;
+ mod_b4 |= 1<<7;
+ break;
+ default:
+ printk("invalid layer a time interleave\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk("invalid layer mode\n");
+ return -EINVAL;
+ }
+
+
+ /* LAYER B Setup */
+ switch (params->layer_b_carrier_modulation) {
+ case ISDB_T_LB_CM_DQPSK:
+ mod_b4 |= 0;
+ break;
+ case ISDB_T_LB_CM_QPSK:
+ mod_b4 |= 1;
+ break;
+ case ISDB_T_LB_CM_16QAM:
+ mod_b4 |= 2;
+ break;
+ case ISDB_T_LB_CM_64QAM:
+ mod_b4 |= 3;
+ break;
+ case ISDB_T_LB_CM_NOLAYER:
+ mod_b4 |= 7;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch(params->layer_b_code_rate) {
+ case ISDB_T_LB_CR_1_2:
+ mod_b5 |= 0<<5;
+ break;
+ case ISDB_T_LB_CR_2_3:
+ mod_b5 |= 1<<5;
+ break;
+ case ISDB_T_LB_CR_3_4:
+ mod_b5 |= 2<<5;
+ break;
+ case ISDB_T_LB_CR_5_6:
+ mod_b5 |= 3<<5;
+ break;
+ case ISDB_T_LB_CR_7_8:
+ mod_b5 |= 4<<5;
+ break;
+ case ISDB_T_LB_CR_NOLAYER:
+ mod_b5 |= 7<<5;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (params->layer_b_mode) {
+ case ISDB_T_LB_MODE_1:
+ switch(params->layer_b_time_interleave) {
+ case ISDB_T_LB_TI_0:
+ mod_b5 |= 0;
+ break;
+ case ISDB_T_LB_TI_4:
+ mod_b5 |= 1<<2;
+ break;
+ case ISDB_T_LB_TI_8:
+ mod_b5 |= 2<<2;
+ break;
+ case ISDB_T_LB_TI_16:
+ mod_b5 |= 3<<2;
+ break;
+ case ISDB_T_LB_TI_32:
+ mod_b5 |= 4<<2;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LB_MODE_2:
+ switch(params->layer_b_time_interleave) {
+ case ISDB_T_LB_TI_0:
+ mod_b5 |= 0;
+ break;
+ case ISDB_T_LB_TI_2:
+ mod_b5 |= 1<<2;
+ break;
+ case ISDB_T_LB_TI_4:
+ mod_b5 |= 2<<2;
+ break;
+ case ISDB_T_LB_TI_8:
+ mod_b5 |= 3<<2;
+ break;
+ case ISDB_T_LB_TI_16:
+ mod_b5 |= 4<<2;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LB_MODE_3:
+ switch(params->layer_b_time_interleave) {
+ case ISDB_T_LB_TI_0:
+ mod_b5 |= 0;
+ break;
+ case ISDB_T_LB_TI_1:
+ mod_b5 |= 1<<2;
+ break;
+ case ISDB_T_LB_TI_2:
+ mod_b5 |= 2<<2;
+ break;
+ case ISDB_T_LB_TI_4:
+ mod_b5 |= 3<<2;
+ break;
+ case ISDB_T_LB_TI_8:
+ mod_b5 |= 4<<2;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* LAYER C Setup */
+ switch (params->layer_c_carrier_modulation) {
+ case ISDB_T_LC_CM_DQPSK:
+ mod_b5 |= 0<<3;
+ break;
+ case ISDB_T_LC_CM_QPSK:
+ mod_b5 |= 1<<3;
+ break;
+ case ISDB_T_LC_CM_16QAM:
+ mod_b5 |= 2<<3;
+ break;
+ case ISDB_T_LC_CM_64QAM:
+ mod_b5 |= 3<<3;
+ break;
+ case ISDB_T_LC_CM_NOLAYER:
+ mod_b5 |= 7<<3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch(params->layer_c_code_rate) {
+ case ISDB_T_LC_CR_1_2:
+ mod_b5 |= 0<<0;
+ break;
+ case ISDB_T_LC_CR_2_3:
+ mod_b5 |= 1<<0;
+ break;
+ case ISDB_T_LC_CR_3_4:
+ mod_b5 |= 2<<0;
+ break;
+ case ISDB_T_LC_CR_5_6:
+ mod_b5 |= 3<<0;
+ break;
+ case ISDB_T_LC_CR_7_8:
+ mod_b5 |= 4<<0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (params->layer_c_mode) {
+ case ISDB_T_LC_MODE_1:
+ switch(params->layer_c_time_interleave) {
+ case ISDB_T_LC_TI_0:
+ mod_b7 |= 0<<5;
+ break;
+ case ISDB_T_LC_TI_4:
+ mod_b7 |= 1<<5;
+ break;
+ case ISDB_T_LC_TI_8:
+ mod_b7 |= 2<<5;
+ break;
+ case ISDB_T_LC_TI_16:
+ mod_b7 |= 3<<5;
+ break;
+ case ISDB_T_LC_TI_32:
+ mod_b7 |= 4<<5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LC_MODE_2:
+ switch(params->layer_c_time_interleave) {
+ case ISDB_T_LC_TI_0:
+ mod_b7 |= 0<<5;
+ break;
+ case ISDB_T_LC_TI_2:
+ mod_b7 |= 1<<5;
+ break;
+ case ISDB_T_LC_TI_4:
+ mod_b7 |= 2<<5;
+ break;
+ case ISDB_T_LC_TI_8:
+ mod_b7 |= 3<<5;
+ break;
+ case ISDB_T_LC_TI_16:
+ mod_b7 |= 4<<5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case ISDB_T_LC_MODE_3:
+ switch(params->layer_c_time_interleave) {
+ case ISDB_T_LC_TI_0:
+ mod_b7 |= 0<<5;
+ break;
+ case ISDB_T_LC_TI_1:
+ mod_b7 |= 1<<5;
+ break;
+ case ISDB_T_LC_TI_2:
+ mod_b7 |= 2<<5;
+ break;
+ case ISDB_T_LC_TI_4:
+ mod_b7 |= 3<<5;
+ break;
+ case ISDB_T_LC_TI_8:
+ mod_b7 |= 4<<5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+#endif
+
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
+ ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
+
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
+ if (ret < 0)
+ return -EINVAL;
+
+ return E_OK;
+}
+
+static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
+
+ int ret;
+ int index;
+
+ index = (params->frequency - 473143000)/6000000;
+
+ if (index > 48) {
+ return -EINVAL;
+ }
+
+ dev->i2c_write(dev->priv_dev, 0x47, 0x60);
+
+ ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
+ if (ret < 0)
+ return -EINVAL;
+
+ dev->i2c_write(dev->priv_dev, 0x01, 0x40);
+ return 0;
+}
+
+static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
+ unsigned int *ret = (unsigned int*)data;
+ u8 ifagc_dt;
+ u8 rfagc_dt;
+
+ mdelay(10);
+ ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
+ rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
+#if 0
+ *ret = dev->i2c_read(dev->priv_dev, 0x82);
+ printk("status 83: %02x\n", *ret);
+ *ret = dev->i2c_read(dev->priv_dev, 0x80);
+ mdelay(10);
+ *ret = dev->i2c_read(dev->priv_dev, 0x80);
+ mdelay(10);
+ *ret = dev->i2c_read(dev->priv_dev, 0x80);
+#endif
+ if (rfagc_dt == 0x40) {
+ *ret = 1;
+ }
+ return 0;
+}
diff --git a/drivers/media/video/empia/sharp/s921_core.h b/drivers/media/video/empia/sharp/s921_core.h
new file mode 100644
index 0000000..ae39a2a
--- /dev/null
+++ b/drivers/media/video/empia/sharp/s921_core.h
@@ -0,0 +1,114 @@
+#ifndef _S921_CORE_H
+#define _S921_CORE_H
+//#define u8 unsigned int
+//#define u32 unsigned int
+
+
+
+//#define EINVAL -1
+#define E_OK 0
+
+struct s921_isdb_t {
+ void *priv_dev;
+ int (*i2c_write)(void *dev, u8 reg, u8 val);
+ int (*i2c_read)(void *dev, u8 reg);
+};
+
+#define ISDB_T_CMD_INIT 0
+#define ISDB_T_CMD_SET_PARAM 1
+#define ISDB_T_CMD_TUNE 2
+#define ISDB_T_CMD_GET_STATUS 3
+
+struct s921_isdb_t_tune_params {
+ u32 frequency;
+};
+
+struct s921_isdb_t_status {
+};
+
+struct s921_isdb_t_transmission_mode_params {
+ u8 mode;
+ u8 layer_a_mode;
+#define ISDB_T_LA_MODE_1 0
+#define ISDB_T_LA_MODE_2 1
+#define ISDB_T_LA_MODE_3 2
+ u8 layer_a_carrier_modulation;
+#define ISDB_T_LA_CM_DQPSK 0
+#define ISDB_T_LA_CM_QPSK 1
+#define ISDB_T_LA_CM_16QAM 2
+#define ISDB_T_LA_CM_64QAM 3
+#define ISDB_T_LA_CM_NOLAYER 4
+ u8 layer_a_code_rate;
+#define ISDB_T_LA_CR_1_2 0
+#define ISDB_T_LA_CR_2_3 1
+#define ISDB_T_LA_CR_3_4 2
+#define ISDB_T_LA_CR_5_6 4
+#define ISDB_T_LA_CR_7_8 8
+#define ISDB_T_LA_CR_NOLAYER 16
+ u8 layer_a_time_interleave;
+#define ISDB_T_LA_TI_0 0
+#define ISDB_T_LA_TI_1 1
+#define ISDB_T_LA_TI_2 2
+#define ISDB_T_LA_TI_4 4
+#define ISDB_T_LA_TI_8 8
+#define ISDB_T_LA_TI_16 16
+#define ISDB_T_LA_TI_32 32
+ u8 layer_a_nseg;
+
+ u8 layer_b_mode;
+#define ISDB_T_LB_MODE_1 0
+#define ISDB_T_LB_MODE_2 1
+#define ISDB_T_LB_MODE_3 2
+ u8 layer_b_carrier_modulation;
+#define ISDB_T_LB_CM_DQPSK 0
+#define ISDB_T_LB_CM_QPSK 1
+#define ISDB_T_LB_CM_16QAM 2
+#define ISDB_T_LB_CM_64QAM 3
+#define ISDB_T_LB_CM_NOLAYER 4
+ u8 layer_b_code_rate;
+#define ISDB_T_LB_CR_1_2 0
+#define ISDB_T_LB_CR_2_3 1
+#define ISDB_T_LB_CR_3_4 2
+#define ISDB_T_LB_CR_5_6 4
+#define ISDB_T_LB_CR_7_8 8
+#define ISDB_T_LB_CR_NOLAYER 16
+ u8 layer_b_time_interleave;
+#define ISDB_T_LB_TI_0 0
+#define ISDB_T_LB_TI_1 1
+#define ISDB_T_LB_TI_2 2
+#define ISDB_T_LB_TI_4 4
+#define ISDB_T_LB_TI_8 8
+#define ISDB_T_LB_TI_16 16
+#define ISDB_T_LB_TI_32 32
+ u8 layer_b_nseg;
+
+ u8 layer_c_mode;
+#define ISDB_T_LC_MODE_1 0
+#define ISDB_T_LC_MODE_2 1
+#define ISDB_T_LC_MODE_3 2
+ u8 layer_c_carrier_modulation;
+#define ISDB_T_LC_CM_DQPSK 0
+#define ISDB_T_LC_CM_QPSK 1
+#define ISDB_T_LC_CM_16QAM 2
+#define ISDB_T_LC_CM_64QAM 3
+#define ISDB_T_LC_CM_NOLAYER 4
+ u8 layer_c_code_rate;
+#define ISDB_T_LC_CR_1_2 0
+#define ISDB_T_LC_CR_2_3 1
+#define ISDB_T_LC_CR_3_4 2
+#define ISDB_T_LC_CR_5_6 4
+#define ISDB_T_LC_CR_7_8 8
+#define ISDB_T_LC_CR_NOLAYER 16
+ u8 layer_c_time_interleave;
+#define ISDB_T_LC_TI_0 0
+#define ISDB_T_LC_TI_1 1
+#define ISDB_T_LC_TI_2 2
+#define ISDB_T_LC_TI_4 4
+#define ISDB_T_LC_TI_8 8
+#define ISDB_T_LC_TI_16 16
+#define ISDB_T_LC_TI_32 32
+ u8 layer_c_nseg;
+};
+
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
+#endif
diff --git a/drivers/media/video/empia/sharp/s921_module.c b/drivers/media/video/empia/sharp/s921_module.c
new file mode 100644
index 0000000..d78ebaf
--- /dev/null
+++ b/drivers/media/video/empia/sharp/s921_module.c
@@ -0,0 +1,254 @@
+/*
+ * Driver for Sharp s921 driver
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ * All rights reserved.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s921_module.h"
+#include "s921_core.h"
+
+static unsigned int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"s921 debugging (default off)");
+
+#define dprintk(fmt, args...) if (debug) do {\
+ printk("s921 debug: " fmt, ##args); } while (0)
+
+struct s921_state
+{
+ struct dvb_frontend frontend;
+ fe_modulation_t current_modulation;
+ __u32 snr;
+ __u32 current_frequency;
+ __u8 addr;
+ struct s921_isdb_t dev;
+ struct i2c_adapter *i2c;
+};
+
+static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ struct s921_isdb_t_transmission_mode_params params;
+ struct s921_isdb_t_tune_params tune_params;
+
+ tune_params.frequency = param->frequency;
+#if 0
+ struct dvb_ofdm_parameters *op = ¶m->u.ofdm;
+
+ switch (op->bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ case BANDWIDTH_7_MHZ:
+ case BANDWIDTH_8_MHZ:
+ default:
+ break;
+ }
+
+ switch (op->code_rate_HP) {
+ case FEC_2_3:
+ case FEC_3_4:
+ case FEC_5_6:
+ case FEC_7_8:
+ case FEC_1_2:
+ case FEC_AUTO:
+ break;
+ default:
+ break;
+ }
+
+ switch(op->code_rate_LP) {
+ case FEC_2_3:
+ case FEC_3_4:
+ case FEC_5_6:
+ case FEC_7_8:
+ case FEC_1_2:
+ case FEC_AUTO:
+ case FEC_NONE:
+ default:
+ break;
+ }
+
+ switch (op->constellation) {
+ case QPSK:
+ case QAM_AUTO:
+ case QAM_16:
+ default:
+ break;
+ }
+
+ switch (op->guard_interval) {
+ case GUARD_INTERVAL_1_32:
+ case GUARD_INTERVAL_AUTO:
+ case GUARD_INTERVAL_1_16:
+ case GUARD_INTERVAL_1_8:
+ case GUARD_INTERVAL_1_4:
+ default:
+ break;
+ }
+
+ switch (op->hierarchy_information) {
+ case HIERARCHY_AUTO:
+ case HIERARCHY_NONE:
+ case HIERARCHY_1:
+ case HIERARCHY_2:
+ case HIERARCHY_4:
+ default:
+ break;
+ }
+
+#endif
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms);
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
+ mdelay(100);
+ return 0;
+}
+
+static int s921_init(struct dvb_frontend *fe) {
+ printk("s921 init\n");
+ return 0;
+}
+
+static int s921_sleep(struct dvb_frontend *fe) {
+ printk("s921 sleep\n");
+ return 0;
+}
+
+static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ unsigned int ret;
+ mdelay(5);
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
+ *status = 0;
+
+ printk("status: %02x\n", ret);
+ if (ret == 1) {
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_SIGNAL;
+ }
+
+ return 0;
+}
+
+static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
+{
+ dprintk("read ber\n");
+ return 0;
+}
+
+static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
+{
+ dprintk("read snr\n");
+ return 0;
+}
+
+static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
+{
+ dprintk("read ucblocks\n");
+ return 0;
+}
+
+static void s921_release(struct dvb_frontend *fe)
+{
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops demod_s921={
+ .info = {
+ .name = "SHARP S921",
+ .type = FE_OFDM,
+ .frequency_min = 473143000,
+ .frequency_max = 767143000,
+ .frequency_stepsize = 6000000,
+ .frequency_tolerance = 0,
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+ FE_CAN_MUTE_TS
+ },
+ .init = s921_init,
+ .sleep = s921_sleep,
+ .set_frontend = s921_set_parameters,
+ .read_snr = s921_read_snr,
+ .read_ber = s921_read_ber,
+ .read_status = s921_read_status,
+ .read_ucblocks = s921_read_ucblocks,
+ .release = s921_release,
+};
+
+static int s921_write(void *dev, u8 reg, u8 val) {
+ struct s921_state *state = dev;
+ char buf[2]={reg,val};
+ int err;
+ struct i2c_msg i2cmsgs = {
+ .addr = state->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buf
+ };
+
+ if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
+ printk("%s i2c_transfer error %d\n", __FUNCTION__, err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int s921_read(void *dev, u8 reg) {
+ struct s921_state *state = dev;
+ u8 b1;
+ int ret;
+ struct i2c_msg msg[2] = { { .addr = state->addr,
+ .flags = 0,
+ .buf = ®, .len = 1 },
+ { .addr = state->addr,
+ .flags = I2C_M_RD,
+ .buf = &b1, .len = 1 } };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2)
+ return ret;
+ return b1;
+}
+
+struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+
+ struct s921_state *state;
+ state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+ memset(state, 0x0, sizeof(struct s921_state));
+
+ state->addr = config->i2c_address;
+ state->i2c = i2c;
+ state->dev.i2c_write = &s921_write;
+ state->dev.i2c_read = &s921_read;
+ state->dev.priv_dev = state;
+
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
+
+ memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+}
+
+EXPORT_SYMBOL_GPL(s921_attach);
+MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
+MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/empia/sharp/s921_module.h b/drivers/media/video/empia/sharp/s921_module.h
new file mode 100644
index 0000000..7866042
--- /dev/null
+++ b/drivers/media/video/empia/sharp/s921_module.h
@@ -0,0 +1,49 @@
+/*
+ * Driver for DVB-T s921 demodulator
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef S921_MODULE_H
+#define S921_MODULE_H
+
+#include <linux/dvb/frontend.h>
+#include "s921_core.h"
+
+int s921_isdb_init(struct s921_isdb_t *dev);
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
+
+struct s921_config
+{
+ /* demodulator's I2C address */
+ u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
+extern struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_S921 */
+
+#endif /* S921_H */
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH 4/7] adding sharp s921 ISDB-T driver
2008-10-22 21:07 [PATCH 4/7] adding sharp s921 ISDB-T driver Markus Rechberger
@ 2008-10-24 17:37 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 2+ messages in thread
From: Mauro Carvalho Chehab @ 2008-10-24 17:37 UTC (permalink / raw)
To: Markus Rechberger
Cc: Linux Kernel Mailing List, em28xx, acano, Andre Kelmanson,
Bouwsma Barry, Dan Kreiser, Frank Neuber, Jelle de Jong,
John Stowers, Lukas Kuna, Stefan Vonolfen, Stephan Berberig,
Thomas Giesecke, Vitaly Wool, Zhenyu Wang
On Wed, 22 Oct 2008 23:07:42 +0200
"Markus Rechberger" <mrechberger@gmail.com> wrote:
> s921_module.c:
> wrapper for the dvb frontend interface
> s921_core.c:
> core s921 1seg ISDB-T driver, everything is set to auto as much as possible
> in order to not require certain parameters which currently cannot be passed
> to the ISDB-T chip.
>
> ISDB-T support can be tested using dvbscan, dvbstream/snoop and mplayer
> Tested 1seg H264/aac stream with this driver using a custom linux
> ISDB-T player
ACK.
Applied at the development tree.
Cheers,
Mauro
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-10-24 17:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-22 21:07 [PATCH 4/7] adding sharp s921 ISDB-T driver Markus Rechberger
2008-10-24 17:37 ` Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®