1
0
Fork 0

Merge branch 'patchwork' into v4l_for_linus

* patchwork: (544 commits)
  [media] ir-hix5hd2: fix build on c6x arch
  [media] pt3: fix DTV FE I2C driver load error paths
  Revert "[media] media: em28xx - remove reset_resume interface"
  [media] exynos4-is: fix some warnings when compiling on arm64
  [media] usb drivers: use %zu instead of %zd
  [media] pci drivers: use %zu instead of %zd
  [media] dvb-frontends: use %zu instead of %zd
  [media] s5p-mfc: Fix several printk warnings
  [media] s5p_mfc_opr: Fix warnings
  [media] ti-vpe: Fix typecast
  [media] s3c-camif: fix dma_addr_t printks
  [media] s5p_mfc_opr_v6: get rid of warnings when compiled with 64 bits
  [media] s5p_mfc_opr_v5: Fix lots of warnings on x86_64
  [media] em28xx: Fix identation
  [media] drxd: remove a dead code
  [media] saa7146: remove return after BUG()
  [media] cx88: remove return after BUG()
  [media] cx88: fix cards table CodingStyle
  [media] radio-sf16fmr2: declare some structs as static
  [media] radio-sf16fmi: declare pnp_attached as static
  ...

Conflicts:
	Documentation/DocBook/media/v4l/compat.xml
wifi-calibration
Mauro Carvalho Chehab 2014-10-09 14:00:54 -03:00
commit a66d05d504
475 changed files with 36228 additions and 13065 deletions

View File

@ -2566,6 +2566,12 @@ fields changed from _s32 to _u32.
<para>Added compound control types and &VIDIOC-QUERY-EXT-CTRL;.
</para>
</listitem>
<title>V4L2 in Linux 3.18</title>
<orderedlist>
<listitem>
<para>Added <constant>V4L2_CID_PAN_SPEED</constant> and
<constant>V4L2_CID_TILT_SPEED</constant> camera controls.</para>
</listitem>
</orderedlist>
</section>

View File

@ -3965,6 +3965,27 @@ by exposure, white balance or focus controls.</entry>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_PAN_SPEED</constant>&nbsp;</entry>
<entry>integer</entry>
</row><row><entry spanname="descr">This control turns the
camera horizontally at the specific speed. The unit is undefined. A
positive value moves the camera to the right (clockwise when viewed
from above), a negative value to the left. A value of zero stops the motion
if one is in progress and has no effect otherwise.</entry>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_TILT_SPEED</constant>&nbsp;</entry>
<entry>integer</entry>
</row><row><entry spanname="descr">This control turns the
camera vertically at the specified speed. The unit is undefined. A
positive value moves the camera up, a negative value down. A value of zero
stops the motion if one is in progress and has no effect otherwise.</entry>
</row>
<row><entry></entry></row>
</tbody>
</tgroup>
</table>
@ -4790,6 +4811,40 @@ interface and may change in the future.</para>
conversion.
</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_RED</constant></entry>
<entry>integer</entry>
</row>
<row>
<entry spanname="descr">Test pattern red colour component.
</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_GREENR</constant></entry>
<entry>integer</entry>
</row>
<row>
<entry spanname="descr">Test pattern green (next to red)
colour component.
</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_BLUE</constant></entry>
<entry>integer</entry>
</row>
<row>
<entry spanname="descr">Test pattern blue colour component.
</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_GREENB</constant></entry>
<entry>integer</entry>
</row>
<row>
<entry spanname="descr">Test pattern green (next to blue)
colour component.
</entry>
</row>
<row><entry></entry></row>
</tbody>
</tgroup>

View File

@ -237,9 +237,9 @@ for a pixel lie next to each other in memory.</para>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB555X">
<entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
<entry>'RGBQ'</entry>
<row id="V4L2-PIX-FMT-ARGB555X">
<entry><constant>V4L2_PIX_FMT_ARGB555X</constant></entry>
<entry>'AR15' | (1 &lt;&lt; 31)</entry>
<entry></entry>
<entry>a</entry>
<entry>r<subscript>4</subscript></entry>
@ -259,6 +259,28 @@ for a pixel lie next to each other in memory.</para>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-XRGB555X">
<entry><constant>V4L2_PIX_FMT_XRGB555X</constant></entry>
<entry>'XR15' | (1 &lt;&lt; 31)</entry>
<entry></entry>
<entry>-</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB565X">
<entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
<entry>'RGBR'</entry>
@ -464,7 +486,7 @@ for a pixel lie next to each other in memory.</para>
</row>
<row id="V4L2-PIX-FMT-ARGB32">
<entry><constant>V4L2_PIX_FMT_ARGB32</constant></entry>
<entry>'AX24'</entry>
<entry>'BA24'</entry>
<entry></entry>
<entry>a<subscript>7</subscript></entry>
<entry>a<subscript>6</subscript></entry>
@ -800,6 +822,28 @@ image</title>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB555X">
<entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
<entry>'RGBQ'</entry>
<entry></entry>
<entry>a</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-BGR32">
<entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
<entry>'BGR4'</entry>

View File

@ -76,21 +76,22 @@
<entry></entry>
<entry>&v4l2-event-vsync;</entry>
<entry><structfield>vsync</structfield></entry>
<entry>Event data for event V4L2_EVENT_VSYNC.
<entry>Event data for event <constant>V4L2_EVENT_VSYNC</constant>.
</entry>
</row>
<row>
<entry></entry>
<entry>&v4l2-event-ctrl;</entry>
<entry><structfield>ctrl</structfield></entry>
<entry>Event data for event V4L2_EVENT_CTRL.
<entry>Event data for event <constant>V4L2_EVENT_CTRL</constant>.
</entry>
</row>
<row>
<entry></entry>
<entry>&v4l2-event-frame-sync;</entry>
<entry><structfield>frame_sync</structfield></entry>
<entry>Event data for event V4L2_EVENT_FRAME_SYNC.</entry>
<entry>Event data for event
<constant>V4L2_EVENT_FRAME_SYNC</constant>.</entry>
</row>
<row>
<entry></entry>

View File

@ -24,7 +24,7 @@
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>const struct v4l2_edid *<parameter>argp</parameter></paramdef>
<paramdef>struct v4l2_edid *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
@ -124,18 +124,18 @@
maximum number of blocks as defined by the standard). When you set the EDID and
<structfield>blocks</structfield> is 0, then the EDID is disabled or erased.</entry>
</row>
<row>
<entry>__u8&nbsp;*</entry>
<entry><structfield>edid</structfield></entry>
<entry>Pointer to memory that contains the EDID. The minimum size is
<structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[5]</entry>
<entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry>
</row>
<row>
<entry>__u8&nbsp;*</entry>
<entry><structfield>edid</structfield></entry>
<entry>Pointer to memory that contains the EDID. The minimum size is
<structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -176,7 +176,7 @@
</row>
<row>
<entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
<entry>5</entry>
<entry>6</entry>
<entry>
<para>Triggered whenever the motion detection state for one or more of the regions
changes. This event has a &v4l2-event-motion-det; associated with it.</para>

View File

@ -0,0 +1,25 @@
Device-Tree bindings for hix5hd2 ir IP
Required properties:
- compatible: Should contain "hisilicon,hix5hd2-ir".
- reg: Base physical address of the controller and length of memory
mapped region.
- interrupts: interrupt-specifier for the sole interrupt generated by
the device. The interrupt specifier format depends on the interrupt
controller parent.
- clocks: clock phandle and specifier pair.
- hisilicon,power-syscon: phandle of syscon used to control power.
Optional properties:
- linux,rc-map-name : Remote control map name.
Example node:
ir: ir@f8001000 {
compatible = "hisilicon,hix5hd2-ir";
reg = <0xf8001000 0x1000>;
interrupts = <0 47 4>;
clocks = <&clock HIX5HD2_FIXED_24M>;
hisilicon,power-syscon = <&sysctrl>;
linux,rc-map-name = "rc-tivo";
};

View File

@ -708,23 +708,25 @@ sub drxk_terratec_htc_stick {
}
sub it9135 {
my $sourcefile = "dvb-usb-it9135.zip";
my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile";
my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
my $outfile = "dvb-usb-it9135.fw";
my $url = "http://www.ite.com.tw/uploads/firmware/v3.25.0.0/";
my $file1 = "dvb-usb-it9135-01.zip";
my $fwfile1 = "dvb-usb-it9135-01.fw";
my $hash1 = "02fcf11174eda84745dae7e61c5ff9ba";
my $file2 = "dvb-usb-it9135-02.zip";
my $fwfile2 = "dvb-usb-it9135-02.fw";
my $hash2 = "d5e1437dc24358578e07999475d4cac9";
checkstandard();
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/$outfile", $hash);
extract("$tmpdir/$outfile", 64, 8128, "$fwfile1");
extract("$tmpdir/$outfile", 12866, 5817, "$fwfile2");
wgetfile($file1, $url . $file1);
unzip($file1, "");
verify("$fwfile1", $hash1);
"$fwfile1 $fwfile2"
wgetfile($file2, $url . $file2);
unzip($file2, "");
verify("$fwfile2", $hash2);
"$file1 $file2"
}
sub tda10071 {

File diff suppressed because it is too large Load Diff

View File

@ -4177,6 +4177,16 @@ L: linuxppc-dev@lists.ozlabs.org
S: Odd Fixes
F: drivers/tty/hvc/
HACKRF MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/hackrf/
HARDWARE MONITORING
M: Jean Delvare <jdelvare@suse.de>
M: Guenter Roeck <linux@roeck-us.net>
@ -5070,7 +5080,7 @@ W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/tuner_it913x*
F: drivers/media/tuners/it913x*
IVTV VIDEO4LINUX DRIVER
M: Andy Walls <awalls@md.metrocast.net>
@ -8588,6 +8598,14 @@ F: include/sound/dmaengine_pcm.h
F: sound/core/pcm_dmaengine.c
F: sound/soc/soc-generic-dmaengine-pcm.c
SP2 MEDIA DRIVER
M: Olli Salonen <olli.salonen@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
F: drivers/media/dvb-frontends/sp2*
SPARC + UltraSPARC (sparc/sparc64)
M: "David S. Miller" <davem@davemloft.net>
L: sparclinux@vger.kernel.org
@ -9293,6 +9311,14 @@ T: git git://linuxtv.org/media_tree.git
S: Odd fixes
F: drivers/media/usb/tm6000/
TW68 VIDEO4LINUX DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Odd Fixes
F: drivers/media/pci/tw68/
TPM DEVICE DRIVER
M: Peter Huewe <peterhuewe@gmx.de>
M: Ashley Lai <ashley@ashleylai.com>

View File

@ -4,7 +4,7 @@
* see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_H__
#define __FLEXCOP_H___
#define __FLEXCOP_H__
#define FC_LOG_PREFIX "b2c2-flexcop"
#include "flexcop-common.h"

View File

@ -311,7 +311,6 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
}
default:
BUG();
return 0;
}
if (mutex_lock_interruptible(vdev->lock))
@ -399,7 +398,6 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
return -EINVAL;
default:
BUG();
return 0;
}
}
@ -423,7 +421,6 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
return -EINVAL;
default:
BUG();
return -EINVAL;
}
}

View File

@ -157,6 +157,12 @@ static struct sms_board sms_boards[] = {
.type = SMS_DENVER_2160,
.default_mode = DEVICE_MODE_DAB_TDMB,
},
[SMS1XXX_BOARD_PCTV_77E] = {
.name = "Hauppauge microStick 77e",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
};
struct sms_board *sms_get_board(unsigned id)

View File

@ -45,6 +45,7 @@
#define SMS1XXX_BOARD_SIANO_RIO 18
#define SMS1XXX_BOARD_SIANO_DENVER_1530 19
#define SMS1XXX_BOARD_SIANO_DENVER_2160 20
#define SMS1XXX_BOARD_PCTV_77E 21
struct sms_board_gpio_cfg {
int lna_vhf_exist;

View File

@ -2129,8 +2129,6 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
static int __init smscore_module_init(void)
{
int rc = 0;
INIT_LIST_HEAD(&g_smscore_notifyees);
INIT_LIST_HEAD(&g_smscore_devices);
kmutex_init(&g_smscore_deviceslock);
@ -2138,7 +2136,7 @@ static int __init smscore_module_init(void)
INIT_LIST_HEAD(&g_smscore_registry);
kmutex_init(&g_smscore_registrylock);
return rc;
return 0;
}
static void __exit smscore_module_exit(void)

View File

@ -1087,8 +1087,8 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
struct dmxdev_filter *dmxdevfilter = file->private_data;
unsigned int mask = 0;
if (!dmxdevfilter)
return -EINVAL;
if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
return POLLERR;
poll_wait(file, &dmxdevfilter->buffer.queue, wait);
@ -1181,6 +1181,9 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
dprintk("function : %s\n", __func__);
if (dmxdev->exit)
return POLLERR;
poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {

View File

@ -144,6 +144,7 @@
#define USB_PID_ITETECH_IT9135 0x9135
#define USB_PID_ITETECH_IT9135_9005 0x9005
#define USB_PID_ITETECH_IT9135_9006 0x9006
#define USB_PID_ITETECH_IT9303 0x9306
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_399U_2 0xe400
#define USB_PID_KWORLD_395U 0xe396
@ -244,6 +245,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081

View File

@ -1934,15 +1934,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int err = 0;
struct dtv_properties *tvps = NULL;
struct dtv_properties *tvps = parg;
struct dtv_property *tvp = NULL;
int i;
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if(cmd == FE_SET_PROPERTY) {
tvps = (struct dtv_properties __user *)parg;
if (cmd == FE_SET_PROPERTY) {
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
@ -1957,7 +1955,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
goto out;
}
if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
if (copy_from_user(tvp, (void __user *)tvps->props,
tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@ -1972,10 +1971,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
if (c->state == DTV_TUNE)
dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
} else
if(cmd == FE_GET_PROPERTY) {
tvps = (struct dtv_properties __user *)parg;
} else if (cmd == FE_GET_PROPERTY) {
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
@ -1990,7 +1986,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
goto out;
}
if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
if (copy_from_user(tvp, (void __user *)tvps->props,
tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@ -2012,7 +2009,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
(tvp + i)->result = err;
}
if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
if (copy_to_user((void __user *)tvps->props, tvp,
tvps->num * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
@ -2072,6 +2070,23 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_DVBC_ANNEX_C:
rolloff = 113;
break;
case SYS_DVBS:
case SYS_TURBO:
rolloff = 135;
break;
case SYS_DVBS2:
switch (c->rolloff) {
case ROLLOFF_20:
rolloff = 120;
break;
case ROLLOFF_25:
rolloff = 125;
break;
default:
case ROLLOFF_35:
rolloff = 135;
}
break;
default:
break;
}
@ -2550,7 +2565,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
fe->id);
if (fe->ops.tuner_ops.sleep)
if (fe->ops.tuner_ops.suspend)
ret = fe->ops.tuner_ops.suspend(fe);
else if (fe->ops.tuner_ops.sleep)
ret = fe->ops.tuner_ops.sleep(fe);
if (fe->ops.sleep)
@ -2572,7 +2589,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
if (fe->ops.init)
ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.init)
if (fe->ops.tuner_ops.resume)
ret = fe->ops.tuner_ops.resume(fe);
else if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe);
fe->exit = DVB_FE_NO_EXIT;

View File

@ -201,6 +201,8 @@ struct dvb_tuner_ops {
int (*release)(struct dvb_frontend *fe);
int (*init)(struct dvb_frontend *fe);
int (*sleep)(struct dvb_frontend *fe);
int (*suspend)(struct dvb_frontend *fe);
int (*resume)(struct dvb_frontend *fe);
/** This is for simple PLLs - set all parameters in one go. */
int (*set_params)(struct dvb_frontend *fe);

View File

@ -166,6 +166,31 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t
return len;
}
ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
const u8 __user *buf, size_t len)
{
int status;
size_t todo = len;
size_t split;
split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
if (split > 0) {
status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split);
if (status)
return len - todo;
buf += split;
todo -= split;
rbuf->pwrite = 0;
}
status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
if (status)
return len - todo;
rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
return len;
}
ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
{
int status;
@ -297,3 +322,4 @@ EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
EXPORT_SYMBOL(dvb_ringbuffer_read_user);
EXPORT_SYMBOL(dvb_ringbuffer_read);
EXPORT_SYMBOL(dvb_ringbuffer_write);
EXPORT_SYMBOL(dvb_ringbuffer_write_user);

View File

@ -133,6 +133,8 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
*/
extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
size_t len);
extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
const u8 __user *buf, size_t len);
/**

View File

@ -471,6 +471,11 @@ config DVB_SI2168
help
Say Y when you want to support this frontend.
config DVB_AS102_FE
tristate
depends on DVB_CORE
default DVB_AS102
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@ -643,6 +648,14 @@ config DVB_MB86A20S
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
config DVB_TC90522
tristate "Toshiba TC90522"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Toshiba TC90522 2xISDB-T + 2xISDB-S demodulator.
Say Y when you want to support this frontend.
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
@ -720,6 +733,13 @@ config DVB_A8293
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_SP2
tristate "CIMaX SP2"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
CIMaX SP2/SP2HF Common Interface module.
config DVB_LGS8GL5
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
depends on DVB_CORE && I2C

View File

@ -107,10 +107,12 @@ obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_SP2) += sp2.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
obj-$(CONFIG_DVB_TC90522) += tc90522.o

View File

@ -683,7 +683,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
switch (c->transmission_mode) {
case TRANSMISSION_MODE_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case TRANSMISSION_MODE_2K:
break;
@ -693,12 +693,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid transmission_mode\n",
__func__);
auto_mode = 1;
auto_mode = true;
}
switch (c->guard_interval) {
case GUARD_INTERVAL_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case GUARD_INTERVAL_1_32:
break;
@ -714,12 +714,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid guard_interval\n",
__func__);
auto_mode = 1;
auto_mode = true;
}
switch (c->hierarchy) {
case HIERARCHY_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case HIERARCHY_NONE:
break;
@ -734,12 +734,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
break;
default:
dev_dbg(&state->i2c->dev, "%s: invalid hierarchy\n", __func__);
auto_mode = 1;
auto_mode = true;
}
switch (c->modulation) {
case QAM_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case QPSK:
break;
@ -751,7 +751,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
break;
default:
dev_dbg(&state->i2c->dev, "%s: invalid modulation\n", __func__);
auto_mode = 1;
auto_mode = true;
}
/* Use HP. How and which case we can switch to LP? */
@ -759,7 +759,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
switch (c->code_rate_HP) {
case FEC_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case FEC_1_2:
break;
@ -778,12 +778,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid code_rate_HP\n",
__func__);
auto_mode = 1;
auto_mode = true;
}
switch (c->code_rate_LP) {
case FEC_AUTO:
auto_mode = 1;
auto_mode = true;
break;
case FEC_1_2:
break;
@ -804,7 +804,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
default:
dev_dbg(&state->i2c->dev, "%s: invalid code_rate_LP\n",
__func__);
auto_mode = 1;
auto_mode = true;
}
switch (c->bandwidth_hz) {

File diff suppressed because it is too large Load Diff

View File

@ -24,12 +24,11 @@
#include <linux/kconfig.h>
/*
* I2C address (TODO: are these in 8-bit format?)
* 0x38, 0x3a, 0x3c, 0x3e
*/
struct af9033_config {
/*
* I2C address
*/
u8 i2c_addr;
/*
* clock Hz
* 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
@ -75,8 +74,23 @@ struct af9033_config {
* input spectrum inversion
*/
bool spec_inv;
};
/*
*
*/
bool dyn0_clk;
/*
* PID filter ops
*/
struct af9033_ops *ops;
/*
* frontend
* returned by that driver
*/
struct dvb_frontend **fe;
};
struct af9033_ops {
int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
@ -84,36 +98,4 @@ struct af9033_ops {
int onoff);
};
#if IS_ENABLED(CONFIG_DVB_AF9033)
extern
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct i2c_adapter *i2c,
struct af9033_ops *ops);
#else
static inline
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct i2c_adapter *i2c,
struct af9033_ops *ops)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
int onoff)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif
#endif /* AF9033_H */

View File

@ -24,6 +24,7 @@
#include "dvb_frontend.h"
#include "af9033.h"
#include <linux/math64.h>
struct reg_val {
u32 reg;

View File

@ -0,0 +1,480 @@
/*
* Abilis Systems Single DVB-T Receiver
* Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
* Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.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, 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 <dvb_frontend.h>
#include "as102_fe.h"
struct as102_state {
struct dvb_frontend frontend;
struct as10x_demod_stats demod_stats;
const struct as102_fe_ops *ops;
void *priv;
uint8_t elna_cfg;
/* signal strength */
uint16_t signal_strength;
/* bit error rate */
uint32_t ber;
};
static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
{
uint8_t c;
switch (arg) {
case FEC_1_2:
c = CODE_RATE_1_2;
break;
case FEC_2_3:
c = CODE_RATE_2_3;
break;
case FEC_3_4:
c = CODE_RATE_3_4;
break;
case FEC_5_6:
c = CODE_RATE_5_6;
break;
case FEC_7_8:
c = CODE_RATE_7_8;
break;
default:
c = CODE_RATE_UNKNOWN;
break;
}
return c;
}
static int as102_fe_set_frontend(struct dvb_frontend *fe)
{
struct as102_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct as10x_tune_args tune_args = { 0 };
/* set frequency */
tune_args.freq = c->frequency / 1000;
/* fix interleaving_mode */
tune_args.interleaving_mode = INTLV_NATIVE;
switch (c->bandwidth_hz) {
case 8000000:
tune_args.bandwidth = BW_8_MHZ;
break;
case 7000000:
tune_args.bandwidth = BW_7_MHZ;
break;
case 6000000:
tune_args.bandwidth = BW_6_MHZ;
break;
default:
tune_args.bandwidth = BW_8_MHZ;
}
switch (c->guard_interval) {
case GUARD_INTERVAL_1_32:
tune_args.guard_interval = GUARD_INT_1_32;
break;
case GUARD_INTERVAL_1_16:
tune_args.guard_interval = GUARD_INT_1_16;
break;
case GUARD_INTERVAL_1_8:
tune_args.guard_interval = GUARD_INT_1_8;
break;
case GUARD_INTERVAL_1_4:
tune_args.guard_interval = GUARD_INT_1_4;
break;
case GUARD_INTERVAL_AUTO:
default:
tune_args.guard_interval = GUARD_UNKNOWN;
break;
}
switch (c->modulation) {
case QPSK:
tune_args.modulation = CONST_QPSK;
break;
case QAM_16:
tune_args.modulation = CONST_QAM16;
break;
case QAM_64:
tune_args.modulation = CONST_QAM64;
break;
default:
tune_args.modulation = CONST_UNKNOWN;
break;
}
switch (c->transmission_mode) {
case TRANSMISSION_MODE_2K:
tune_args.transmission_mode = TRANS_MODE_2K;
break;
case TRANSMISSION_MODE_8K:
tune_args.transmission_mode = TRANS_MODE_8K;
break;
default:
tune_args.transmission_mode = TRANS_MODE_UNKNOWN;
}
switch (c->hierarchy) {
case HIERARCHY_NONE:
tune_args.hierarchy = HIER_NONE;
break;
case HIERARCHY_1:
tune_args.hierarchy = HIER_ALPHA_1;
break;
case HIERARCHY_2:
tune_args.hierarchy = HIER_ALPHA_2;
break;
case HIERARCHY_4:
tune_args.hierarchy = HIER_ALPHA_4;
break;
case HIERARCHY_AUTO:
tune_args.hierarchy = HIER_UNKNOWN;
break;
}
pr_debug("as102: tuner parameters: freq: %d bw: 0x%02x gi: 0x%02x\n",
c->frequency,
tune_args.bandwidth,
tune_args.guard_interval);
/*
* Detect a hierarchy selection
* if HP/LP are both set to FEC_NONE, HP will be selected.
*/
if ((tune_args.hierarchy != HIER_NONE) &&
((c->code_rate_LP == FEC_NONE) ||
(c->code_rate_HP == FEC_NONE))) {
if (c->code_rate_LP == FEC_NONE) {
tune_args.hier_select = HIER_HIGH_PRIORITY;
tune_args.code_rate =
as102_fe_get_code_rate(c->code_rate_HP);
}
if (c->code_rate_HP == FEC_NONE) {
tune_args.hier_select = HIER_LOW_PRIORITY;
tune_args.code_rate =
as102_fe_get_code_rate(c->code_rate_LP);
}
pr_debug("as102: \thierarchy: 0x%02x selected: %s code_rate_%s: 0x%02x\n",
tune_args.hierarchy,
tune_args.hier_select == HIER_HIGH_PRIORITY ?
"HP" : "LP",
tune_args.hier_select == HIER_HIGH_PRIORITY ?
"HP" : "LP",
tune_args.code_rate);
} else {
tune_args.code_rate =
as102_fe_get_code_rate(c->code_rate_HP);
}
/* Set frontend arguments */
return state->ops->set_tune(state->priv, &tune_args);
}
static int as102_fe_get_frontend(struct dvb_frontend *fe)
{
struct as102_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret = 0;
struct as10x_tps tps = { 0 };
/* send abilis command: GET_TPS */
ret = state->ops->get_tps(state->priv, &tps);
if (ret < 0)
return ret;
/* extract constellation */
switch (tps.modulation) {
case CONST_QPSK:
c->modulation = QPSK;
break;
case CONST_QAM16:
c->modulation = QAM_16;
break;
case CONST_QAM64:
c->modulation = QAM_64;
break;
}
/* extract hierarchy */
switch (tps.hierarchy) {
case HIER_NONE:
c->hierarchy = HIERARCHY_NONE;
break;
case HIER_ALPHA_1:
c->hierarchy = HIERARCHY_1;
break;
case HIER_ALPHA_2:
c->hierarchy = HIERARCHY_2;
break;
case HIER_ALPHA_4:
c->hierarchy = HIERARCHY_4;
break;
}
/* extract code rate HP */
switch (tps.code_rate_HP) {
case CODE_RATE_1_2:
c->code_rate_HP = FEC_1_2;
break;
case CODE_RATE_2_3:
c->code_rate_HP = FEC_2_3;
break;
case CODE_RATE_3_4:
c->code_rate_HP = FEC_3_4;
break;
case CODE_RATE_5_6:
c->code_rate_HP = FEC_5_6;
break;
case CODE_RATE_7_8:
c->code_rate_HP = FEC_7_8;
break;
}
/* extract code rate LP */
switch (tps.code_rate_LP) {
case CODE_RATE_1_2:
c->code_rate_LP = FEC_1_2;
break;
case CODE_RATE_2_3:
c->code_rate_LP = FEC_2_3;
break;
case CODE_RATE_3_4:
c->code_rate_LP = FEC_3_4;
break;
case CODE_RATE_5_6:
c->code_rate_LP = FEC_5_6;
break;
case CODE_RATE_7_8:
c->code_rate_LP = FEC_7_8;
break;
}
/* extract guard interval */
switch (tps.guard_interval) {
case GUARD_INT_1_32:
c->guard_interval = GUARD_INTERVAL_1_32;
break;
case GUARD_INT_1_16:
c->guard_interval = GUARD_INTERVAL_1_16;
break;
case GUARD_INT_1_8:
c->guard_interval = GUARD_INTERVAL_1_8;
break;
case GUARD_INT_1_4:
c->guard_interval = GUARD_INTERVAL_1_4;
break;
}
/* extract transmission mode */
switch (tps.transmission_mode) {
case TRANS_MODE_2K:
c->transmission_mode = TRANSMISSION_MODE_2K;
break;
case TRANS_MODE_8K:
c->transmission_mode = TRANSMISSION_MODE_8K;
break;
}
return 0;
}
static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *settings) {
settings->min_delay_ms = 1000;
return 0;
}
static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
int ret = 0;
struct as102_state *state = fe->demodulator_priv;
struct as10x_tune_status tstate = { 0 };
/* send abilis command: GET_TUNE_STATUS */
ret = state->ops->get_status(state->priv, &tstate);
if (ret < 0)
return ret;
state->signal_strength = tstate.signal_strength;
state->ber = tstate.BER;
switch (tstate.tune_state) {
case TUNE_STATUS_SIGNAL_DVB_OK:
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
break;
case TUNE_STATUS_STREAM_DETECTED:
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
FE_HAS_VITERBI;
break;
case TUNE_STATUS_STREAM_TUNED:
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
FE_HAS_LOCK | FE_HAS_VITERBI;
break;
default:
*status = TUNE_STATUS_NOT_TUNED;
}
pr_debug("as102: tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
tstate.tune_state, tstate.signal_strength,
tstate.PER, tstate.BER);
if (!(*status & FE_HAS_LOCK)) {
memset(&state->demod_stats, 0, sizeof(state->demod_stats));
return 0;
}
ret = state->ops->get_stats(state->priv, &state->demod_stats);
if (ret < 0)
memset(&state->demod_stats, 0, sizeof(state->demod_stats));
return ret;
}
/*
* Note:
* - in AS102 SNR=MER
* - the SNR will be returned in linear terms, i.e. not in dB
* - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
* - the accuracy is >2dB for SNR values outside this range
*/
static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
{
struct as102_state *state = fe->demodulator_priv;
*snr = state->demod_stats.mer;
return 0;
}
static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct as102_state *state = fe->demodulator_priv;
*ber = state->ber;
return 0;
}
static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
struct as102_state *state = fe->demodulator_priv;
*strength = (((0xffff * 400) * state->signal_strength + 41000) * 2);
return 0;
}
static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
struct as102_state *state = fe->demodulator_priv;
if (state->demod_stats.has_started)
*ucblocks = state->demod_stats.bad_frame_count;
else
*ucblocks = 0;
return 0;
}
static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
{
struct as102_state *state = fe->demodulator_priv;
return state->ops->stream_ctrl(state->priv, acquire,
state->elna_cfg);
}
static void as102_fe_release(struct dvb_frontend *fe)
{
struct as102_state *state = fe->demodulator_priv;
kfree(state);
}
static struct dvb_frontend_ops as102_fe_ops = {
.delsys = { SYS_DVBT },
.info = {
.name = "Abilis AS102 DVB-T",
.frequency_min = 174000000,
.frequency_max = 862000000,
.frequency_stepsize = 166667,
.caps = FE_CAN_INVERSION_AUTO
| 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_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
| 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
},
.set_frontend = as102_fe_set_frontend,
.get_frontend = as102_fe_get_frontend,
.get_tune_settings = as102_fe_get_tune_settings,
.read_status = as102_fe_read_status,
.read_snr = as102_fe_read_snr,
.read_ber = as102_fe_read_ber,
.read_signal_strength = as102_fe_read_signal_strength,
.read_ucblocks = as102_fe_read_ucblocks,
.ts_bus_ctrl = as102_fe_ts_bus_ctrl,
.release = as102_fe_release,
};
struct dvb_frontend *as102_attach(const char *name,
const struct as102_fe_ops *ops,
void *priv,
uint8_t elna_cfg)
{
struct as102_state *state;
struct dvb_frontend *fe;
state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
if (state == NULL) {
pr_err("%s: unable to allocate memory for state\n", __func__);
return NULL;
}
fe = &state->frontend;
fe->demodulator_priv = state;
state->ops = ops;
state->priv = priv;
state->elna_cfg = elna_cfg;
/* init frontend callback ops */
memcpy(&fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
strncpy(fe->ops.info.name, name, sizeof(fe->ops.info.name));
return fe;
}
EXPORT_SYMBOL_GPL(as102_attach);
MODULE_DESCRIPTION("as102-fe");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");

View File

@ -0,0 +1,29 @@
/*
* Abilis Systems Single DVB-T Receiver
* Copyright (C) 2014 Mauro Carvalho Chehab <m.chehab@samsung.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, 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 "as102_fe_types.h"
struct as102_fe_ops {
int (*set_tune)(void *priv, struct as10x_tune_args *tune_args);
int (*get_tps)(void *priv, struct as10x_tps *tps);
int (*get_status)(void *priv, struct as10x_tune_status *tstate);
int (*get_stats)(void *priv, struct as10x_demod_stats *demod_stats);
int (*stream_ctrl)(void *priv, int acquire, uint32_t elna_cfg);
};
struct dvb_frontend *as102_attach(const char *name,
const struct as102_fe_ops *ops,
void *priv,
uint8_t elna_cfg);

View File

@ -11,16 +11,10 @@
* 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 _AS10X_TYPES_H_
#define _AS10X_TYPES_H_
#include "as10x_handle.h"
/*********************************/
/* MACRO DEFINITIONS */
/*********************************/

View File

@ -639,12 +639,12 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
return ret;
}
deb_info("got firmware: %zd\n",fw->size);
deb_info("got firmware: %zu\n", fw->size);
b = fw->data;
for (i = 0; i < fw->size;) {
addr = le16_to_cpu( *( (u16 *)&b[i] ) );
len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
addr = le16_to_cpu(*((__le16 *)&b[i]));
len = le16_to_cpu(*((__le16 *)&b[i+2]));
deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
err("firmware download failed: %d\n",ret);

View File

@ -65,7 +65,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
}
priv->delivery_system = SYS_DVBC_ANNEX_A;
priv->ber_running = 0; /* tune stops BER counter */
priv->ber_running = false; /* tune stops BER counter */
/* program IF frequency */
if (fe->ops.tuner_ops.get_if_frequency) {
@ -168,7 +168,7 @@ int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
start_ber = 1;
}
} else {
priv->ber_running = 1;
priv->ber_running = true;
start_ber = 1;
}

View File

@ -564,10 +564,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
/* check if we have a valid signal */
if (status & FE_HAS_LOCK) {
priv->last_tune_failed = 0;
priv->last_tune_failed = false;
return DVBFE_ALGO_SEARCH_SUCCESS;
} else {
priv->last_tune_failed = 1;
priv->last_tune_failed = true;
return DVBFE_ALGO_SEARCH_AGAIN;
}

View File

@ -89,7 +89,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
}
priv->delivery_system = SYS_DVBT;
priv->ber_running = 0; /* tune stops BER counter */
priv->ber_running = false; /* tune stops BER counter */
/* program IF frequency */
if (fe->ops.tuner_ops.get_if_frequency) {
@ -272,7 +272,7 @@ int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
start_ber = 1;
}
} else {
priv->ber_running = 1;
priv->ber_running = true;
start_ber = 1;
}

View File

@ -2559,7 +2559,7 @@ static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
dib7000p_write_word(state, 1288, reg_1288);
}
int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg_1287;

View File

@ -2174,7 +2174,7 @@ int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
u32 addr,
u32 *data, u32 flags)
{
u8 buf[sizeof(*data)];
u8 buf[sizeof(*data)] = { 0 };
int rc = -EIO;
u32 word = 0;
@ -4193,7 +4193,7 @@ int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
u32 addr,
u16 *data, u32 flags)
{
u8 buf[2];
u8 buf[2] = { 0 };
int rc = -EIO;
u16 word = 0;
@ -10667,7 +10667,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
enum drx_standard standard = ext_attr->standard;
int rc;
u32 ber, cnt, err, pkt;
u16 mer, strength;
u16 mer, strength = 0;
rc = get_sig_strength(demod, &strength);
if (rc < 0) {
@ -11602,7 +11602,7 @@ static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
u32 carry = 0;
while (i < nr_words) {
crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
for (j = 0; j < 16; j++) {
crc_word <<= 1;
if (carry != 0)
@ -11629,7 +11629,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
int i;
unsigned count = 2 * sizeof(u16);
u32 mc_dev_type, mc_version, mc_base_version;
u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
/*
* Scan microcode blocks first for version info
@ -11647,13 +11647,13 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
goto eof;
/* Process block header */
block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
count += sizeof(u32);
block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
count += sizeof(u16);
pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
@ -11667,7 +11667,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
if (block_hdr.addr + sizeof(u16) > size)
goto eof;
auxtype = be16_to_cpu(*(u32 *)(auxblk));
auxtype = be16_to_cpu(*(__be16 *)(auxblk));
/* Aux block. Check type */
if (DRX_ISMCVERTYPE(auxtype)) {
@ -11675,11 +11675,11 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
goto eof;
auxblk += sizeof(u16);
mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
auxblk += sizeof(u32);
mc_version = be32_to_cpu(*(u32 *)(auxblk));
mc_version = be32_to_cpu(*(__be32 *)(auxblk));
auxblk += sizeof(u32);
mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
@ -11765,9 +11765,9 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
mc_data = (void *)mc_data_init;
/* Check data */
mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
@ -11791,13 +11791,13 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
u16 mc_block_nr_bytes = 0;
/* Process block header */
block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
mc_data += sizeof(u32);
block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
mc_data += sizeof(u16);
pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",

View File

@ -2628,10 +2628,11 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
break;
/* Apply I2c address patch to B1 */
if (!state->type_A && state->m_HiI2cPatch != NULL)
if (!state->type_A && state->m_HiI2cPatch != NULL) {
status = WriteTable(state, state->m_HiI2cPatch);
if (status < 0)
break;
}
if (state->type_A) {
/* HI firmware patch for UIO readout,
@ -2830,14 +2831,8 @@ static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
static int drxd_init(struct dvb_frontend *fe)
{
struct drxd_state *state = fe->demodulator_priv;
int err = 0;
/* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
return DRXD_init(state, NULL, 0);
err = DRXD_init(state, state->fw->data, state->fw->size);
release_firmware(state->fw);
return err;
}
static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)

View File

@ -1028,7 +1028,7 @@ static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
((state->m_hi_cfg_ctrl) &
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
if (powerdown_cmd == false) {
if (!powerdown_cmd) {
/* Wait until command rdy */
u32 retry_count = 0;
u16 wait_cmd;
@ -1129,7 +1129,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
if (status < 0)
goto error;
if (mpeg_enable == false) {
if (!mpeg_enable) {
/* Set MPEG TS pads to inputmode */
status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
if (status < 0)
@ -1190,7 +1190,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
if (status < 0)
goto error;
if (state->m_enable_parallel == true) {
if (state->m_enable_parallel) {
/* parallel -> enable MD1 to MD7 */
status = write16(state, SIO_PDR_MD1_CFG__A,
sio_pdr_mdx_cfg);
@ -1392,7 +1392,7 @@ static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
dprintk(1, "\n");
if (enable == false) {
if (!enable) {
desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
}
@ -2012,7 +2012,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
goto error;
fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
if (state->m_insert_rs_byte == true) {
if (state->m_insert_rs_byte) {
/* enable parity symbol forward */
fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
/* MVAL disable during parity bytes */
@ -2023,7 +2023,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
/* Check serial or parallel output */
fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
if (state->m_enable_parallel == false) {
if (!state->m_enable_parallel) {
/* MPEG data output is serial -> set ipr_mode[0] */
fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
}
@ -2136,19 +2136,19 @@ static int mpegts_configure_polarity(struct drxk_state *state)
/* Control selective inversion of output bits */
fec_oc_reg_ipr_invert &= (~(invert_data_mask));
if (state->m_invert_data == true)
if (state->m_invert_data)
fec_oc_reg_ipr_invert |= invert_data_mask;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
if (state->m_invert_err == true)
if (state->m_invert_err)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
if (state->m_invert_str == true)
if (state->m_invert_str)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
if (state->m_invert_val == true)
if (state->m_invert_val)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
if (state->m_invert_clk == true)
if (state->m_invert_clk)
fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
@ -2220,12 +2220,13 @@ static int set_agc_rf(struct drxk_state *state,
}
/* Set TOP, only if IF-AGC is in AUTO mode */
if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
status = write16(state,
SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
p_agc_cfg->top);
if (status < 0)
goto error;
}
/* Cut-Off current */
status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
@ -3352,7 +3353,7 @@ static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
int status;
dprintk(1, "\n");
if (*enabled == true)
if (*enabled)
status = write16(state, IQM_CF_BYPASSDET__A, 0);
else
status = write16(state, IQM_CF_BYPASSDET__A, 1);
@ -3368,7 +3369,7 @@ static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
int status;
dprintk(1, "\n");
if (*enabled == true) {
if (*enabled) {
/* write mask to 1 */
status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
DEFAULT_FR_THRES_8K);
@ -6794,11 +6795,11 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
state->enable_merr_cfg = config->enable_merr_cfg;
if (config->dynamic_clk) {
state->m_dvbt_static_clk = 0;
state->m_dvbc_static_clk = 0;
state->m_dvbt_static_clk = false;
state->m_dvbc_static_clk = false;
} else {
state->m_dvbt_static_clk = 1;
state->m_dvbc_static_clk = 1;
state->m_dvbt_static_clk = true;
state->m_dvbc_static_clk = true;
}

View File

@ -159,6 +159,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
{
int ret, i, j;
u8 buf[83];
dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
if (tab_len > 83) {
@ -247,8 +248,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
u8 u8tmp, u8tmp1, u8tmp2;
u8 buf[2];
u16 u16tmp, divide_ratio;
u32 tuner_frequency, target_mclk, ts_clk;
u32 tuner_frequency, target_mclk;
s32 s32tmp;
dev_dbg(&priv->i2c->dev,
"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
__func__, c->delivery_system,
@ -316,9 +318,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
target_mclk = 144000;
break;
case M88DS3103_TS_PARALLEL:
case M88DS3103_TS_PARALLEL_12:
case M88DS3103_TS_PARALLEL_16:
case M88DS3103_TS_PARALLEL_19_2:
case M88DS3103_TS_CI:
if (c->symbol_rate < 18000000)
target_mclk = 96000;
@ -352,33 +351,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
switch (priv->cfg->ts_mode) {
case M88DS3103_TS_SERIAL:
u8tmp1 = 0x00;
ts_clk = 0;
u8tmp = 0x46;
u8tmp = 0x06;
break;
case M88DS3103_TS_SERIAL_D7:
u8tmp1 = 0x20;
ts_clk = 0;
u8tmp = 0x46;
u8tmp = 0x06;
break;
case M88DS3103_TS_PARALLEL:
ts_clk = 24000;
u8tmp = 0x42;
break;
case M88DS3103_TS_PARALLEL_12:
ts_clk = 12000;
u8tmp = 0x42;
break;
case M88DS3103_TS_PARALLEL_16:
ts_clk = 16000;
u8tmp = 0x42;
break;
case M88DS3103_TS_PARALLEL_19_2:
ts_clk = 19200;
u8tmp = 0x42;
u8tmp = 0x02;
break;
case M88DS3103_TS_CI:
ts_clk = 6000;
u8tmp = 0x43;
u8tmp = 0x03;
break;
default:
dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__);
@ -386,6 +369,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err;
}
if (priv->cfg->ts_clk_pol)
u8tmp |= 0x40;
/* TS mode */
ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp);
if (ret)
@ -399,8 +385,8 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
goto err;
}
if (ts_clk) {
divide_ratio = DIV_ROUND_UP(target_mclk, ts_clk);
if (priv->cfg->ts_clk) {
divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
u8tmp1 = divide_ratio / 2;
u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
} else {
@ -411,7 +397,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
dev_dbg(&priv->i2c->dev,
"%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n",
__func__, target_mclk, ts_clk, divide_ratio);
__func__, target_mclk, priv->cfg->ts_clk, divide_ratio);
u8tmp1--;
u8tmp2--;
@ -536,6 +522,7 @@ static int m88ds3103_init(struct dvb_frontend *fe)
const struct firmware *fw = NULL;
u8 *fw_file = M88DS3103_FIRMWARE;
u8 u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
/* set cold state by default */
@ -648,6 +635,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
priv->delivery_system = SYS_UNDEFINED;
@ -682,6 +670,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
u8 buf[3];
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
@ -857,6 +846,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
u8 buf[3];
u16 noise, signal;
u32 noise_tot, signal_tot;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
/* reports SNR in resolution of 0.1 dB */
@ -933,6 +923,7 @@ static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
int ret;
unsigned int utmp;
u8 buf[3], u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
switch (c->delivery_system) {
@ -1013,6 +1004,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret;
u8 u8tmp, tone, reg_a1_mask;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__,
fe_sec_tone_mode);
@ -1053,12 +1045,64 @@ err:
return ret;
}
static int m88ds3103_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t fe_sec_voltage)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret;
u8 u8tmp;
bool voltage_sel, voltage_dis;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
fe_sec_voltage);
if (!priv->warm) {
ret = -EAGAIN;
goto err;
}
switch (fe_sec_voltage) {
case SEC_VOLTAGE_18:
voltage_sel = true;
voltage_dis = false;
break;
case SEC_VOLTAGE_13:
voltage_sel = false;
voltage_dis = false;
break;
case SEC_VOLTAGE_OFF:
voltage_sel = false;
voltage_dis = true;
break;
default:
dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
__func__);
ret = -EINVAL;
goto err;
}
/* output pin polarity */
voltage_sel ^= priv->cfg->lnb_hv_pol;
voltage_dis ^= priv->cfg->lnb_en_pol;
u8tmp = voltage_dis << 1 | voltage_sel << 0;
ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0x03);
if (ret)
goto err;
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *diseqc_cmd)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret, i;
u8 u8tmp;
dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
diseqc_cmd->msg_len, diseqc_cmd->msg);
@ -1130,6 +1174,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
struct m88ds3103_priv *priv = fe->demodulator_priv;
int ret, i;
u8 u8tmp, burst;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
fe_sec_mini_cmd);
@ -1202,6 +1247,7 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
static void m88ds3103_release(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
i2c_del_mux_adapter(priv->i2c_adapter);
kfree(priv);
}
@ -1370,6 +1416,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.diseqc_send_burst = m88ds3103_diseqc_send_burst,
.set_tone = m88ds3103_set_tone,
.set_voltage = m88ds3103_set_voltage,
};
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -47,13 +47,22 @@ struct m88ds3103_config {
*/
#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
#define M88DS3103_TS_PARALLEL 2 /* 24 MHz, normal */
#define M88DS3103_TS_PARALLEL_12 3 /* 12 MHz */
#define M88DS3103_TS_PARALLEL_16 4 /* 16 MHz */
#define M88DS3103_TS_PARALLEL_19_2 5 /* 19.2 MHz */
#define M88DS3103_TS_CI 6 /* 6 MHz */
#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */
#define M88DS3103_TS_CI 3 /* TS CI Mode */
u8 ts_mode;
/*
* TS clk in KHz
* Default: 0.
*/
u32 ts_clk;
/*
* TS clk polarity.
* Default: 0. 1-active at falling edge; 0-active at rising edge.
*/
u8 ts_clk_pol:1;
/*
* spectrum inversion
* Default: 0
@ -86,6 +95,22 @@ struct m88ds3103_config {
* Default: none, must set
*/
u8 agc;
/*
* LNB H/V pin polarity
* Default: 0.
* 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18.
* 0: pin high set to VOLTAGE_18, pin low to set VOLTAGE_13.
*/
u8 lnb_hv_pol:1;
/*
* LNB enable pin polarity
* Default: 0.
* 1: pin high to enable, pin low to disable.
* 0: pin high to disable, pin low to enable.
*/
u8 lnb_en_pol:1;
};
/*

View File

@ -28,7 +28,7 @@
#include "mb86a16.h"
#include "mb86a16_priv.h"
unsigned int verbose = 5;
static unsigned int verbose = 5;
module_param(verbose, int, 0644);
#define ABS(x) ((x) < 0 ? (-x) : (x))
@ -115,9 +115,11 @@ static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
};
ret = i2c_transfer(state->i2c_adap, msg, 2);
if (ret != 2) {
dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=%i)",
reg, ret);
if (ret < 0)
return ret;
return -EREMOTEIO;
}
*val = b1[0];

View File

@ -33,7 +33,7 @@ enum mb86a20s_bandwidth {
MB86A20S_3SEG = 3,
};
u8 mb86a20s_subchannel[] = {
static u8 mb86a20s_subchannel[] = {
0xb0, 0xc0, 0xd0, 0xe0,
0xf0, 0x00, 0x10, 0x20,
};
@ -1228,7 +1228,7 @@ struct linear_segments {
* All tables below return a dB/1000 measurement
*/
static struct linear_segments cnr_to_db_table[] = {
static const struct linear_segments cnr_to_db_table[] = {
{ 19648, 0},
{ 18187, 1000},
{ 16534, 2000},
@ -1262,7 +1262,7 @@ static struct linear_segments cnr_to_db_table[] = {
{ 788, 30000},
};
static struct linear_segments cnr_64qam_table[] = {
static const struct linear_segments cnr_64qam_table[] = {
{ 3922688, 0},
{ 3920384, 1000},
{ 3902720, 2000},
@ -1296,7 +1296,7 @@ static struct linear_segments cnr_64qam_table[] = {
{ 388864, 30000},
};
static struct linear_segments cnr_16qam_table[] = {
static const struct linear_segments cnr_16qam_table[] = {
{ 5314816, 0},
{ 5219072, 1000},
{ 5118720, 2000},
@ -1330,7 +1330,7 @@ static struct linear_segments cnr_16qam_table[] = {
{ 95744, 30000},
};
struct linear_segments cnr_qpsk_table[] = {
static const struct linear_segments cnr_qpsk_table[] = {
{ 2834176, 0},
{ 2683648, 1000},
{ 2536960, 2000},
@ -1364,7 +1364,7 @@ struct linear_segments cnr_qpsk_table[] = {
{ 11520, 30000},
};
static u32 interpolate_value(u32 value, struct linear_segments *segments,
static u32 interpolate_value(u32 value, const struct linear_segments *segments,
unsigned len)
{
u64 tmp64;
@ -1448,7 +1448,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 mer, cnr;
int rc, val, layer;
struct linear_segments *segs;
const struct linear_segments *segs;
unsigned segs_len;
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);

View File

@ -103,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
if (1 + count > sizeof(buf)) {
printk(KERN_WARNING
"mt312: write: len=%zd is too big!\n", count);
"mt312: write: len=%zu is too big!\n", count);
return -EINVAL;
}

View File

@ -111,7 +111,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe,
u8 tudata[585];
int i;
dprintk("Firmware is %zd bytes\n",fw->size);
dprintk("Firmware is %zu bytes\n", fw->size);
/* Get eprom data */
tudata[0] = 17;

View File

@ -936,7 +936,7 @@ static void rtl2832_i2c_gate_work(struct work_struct *work)
if (ret != 1)
goto err;
priv->i2c_gate_state = 0;
priv->i2c_gate_state = false;
return;
err:

View File

@ -329,7 +329,7 @@ static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
struct rtl2832_sdr_state *s)
{
unsigned long flags = 0;
unsigned long flags;
struct rtl2832_sdr_frame_buf *buf = NULL;
spin_lock_irqsave(&s->queued_bufs_lock, flags);
@ -365,17 +365,19 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
dst_len = 0;
}
/* calculate samping rate and output it in 10 seconds intervals */
/* calculate sample rate and output it in 10 seconds intervals */
if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
#define MSECS 10000UL
#define MSECS 10000UL
unsigned int msecs = jiffies_to_msecs(jiffies -
s->jiffies_next + msecs_to_jiffies(MSECS));
unsigned int samples = s->sample - s->sample_measured;
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
s->sample_measured = s->sample;
dev_dbg(&s->udev->dev,
"slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
src_len, samples, MSECS,
samples * 1000UL / MSECS);
"slen=%u samples=%u msecs=%u sample rate=%lu\n",
src_len, samples, msecs,
samples * 1000UL / msecs);
}
/* total number of I+Q pairs */
@ -394,8 +396,8 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
struct rtl2832_sdr_frame_buf *fbuf;
dev_dbg_ratelimited(&s->udev->dev,
"%s: status=%d length=%d/%d errors=%d\n",
__func__, urb->status, urb->actual_length,
"status=%d length=%d/%d errors=%d\n",
urb->status, urb->actual_length,
urb->transfer_buffer_length, urb->error_count);
switch (urb->status) {
@ -443,7 +445,7 @@ static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
int i;
for (i = s->urbs_submitted - 1; i >= 0; i--) {
dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
dev_dbg(&s->udev->dev, "kill urb=%d\n", i);
/* stop the URB */
usb_kill_urb(s->urb_list[i]);
}
@ -457,7 +459,7 @@ static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
int i, ret;
for (i = 0; i < s->urbs_initialized; i++) {
dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
dev_dbg(&s->udev->dev, "submit urb=%d\n", i);
ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
if (ret) {
dev_err(&s->udev->dev,
@ -477,8 +479,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
if (s->flags & USB_STATE_URB_BUF) {
while (s->buf_num) {
s->buf_num--;
dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
__func__, s->buf_num);
dev_dbg(&s->udev->dev, "free buf=%d\n", s->buf_num);
usb_free_coherent(s->udev, s->buf_size,
s->buf_list[s->buf_num],
s->dma_addr[s->buf_num]);
@ -494,24 +495,22 @@ static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
s->buf_num = 0;
s->buf_size = BULK_BUFFER_SIZE;
dev_dbg(&s->udev->dev,
"%s: all in all I will use %u bytes for streaming\n",
__func__, MAX_BULK_BUFS * BULK_BUFFER_SIZE);
dev_dbg(&s->udev->dev, "all in all I will use %u bytes for streaming\n",
MAX_BULK_BUFS * BULK_BUFFER_SIZE);
for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
BULK_BUFFER_SIZE, GFP_ATOMIC,
&s->dma_addr[s->buf_num]);
if (!s->buf_list[s->buf_num]) {
dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
__func__, s->buf_num);
dev_dbg(&s->udev->dev, "alloc buf=%d failed\n",
s->buf_num);
rtl2832_sdr_free_stream_bufs(s);
return -ENOMEM;
}
dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
__func__, s->buf_num,
s->buf_list[s->buf_num],
dev_dbg(&s->udev->dev, "alloc buf=%d %p (dma %llu)\n",
s->buf_num, s->buf_list[s->buf_num],
(long long)s->dma_addr[s->buf_num]);
s->flags |= USB_STATE_URB_BUF;
}
@ -527,8 +526,7 @@ static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
for (i = s->urbs_initialized - 1; i >= 0; i--) {
if (s->urb_list[i]) {
dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
__func__, i);
dev_dbg(&s->udev->dev, "free urb=%d\n", i);
/* free the URBs */
usb_free_urb(s->urb_list[i]);
}
@ -544,10 +542,10 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
/* allocate the URBs */
for (i = 0; i < MAX_BULK_BUFS; i++) {
dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
dev_dbg(&s->udev->dev, "alloc urb=%d\n", i);
s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
if (!s->urb_list[i]) {
dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
dev_dbg(&s->udev->dev, "failed\n");
for (j = 0; j < i; j++)
usb_free_urb(s->urb_list[j]);
return -ENOMEM;
@ -570,9 +568,9 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
/* Must be called with vb_queue_lock hold */
static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
{
unsigned long flags = 0;
unsigned long flags;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) {
@ -591,7 +589,7 @@ static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
{
struct rtl2832_sdr_state *s = fe->sec_priv;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
mutex_lock(&s->vb_queue_lock);
mutex_lock(&s->v4l2_lock);
@ -613,7 +611,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
@ -631,15 +629,15 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
dev_dbg(&s->udev->dev, "nbuffers=%d\n", *nbuffers);
/* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers;
*nplanes = 1;
sizes[0] = PAGE_ALIGN(s->buffersize);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]);
dev_dbg(&s->udev->dev, "nbuffers=%d sizes[0]=%d\n",
*nbuffers, sizes[0]);
return 0;
}
@ -659,7 +657,7 @@ static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
struct rtl2832_sdr_frame_buf *buf =
container_of(vb, struct rtl2832_sdr_frame_buf, vb);
unsigned long flags = 0;
unsigned long flags;
/* Check the device has not disconnected between prep and queuing */
if (!s->udev) {
@ -681,7 +679,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u64 u64tmp;
u32 u32tmp;
dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
dev_dbg(&s->udev->dev, "f_adc=%u\n", s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
return 0;
@ -715,8 +713,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u64tmp = -u64tmp;
u32tmp = u64tmp & 0x3fffff;
dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
__func__, f_if, u32tmp);
dev_dbg(&s->udev->dev, "f_if=%u if_ctl=%08x\n", f_if, u32tmp);
buf[0] = (u32tmp >> 16) & 0xff;
buf[1] = (u32tmp >> 8) & 0xff;
@ -903,7 +900,7 @@ static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
{
int ret;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
/* PID filter */
ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
@ -964,8 +961,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
c->frequency = s->f_tuner;
c->delivery_system = SYS_DVBT;
dev_dbg(&s->udev->dev, "%s: frequency=%u bandwidth=%d\n",
__func__, c->frequency, c->bandwidth_hz);
dev_dbg(&s->udev->dev, "frequency=%u bandwidth=%d\n",
c->frequency, c->bandwidth_hz);
if (!test_bit(POWER_ON, &s->flags))
return 0;
@ -980,7 +977,7 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
{
struct dvb_frontend *fe = s->fe;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
if (fe->ops.tuner_ops.init)
fe->ops.tuner_ops.init(fe);
@ -992,7 +989,7 @@ static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
{
struct dvb_frontend *fe = s->fe;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
if (fe->ops.tuner_ops.sleep)
fe->ops.tuner_ops.sleep(fe);
@ -1005,7 +1002,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
int ret;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
if (!s->udev)
return -ENODEV;
@ -1054,7 +1051,7 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
mutex_lock(&s->v4l2_lock);
@ -1088,8 +1085,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
__func__, v->index, v->type);
dev_dbg(&s->udev->dev, "index=%d type=%d\n", v->index, v->type);
if (v->index == 0) {
strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
@ -1115,7 +1111,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
if (v->index > 1)
return -EINVAL;
@ -1127,8 +1123,8 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
__func__, band->tuner, band->type, band->index);
dev_dbg(&s->udev->dev, "tuner=%d type=%d index=%d\n",
band->tuner, band->type, band->index);
if (band->tuner == 0) {
if (band->index >= ARRAY_SIZE(bands_adc))
@ -1153,8 +1149,8 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret = 0;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
__func__, f->tuner, f->type);
dev_dbg(&s->udev->dev, "tuner=%d type=%d\n",
f->tuner, f->type);
if (f->tuner == 0) {
f->frequency = s->f_adc;
@ -1175,8 +1171,8 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret, band;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
__func__, f->tuner, f->type, f->frequency);
dev_dbg(&s->udev->dev, "tuner=%d type=%d frequency=%u\n",
f->tuner, f->type, f->frequency);
/* ADC band midpoints */
#define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
@ -1194,15 +1190,13 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
bands_adc[band].rangelow,
bands_adc[band].rangehigh);
dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
__func__, s->f_adc);
dev_dbg(&s->udev->dev, "ADC frequency=%u Hz\n", s->f_adc);
ret = rtl2832_sdr_set_adc(s);
} else if (f->tuner == 1) {
s->f_tuner = clamp_t(unsigned int, f->frequency,
bands_fm[0].rangelow,
bands_fm[0].rangehigh);
dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
__func__, f->frequency);
dev_dbg(&s->udev->dev, "RF frequency=%u Hz\n", f->frequency);
ret = rtl2832_sdr_set_tuner_freq(s);
} else {
@ -1217,7 +1211,7 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
if (f->index >= s->num_formats)
return -EINVAL;
@ -1233,7 +1227,7 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
dev_dbg(&s->udev->dev, "\n");
f->fmt.sdr.pixelformat = s->pixelformat;
f->fmt.sdr.buffersize = s->buffersize;
@ -1250,7 +1244,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
struct vb2_queue *q = &s->vb_queue;
int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
(char *)&f->fmt.sdr.pixelformat);
if (vb2_is_busy(q))
@ -1280,7 +1274,7 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
(char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
@ -1354,8 +1348,8 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
int ret;
dev_dbg(&s->udev->dev,
"%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
__func__, ctrl->id, ctrl->name, ctrl->val,
"id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step);
switch (ctrl->id) {
@ -1432,7 +1426,7 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
s->num_formats = NUM_FORMATS;
if (rtl2832_sdr_emulated_fmt == false)
if (!rtl2832_sdr_emulated_fmt)
s->num_formats -= 1;
mutex_init(&s->v4l2_lock);

View File

@ -1,5 +1,5 @@
/*
Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
@ -44,9 +44,7 @@ struct si2165_state {
struct si2165_config config;
/* chip revision */
u8 revcode;
/* chip type */
u8 chip_revcode;
u8 chip_type;
/* calculated by xtal and div settings */
@ -312,7 +310,7 @@ static u32 si2165_get_fe_clk(struct si2165_state *state)
return state->adc_clk;
}
static bool si2165_wait_init_done(struct si2165_state *state)
static int si2165_wait_init_done(struct si2165_state *state)
{
int ret = -EINVAL;
u8 val = 0;
@ -407,7 +405,7 @@ static int si2165_upload_firmware(struct si2165_state *state)
int ret;
const struct firmware *fw = NULL;
u8 *fw_file = SI2165_FIRMWARE;
u8 *fw_file;
const u8 *data;
u32 len;
u32 offset;
@ -415,10 +413,20 @@ static int si2165_upload_firmware(struct si2165_state *state)
u8 block_count;
u16 crc_expected;
switch (state->chip_revcode) {
case 0x03: /* revision D */
fw_file = SI2165_FIRMWARE_REV_D;
break;
default:
dev_info(&state->i2c->dev, "%s: no firmware file for revision=%d\n",
KBUILD_MODNAME, state->chip_revcode);
return 0;
}
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
if (ret) {
dev_warn(&state->i2c->dev, "%s: firmare file '%s' not found\n",
dev_warn(&state->i2c->dev, "%s: firmware file '%s' not found\n",
KBUILD_MODNAME, fw_file);
goto error;
}
@ -908,7 +916,7 @@ static void si2165_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops si2165_ops = {
.info = {
.name = "Silicon Labs Si2165",
.name = "Silicon Labs ",
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
@ -948,6 +956,8 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
int n;
int io_ret;
u8 val;
char rev_char;
const char *chip_name;
if (config == NULL || i2c == NULL)
goto error;
@ -984,7 +994,7 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
if (val != state->config.chip_mode)
goto error;
io_ret = si2165_readreg8(state, 0x0023 , &state->revcode);
io_ret = si2165_readreg8(state, 0x0023, &state->chip_revcode);
if (io_ret < 0)
goto error;
@ -997,22 +1007,35 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
if (io_ret < 0)
goto error;
dev_info(&state->i2c->dev, "%s: hardware revision 0x%02x, chip type 0x%02x\n",
KBUILD_MODNAME, state->revcode, state->chip_type);
if (state->chip_revcode < 26)
rev_char = 'A' + state->chip_revcode;
else
rev_char = '?';
/* It is a guess that register 0x0118 (chip type?) can be used to
* differ between si2161, si2163 and si2165
* Only si2165 has been tested.
*/
if (state->revcode == 0x03 && state->chip_type == 0x07) {
switch (state->chip_type) {
case 0x06:
chip_name = "Si2161";
state->has_dvbt = true;
break;
case 0x07:
chip_name = "Si2165";
state->has_dvbt = true;
state->has_dvbc = true;
} else {
dev_err(&state->i2c->dev, "%s: Unsupported chip.\n",
KBUILD_MODNAME);
break;
default:
dev_err(&state->i2c->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n",
KBUILD_MODNAME, state->chip_type, state->chip_revcode);
goto error;
}
dev_info(&state->i2c->dev,
"%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n",
KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
state->chip_revcode);
strlcat(state->frontend.ops.info.name, chip_name,
sizeof(state->frontend.ops.info.name));
n = 0;
if (state->has_dvbt) {
state->frontend.ops.delsys[n++] = SYS_DVBT;
@ -1037,4 +1060,4 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(SI2165_FIRMWARE);
MODULE_FIRMWARE(SI2165_FIRMWARE_REV_D);

View File

@ -18,6 +18,6 @@
#ifndef _DVB_SI2165_PRIV
#define _DVB_SI2165_PRIV
#define SI2165_FIRMWARE "dvb-demod-si2165.fw"
#define SI2165_FIRMWARE_REV_D "dvb-demod-si2165.fw"
#endif /* _DVB_SI2165_PRIV */

View File

@ -55,8 +55,7 @@ static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
break;
}
dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
__func__,
dev_dbg(&s->client->dev, "cmd execution took %d ms\n",
jiffies_to_msecs(jiffies) -
(jiffies_to_msecs(timeout) - TIMEOUT));
@ -75,7 +74,7 @@ err_mutex_unlock:
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@ -150,12 +149,12 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
}
dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
__func__, *status, cmd.rlen, cmd.args);
dev_dbg(&s->client->dev, "status=%02x args=%*ph\n",
*status, cmd.rlen, cmd.args);
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@ -168,10 +167,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
u8 bandwidth, delivery_system;
dev_dbg(&s->client->dev,
"%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
__func__, c->delivery_system, c->modulation,
"delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u, stream_id=%d\n",
c->delivery_system, c->modulation,
c->frequency, c->bandwidth_hz, c->symbol_rate,
c->inversion);
c->inversion, c->stream_id);
if (!s->active) {
ret = -EAGAIN;
@ -235,6 +234,18 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
if (c->delivery_system == SYS_DVBT2) {
/* select PLP */
cmd.args[0] = 0x52;
cmd.args[1] = c->stream_id & 0xff;
cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1;
cmd.wlen = 3;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
}
memcpy(cmd.args, "\x51\x03", 2);
cmd.wlen = 2;
cmd.rlen = 12;
@ -297,13 +308,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
cmd.rlen = 4;
@ -343,7 +347,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@ -357,8 +361,9 @@ static int si2168_init(struct dvb_frontend *fe)
struct si2168_cmd cmd;
unsigned int chip_id;
dev_dbg(&s->client->dev, "%s:\n", __func__);
dev_dbg(&s->client->dev, "\n");
/* initialize */
memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
cmd.wlen = 13;
cmd.rlen = 0;
@ -366,6 +371,26 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
goto err;
if (s->fw_loaded) {
/* resume */
memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
cmd.wlen = 8;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x85", 1);
cmd.wlen = 1;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
goto warm;
}
/* power up */
memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
cmd.wlen = 8;
cmd.rlen = 1;
@ -400,16 +425,16 @@ static int si2168_init(struct dvb_frontend *fe)
break;
default:
dev_err(&s->client->dev,
"%s: unkown chip version Si21%d-%c%c%c\n",
KBUILD_MODNAME, cmd.args[2], cmd.args[1],
"unknown chip version Si21%d-%c%c%c\n",
cmd.args[2], cmd.args[1],
cmd.args[3], cmd.args[4]);
ret = -EINVAL;
goto err;
}
/* cold state - try to download firmware */
dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
KBUILD_MODNAME, si2168_ops.info.name);
dev_info(&s->client->dev, "found a '%s' in cold state\n",
si2168_ops.info.name);
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &s->client->dev);
@ -422,18 +447,18 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret == 0) {
dev_notice(&s->client->dev,
"%s: please install firmware file '%s'\n",
KBUILD_MODNAME, SI2168_B40_FIRMWARE);
"please install firmware file '%s'\n",
SI2168_B40_FIRMWARE);
} else {
dev_err(&s->client->dev,
"%s: firmware file '%s' not found\n",
KBUILD_MODNAME, fw_file);
"firmware file '%s' not found\n",
fw_file);
goto err;
}
}
dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
KBUILD_MODNAME, fw_file);
dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
fw_file);
for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
len = remaining;
@ -446,8 +471,8 @@ static int si2168_init(struct dvb_frontend *fe)
ret = si2168_cmd_execute(s, &cmd);
if (ret) {
dev_err(&s->client->dev,
"%s: firmware download failed=%d\n",
KBUILD_MODNAME, ret);
"firmware download failed=%d\n",
ret);
goto err;
}
}
@ -462,8 +487,20 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
goto err;
dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
KBUILD_MODNAME, si2168_ops.info.name);
/* set ts mode */
memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
cmd.args[4] |= s->ts_mode;
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
s->fw_loaded = true;
warm:
dev_info(&s->client->dev, "found a '%s' in warm state\n",
si2168_ops.info.name);
s->active = true;
@ -472,7 +509,7 @@ err:
if (fw)
release_firmware(fw);
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@ -482,7 +519,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
int ret;
struct si2168_cmd cmd;
dev_dbg(&s->client->dev, "%s:\n", __func__);
dev_dbg(&s->client->dev, "\n");
s->active = false;
@ -495,7 +532,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&s->client->dev, "failed=%d\n", ret);
return ret;
}
@ -528,8 +565,7 @@ static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
/* open tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
if (ret != 1) {
dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
KBUILD_MODNAME, ret);
dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
@ -553,8 +589,7 @@ static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
/* close tuner I2C gate */
ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
if (ret != 1) {
dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
KBUILD_MODNAME, ret);
dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
if (ret >= 0)
ret = -EREMOTEIO;
} else {
@ -587,7 +622,8 @@ static const struct dvb_frontend_ops si2168_ops = {
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
FE_CAN_2G_MODULATION
FE_CAN_2G_MODULATION |
FE_CAN_MULTISTREAM
},
.get_tune_settings = si2168_get_tune_settings,
@ -607,12 +643,12 @@ static int si2168_probe(struct i2c_client *client,
struct si2168 *s;
int ret;
dev_dbg(&client->dev, "%s:\n", __func__);
dev_dbg(&client->dev, "\n");
s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
@ -633,16 +669,17 @@ static int si2168_probe(struct i2c_client *client,
*config->i2c_adapter = s->adapter;
*config->fe = &s->fe;
s->ts_mode = config->ts_mode;
s->fw_loaded = false;
i2c_set_clientdata(client, s);
dev_info(&s->client->dev,
"%s: Silicon Labs Si2168 successfully attached\n",
KBUILD_MODNAME);
"Silicon Labs Si2168 successfully attached\n");
return 0;
err:
kfree(s);
dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
@ -650,7 +687,7 @@ static int si2168_remove(struct i2c_client *client)
{
struct si2168 *s = i2c_get_clientdata(client);
dev_dbg(&client->dev, "%s:\n", __func__);
dev_dbg(&client->dev, "\n");
i2c_del_mux_adapter(s->adapter);

View File

@ -34,6 +34,12 @@ struct si2168_config {
* returned by driver
*/
struct i2c_adapter **i2c_adapter;
/* TS mode */
u8 ts_mode;
};
#define SI2168_TS_PARALLEL 0x06
#define SI2168_TS_SERIAL 0x03
#endif

View File

@ -36,6 +36,8 @@ struct si2168 {
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
bool active;
bool fw_loaded;
u8 ts_mode;
};
/* firmare command struct */

View File

@ -236,6 +236,9 @@ static int si21_writeregs(struct si21xx_state *state, u8 reg1,
.len = len + 1
};
if (len > sizeof(buf) - 1)
return -EINVAL;
msg.buf[0] = reg1;
memcpy(msg.buf + 1, data, len);

View File

@ -0,0 +1,441 @@
/*
* CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
*
* Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
*
* Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
* DVB-S2 CI card (cimax2) with following copyrights:
*
* Copyright (C) 2009 NetUP Inc.
* Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
* Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
*
* 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 "sp2_priv.h"
static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
{
int ret;
struct i2c_client *client = s->client;
struct i2c_adapter *adap = client->adapter;
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.buf = &reg,
.len = 1
}, {
.addr = client->addr,
.flags = I2C_M_RD,
.buf = buf,
.len = len
}
};
ret = i2c_transfer(adap, msg, 2);
if (ret != 2) {
dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
reg, ret);
if (ret < 0)
return ret;
else
return -EIO;
}
dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
client->addr, reg, buf[0]);
return 0;
}
static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
{
int ret;
u8 buffer[35];
struct i2c_client *client = s->client;
struct i2c_adapter *adap = client->adapter;
struct i2c_msg msg = {
.addr = client->addr,
.flags = 0,
.buf = &buffer[0],
.len = len + 1
};
if ((len + 1) > sizeof(buffer)) {
dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
reg, len);
return -EINVAL;
}
buffer[0] = reg;
memcpy(&buffer[1], buf, len);
ret = i2c_transfer(adap, &msg, 1);
if (ret != 1) {
dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
reg, ret);
if (ret < 0)
return ret;
else
return -EIO;
}
return 0;
}
static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
u8 read, int addr, u8 data)
{
struct sp2 *s = en50221->data;
u8 store;
int mem, ret;
int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
slot, acs, addr, data);
if (slot != 0)
return -EINVAL;
/*
* change module access type between IO space and attribute memory
* when needed
*/
if (s->module_access_type != acs) {
ret = sp2_read_i2c(s, 0x00, &store, 1);
if (ret)
return ret;
store &= ~(SP2_MOD_CTL_ACS1 | SP2_MOD_CTL_ACS0);
store |= acs;
ret = sp2_write_i2c(s, 0x00, &store, 1);
if (ret)
return ret;
}
s->module_access_type = acs;
/* implementation of ci_op_cam is device specific */
if (ci_op_cam) {
ret = ci_op_cam(s->priv, read, addr, data, &mem);
} else {
dev_err(&s->client->dev, "callback not defined");
return -EINVAL;
}
if (ret)
return ret;
if (read) {
dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x",
addr, mem);
return mem;
} else {
return 0;
}
}
int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
int slot, int addr)
{
return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
SP2_CI_RD, addr, 0);
}
int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
int slot, int addr, u8 data)
{
return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
SP2_CI_WR, addr, data);
}
int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
int slot, u8 addr)
{
return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
SP2_CI_RD, addr, 0);
}
int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
int slot, u8 addr, u8 data)
{
return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
SP2_CI_WR, addr, data);
}
int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
{
struct sp2 *s = en50221->data;
u8 buf;
int ret;
dev_dbg(&s->client->dev, "slot: %d\n", slot);
if (slot != 0)
return -EINVAL;
/* RST on */
buf = SP2_MOD_CTL_RST;
ret = sp2_write_i2c(s, 0x00, &buf, 1);
if (ret)
return ret;
usleep_range(500, 600);
/* RST off */
buf = 0x00;
ret = sp2_write_i2c(s, 0x00, &buf, 1);
if (ret)
return ret;
msleep(1000);
return 0;
}
int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
{
struct sp2 *s = en50221->data;
dev_dbg(&s->client->dev, "slot:%d\n", slot);
/* not implemented */
return 0;
}
int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot)
{
struct sp2 *s = en50221->data;
u8 buf;
dev_dbg(&s->client->dev, "slot:%d\n", slot);
if (slot != 0)
return -EINVAL;
sp2_read_i2c(s, 0x00, &buf, 1);
/* disable bypass and enable TS */
buf |= (SP2_MOD_CTL_TSOEN | SP2_MOD_CTL_TSIEN);
return sp2_write_i2c(s, 0, &buf, 1);
}
int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
int slot, int open)
{
struct sp2 *s = en50221->data;
u8 buf[2];
int ret;
dev_dbg(&s->client->dev, "slot:%d open:%d\n", slot, open);
/*
* CAM module INSERT/REMOVE processing. Slow operation because of i2c
* transfers. Throttle read to one per sec.
*/
if (time_after(jiffies, s->next_status_checked_time)) {
ret = sp2_read_i2c(s, 0x00, buf, 1);
s->next_status_checked_time = jiffies + msecs_to_jiffies(1000);
if (ret)
return 0;
if (buf[0] & SP2_MOD_CTL_DET)
s->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
DVB_CA_EN50221_POLL_CAM_READY;
else
s->status = 0;
}
return s->status;
}
int sp2_init(struct sp2 *s)
{
int ret = 0;
u8 buf;
u8 cimax_init[34] = {
0x00, /* module A control*/
0x00, /* auto select mask high A */
0x00, /* auto select mask low A */
0x00, /* auto select pattern high A */
0x00, /* auto select pattern low A */
0x44, /* memory access time A, 600 ns */
0x00, /* invert input A */
0x00, /* RFU */
0x00, /* RFU */
0x00, /* module B control*/
0x00, /* auto select mask high B */
0x00, /* auto select mask low B */
0x00, /* auto select pattern high B */
0x00, /* auto select pattern low B */
0x44, /* memory access time B, 600 ns */
0x00, /* invert input B */
0x00, /* RFU */
0x00, /* RFU */
0x00, /* auto select mask high Ext */
0x00, /* auto select mask low Ext */
0x00, /* auto select pattern high Ext */
0x00, /* auto select pattern low Ext */
0x00, /* RFU */
0x02, /* destination - module A */
0x01, /* power control reg, VCC power on */
0x00, /* RFU */
0x00, /* int status read only */
0x00, /* Interrupt Mask Register */
0x05, /* EXTINT=active-high, INT=push-pull */
0x00, /* USCG1 */
0x04, /* ack active low */
0x00, /* LOCK = 0 */
0x22, /* unknown */
0x00, /* synchronization? */
};
dev_dbg(&s->client->dev, "\n");
s->ca.owner = THIS_MODULE;
s->ca.read_attribute_mem = sp2_ci_read_attribute_mem;
s->ca.write_attribute_mem = sp2_ci_write_attribute_mem;
s->ca.read_cam_control = sp2_ci_read_cam_control;
s->ca.write_cam_control = sp2_ci_write_cam_control;
s->ca.slot_reset = sp2_ci_slot_reset;
s->ca.slot_shutdown = sp2_ci_slot_shutdown;
s->ca.slot_ts_enable = sp2_ci_slot_ts_enable;
s->ca.poll_slot_status = sp2_ci_poll_slot_status;
s->ca.data = s;
s->module_access_type = 0;
/* initialize all regs */
ret = sp2_write_i2c(s, 0x00, &cimax_init[0], 34);
if (ret)
goto err;
/* lock registers */
buf = 1;
ret = sp2_write_i2c(s, 0x1f, &buf, 1);
if (ret)
goto err;
/* power on slots */
ret = sp2_write_i2c(s, 0x18, &buf, 1);
if (ret)
goto err;
ret = dvb_ca_en50221_init(s->dvb_adap, &s->ca, 0, 1);
if (ret)
goto err;
return 0;
err:
dev_dbg(&s->client->dev, "init failed=%d\n", ret);
return ret;
}
int sp2_exit(struct i2c_client *client)
{
struct sp2 *s;
dev_dbg(&client->dev, "\n");
if (client == NULL)
return 0;
s = i2c_get_clientdata(client);
if (s == NULL)
return 0;
if (s->ca.data == NULL)
return 0;
dvb_ca_en50221_release(&s->ca);
return 0;
}
static int sp2_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct sp2_config *cfg = client->dev.platform_data;
struct sp2 *s;
int ret;
dev_dbg(&client->dev, "\n");
s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
s->client = client;
s->dvb_adap = cfg->dvb_adap;
s->priv = cfg->priv;
s->ci_control = cfg->ci_control;
i2c_set_clientdata(client, s);
ret = sp2_init(s);
if (ret)
goto err;
dev_info(&s->client->dev, "CIMaX SP2 successfully attached\n");
return 0;
err:
dev_dbg(&client->dev, "init failed=%d\n", ret);
kfree(s);
return ret;
}
static int sp2_remove(struct i2c_client *client)
{
struct si2157 *s = i2c_get_clientdata(client);
dev_dbg(&client->dev, "\n");
sp2_exit(client);
if (s != NULL)
kfree(s);
return 0;
}
static const struct i2c_device_id sp2_id[] = {
{"sp2", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, sp2_id);
static struct i2c_driver sp2_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sp2",
},
.probe = sp2_probe,
.remove = sp2_remove,
.id_table = sp2_id,
};
module_i2c_driver(sp2_driver);
MODULE_DESCRIPTION("CIMaX SP2/HF CI driver");
MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,53 @@
/*
* CIMaX SP2/HF CI driver
*
* Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef SP2_H
#define SP2_H
#include <linux/kconfig.h>
#include "dvb_ca_en50221.h"
/*
* I2C address
* 0x40 (port 0)
* 0x41 (port 1)
*/
struct sp2_config {
/* dvb_adapter to attach the ci to */
struct dvb_adapter *dvb_adap;
/* function ci_control handles the device specific ci ops */
void *ci_control;
/* priv is passed back to function ci_control */
void *priv;
};
extern int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
int slot, int addr);
extern int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
int slot, int addr, u8 data);
extern int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
int slot, u8 addr);
extern int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
int slot, u8 addr, u8 data);
extern int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
extern int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
extern int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot);
extern int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
int slot, int open);
#endif

View File

@ -0,0 +1,50 @@
/*
* CIMaX SP2/HF CI driver
*
* Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef SP2_PRIV_H
#define SP2_PRIV_H
#include "sp2.h"
#include "dvb_frontend.h"
/* state struct */
struct sp2 {
int status;
struct i2c_client *client;
struct dvb_adapter *dvb_adap;
struct dvb_ca_en50221 ca;
int module_access_type;
unsigned long next_status_checked_time;
void *priv;
void *ci_control;
};
#define SP2_CI_ATTR_ACS 0x00
#define SP2_CI_IO_ACS 0x04
#define SP2_CI_WR 0
#define SP2_CI_RD 1
/* Module control register (0x00 module A, 0x09 module B) bits */
#define SP2_MOD_CTL_DET 0x01
#define SP2_MOD_CTL_AUTO 0x02
#define SP2_MOD_CTL_ACS0 0x04
#define SP2_MOD_CTL_ACS1 0x08
#define SP2_MOD_CTL_HAD 0x10
#define SP2_MOD_CTL_TSIEN 0x20
#define SP2_MOD_CTL_TSOEN 0x40
#define SP2_MOD_CTL_RST 0x80
#endif

View File

@ -394,8 +394,7 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
if (ret < 0)
return -EIO;
tmp = ret << 6;
tmp = ret << 6;
if (tmp >= 0x3FFF0)
tmp = ~0;

View File

@ -59,7 +59,6 @@ struct stv0367cab_state {
int locked; /* channel found */
u32 freq_khz; /* found frequency (in kHz) */
u32 symbol_rate; /* found symbol rate (in Bds) */
enum stv0367cab_mod modulation; /* modulation */
fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
};
@ -554,7 +553,7 @@ static struct st_register def0367ter[STV0367TER_NBREGS] = {
#define RF_LOOKUP_TABLE_SIZE 31
#define RF_LOOKUP_TABLE2_SIZE 16
/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
static const s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
{/*AGC1*/
48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
@ -566,7 +565,7 @@ s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
}
};
/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
{/*AGC2*/
28, 29, 31, 32, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45,
@ -1935,8 +1934,6 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct stv0367_state *state = fe->demodulator_priv;
struct stv0367ter_state *ter_state = state->ter_state;
int error = 0;
enum stv0367_ter_mode mode;
int constell = 0,/* snr = 0,*/ Data = 0;
@ -2020,7 +2017,7 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
return error;
return 0;
}
static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
@ -2999,7 +2996,6 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
if (QAMFEC_Lock) {
signalType = FE_CAB_DATAOK;
cab_state->modulation = p->modulation;
cab_state->spect_inv = stv0367_readbits(state,
F367CAB_QUAD_INV);
#if 0
@ -3165,7 +3161,7 @@ static int stv0367cab_get_frontend(struct dvb_frontend *fe)
case FE_CAB_MOD_QAM128:
p->modulation = QAM_128;
break;
case QAM_256:
case FE_CAB_MOD_QAM256:
p->modulation = QAM_256;
break;
default:

View File

@ -1270,7 +1270,6 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
enum fe_stv0900_demod_mode LDPC_Mode,
enum fe_stv0900_demod_num demod)
{
enum fe_stv0900_error error = STV0900_NO_ERROR;
s32 reg_ind;
dprintk("%s\n", __func__);
@ -1337,7 +1336,7 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
break;
}
return error;
return STV0900_NO_ERROR;
}
static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
@ -1555,8 +1554,6 @@ static int stv0900_status(struct stv0900_internal *intp,
static int stv0900_set_mis(struct stv0900_internal *intp,
enum fe_stv0900_demod_num demod, int mis)
{
enum fe_stv0900_error error = STV0900_NO_ERROR;
dprintk("%s\n", __func__);
if (mis < 0 || mis > 255) {
@ -1569,7 +1566,7 @@ static int stv0900_set_mis(struct stv0900_internal *intp,
stv0900_write_reg(intp, ISIBITENA, 0xff);
}
return error;
return STV0900_NO_ERROR;
}

View File

@ -1733,9 +1733,10 @@ static void stv0900_set_search_standard(struct stv0900_internal *intp,
break;
case STV0900_SEARCH_DSS:
dprintk("Search Standard = DSS\n");
case STV0900_SEARCH_DVBS2:
break;
case STV0900_SEARCH_DVBS2:
dprintk("Search Standard = DVBS2\n");
break;
case STV0900_AUTO_SEARCH:
default:
dprintk("Search Standard = AUTO\n");

View File

@ -0,0 +1,840 @@
/*
* Toshiba TC90522 Demodulator
*
* Copyright (C) 2014 Akihiro Tsukada <tskd08@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 version 2.
*
*
* 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.
*/
/*
* NOTICE:
* This driver is incomplete and lacks init/config of the chips,
* as the necessary info is not disclosed.
* It assumes that users of this driver (such as a PCI bridge of
* DTV receiver cards) properly init and configure the chip
* via I2C *before* calling this driver's init() function.
*
* Currently, PT3 driver is the only one that uses this driver,
* and contains init/config code in its firmware.
* Thus some part of the code might be dependent on PT3 specific config.
*/
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/dvb/frontend.h>
#include "dvb_math.h"
#include "tc90522.h"
#define TC90522_I2C_THRU_REG 0xfe
#define TC90522_MODULE_IDX(addr) (((u8)(addr) & 0x02U) >> 1)
struct tc90522_state {
struct tc90522_config cfg;
struct dvb_frontend fe;
struct i2c_client *i2c_client;
struct i2c_adapter tuner_i2c;
bool lna;
};
struct reg_val {
u8 reg;
u8 val;
};
static int
reg_write(struct tc90522_state *state, const struct reg_val *regs, int num)
{
int i, ret;
struct i2c_msg msg;
ret = 0;
msg.addr = state->i2c_client->addr;
msg.flags = 0;
msg.len = 2;
for (i = 0; i < num; i++) {
msg.buf = (u8 *)&regs[i];
ret = i2c_transfer(state->i2c_client->adapter, &msg, 1);
if (ret == 0)
ret = -EIO;
if (ret < 0)
return ret;
}
return 0;
}
static int reg_read(struct tc90522_state *state, u8 reg, u8 *val, u8 len)
{
struct i2c_msg msgs[2] = {
{
.addr = state->i2c_client->addr,
.flags = 0,
.buf = &reg,
.len = 1,
},
{
.addr = state->i2c_client->addr,
.flags = I2C_M_RD,
.buf = val,
.len = len,
},
};
int ret;
ret = i2c_transfer(state->i2c_client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret == ARRAY_SIZE(msgs))
ret = 0;
else if (ret >= 0)
ret = -EIO;
return ret;
}
static struct tc90522_state *cfg_to_state(struct tc90522_config *c)
{
return container_of(c, struct tc90522_state, cfg);
}
static int tc90522s_set_tsid(struct dvb_frontend *fe)
{
struct reg_val set_tsid[] = {
{ 0x8f, 00 },
{ 0x90, 00 }
};
set_tsid[0].val = (fe->dtv_property_cache.stream_id & 0xff00) >> 8;
set_tsid[1].val = fe->dtv_property_cache.stream_id & 0xff;
return reg_write(fe->demodulator_priv, set_tsid, ARRAY_SIZE(set_tsid));
}
static int tc90522t_set_layers(struct dvb_frontend *fe)
{
struct reg_val rv;
u8 laysel;
laysel = ~fe->dtv_property_cache.isdbt_layer_enabled & 0x07;
laysel = (laysel & 0x01) << 2 | (laysel & 0x02) | (laysel & 0x04) >> 2;
rv.reg = 0x71;
rv.val = laysel;
return reg_write(fe->demodulator_priv, &rv, 1);
}
/* frontend ops */
static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct tc90522_state *state;
int ret;
u8 reg;
state = fe->demodulator_priv;
ret = reg_read(state, 0xc3, &reg, 1);
if (ret < 0)
return ret;
*status = 0;
if (reg & 0x80) /* input level under min ? */
return 0;
*status |= FE_HAS_SIGNAL;
if (reg & 0x60) /* carrier? */
return 0;
*status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
if (reg & 0x10)
return 0;
if (reg_read(state, 0xc5, &reg, 1) < 0 || !(reg & 0x03))
return 0;
*status |= FE_HAS_LOCK;
return 0;
}
static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct tc90522_state *state;
int ret;
u8 reg;
state = fe->demodulator_priv;
ret = reg_read(state, 0x96, &reg, 1);
if (ret < 0)
return ret;
*status = 0;
if (reg & 0xe0) {
*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
| FE_HAS_SYNC | FE_HAS_LOCK;
return 0;
}
ret = reg_read(state, 0x80, &reg, 1);
if (ret < 0)
return ret;
if (reg & 0xf0)
return 0;
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
if (reg & 0x0c)
return 0;
*status |= FE_HAS_SYNC | FE_HAS_VITERBI;
if (reg & 0x02)
return 0;
*status |= FE_HAS_LOCK;
return 0;
}
static const fe_code_rate_t fec_conv_sat[] = {
FEC_NONE, /* unused */
FEC_1_2, /* for BPSK */
FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, /* for QPSK */
FEC_2_3, /* for 8PSK. (trellis code) */
};
static int tc90522s_get_frontend(struct dvb_frontend *fe)
{
struct tc90522_state *state;
struct dtv_frontend_properties *c;
struct dtv_fe_stats *stats;
int ret, i;
int layers;
u8 val[10];
u32 cndat;
state = fe->demodulator_priv;
c = &fe->dtv_property_cache;
c->delivery_system = SYS_ISDBS;
layers = 0;
ret = reg_read(state, 0xe8, val, 3);
if (ret == 0) {
int slots;
u8 v;
/* high/single layer */
v = (val[0] & 0x70) >> 4;
c->modulation = (v == 7) ? PSK_8 : QPSK;
c->fec_inner = fec_conv_sat[v];
c->layer[0].fec = c->fec_inner;
c->layer[0].modulation = c->modulation;
c->layer[0].segment_count = val[1] & 0x3f; /* slots */
/* low layer */
v = (val[0] & 0x07);
c->layer[1].fec = fec_conv_sat[v];
if (v == 0) /* no low layer */
c->layer[1].segment_count = 0;
else
c->layer[1].segment_count = val[2] & 0x3f; /* slots */
/* actually, BPSK if v==1, but not defined in fe_modulation_t */
c->layer[1].modulation = QPSK;
layers = (v > 0) ? 2 : 1;
slots = c->layer[0].segment_count + c->layer[1].segment_count;
c->symbol_rate = 28860000 * slots / 48;
}
/* statistics */
stats = &c->strength;
stats->len = 0;
/* let the connected tuner set RSSI property cache */
if (fe->ops.tuner_ops.get_rf_strength) {
u16 dummy;
fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
}
stats = &c->cnr;
stats->len = 1;
stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
cndat = 0;
ret = reg_read(state, 0xbc, val, 2);
if (ret == 0)
cndat = val[0] << 8 | val[1];
if (cndat >= 3000) {
u32 p, p4;
s64 cn;
cndat -= 3000; /* cndat: 4.12 fixed point float */
/*
* cnr[mdB] = -1634.6 * P^5 + 14341 * P^4 - 50259 * P^3
* + 88977 * P^2 - 89565 * P + 58857
* (P = sqrt(cndat) / 64)
*/
/* p := sqrt(cndat) << 8 = P << 14, 2.14 fixed point float */
/* cn = cnr << 3 */
p = int_sqrt(cndat << 16);
p4 = cndat * cndat;
cn = div64_s64(-16346LL * p4 * p, 10) >> 35;
cn += (14341LL * p4) >> 21;
cn -= (50259LL * cndat * p) >> 23;
cn += (88977LL * cndat) >> 9;
cn -= (89565LL * p) >> 11;
cn += 58857 << 3;
stats->stat[0].svalue = cn >> 3;
stats->stat[0].scale = FE_SCALE_DECIBEL;
}
/* per-layer post viterbi BER (or PER? config dependent?) */
stats = &c->post_bit_error;
memset(stats, 0, sizeof(*stats));
stats->len = layers;
ret = reg_read(state, 0xeb, val, 10);
if (ret < 0)
for (i = 0; i < layers; i++)
stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
else {
for (i = 0; i < layers; i++) {
stats->stat[i].scale = FE_SCALE_COUNTER;
stats->stat[i].uvalue = val[i * 5] << 16
| val[i * 5 + 1] << 8 | val[i * 5 + 2];
}
}
stats = &c->post_bit_count;
memset(stats, 0, sizeof(*stats));
stats->len = layers;
if (ret < 0)
for (i = 0; i < layers; i++)
stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
else {
for (i = 0; i < layers; i++) {
stats->stat[i].scale = FE_SCALE_COUNTER;
stats->stat[i].uvalue =
val[i * 5 + 3] << 8 | val[i * 5 + 4];
stats->stat[i].uvalue *= 204 * 8;
}
}
return 0;
}
static const fe_transmit_mode_t tm_conv[] = {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_4K,
TRANSMISSION_MODE_8K,
0
};
static const fe_code_rate_t fec_conv_ter[] = {
FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, 0, 0, 0
};
static const fe_modulation_t mod_conv[] = {
DQPSK, QPSK, QAM_16, QAM_64, 0, 0, 0, 0
};
static int tc90522t_get_frontend(struct dvb_frontend *fe)
{
struct tc90522_state *state;
struct dtv_frontend_properties *c;
struct dtv_fe_stats *stats;
int ret, i;
int layers;
u8 val[15], mode;
u32 cndat;
state = fe->demodulator_priv;
c = &fe->dtv_property_cache;
c->delivery_system = SYS_ISDBT;
c->bandwidth_hz = 6000000;
mode = 1;
ret = reg_read(state, 0xb0, val, 1);
if (ret == 0) {
mode = (val[0] & 0xc0) >> 2;
c->transmission_mode = tm_conv[mode];
c->guard_interval = (val[0] & 0x30) >> 4;
}
ret = reg_read(state, 0xb2, val, 6);
layers = 0;
if (ret == 0) {
u8 v;
c->isdbt_partial_reception = val[0] & 0x01;
c->isdbt_sb_mode = (val[0] & 0xc0) == 0x01;
/* layer A */
v = (val[2] & 0x78) >> 3;
if (v == 0x0f)
c->layer[0].segment_count = 0;
else {
layers++;
c->layer[0].segment_count = v;
c->layer[0].fec = fec_conv_ter[(val[1] & 0x1c) >> 2];
c->layer[0].modulation = mod_conv[(val[1] & 0xe0) >> 5];
v = (val[1] & 0x03) << 1 | (val[2] & 0x80) >> 7;
c->layer[0].interleaving = v;
}
/* layer B */
v = (val[3] & 0x03) << 1 | (val[4] & 0xc0) >> 6;
if (v == 0x0f)
c->layer[1].segment_count = 0;
else {
layers++;
c->layer[1].segment_count = v;
c->layer[1].fec = fec_conv_ter[(val[3] & 0xe0) >> 5];
c->layer[1].modulation = mod_conv[(val[2] & 0x07)];
c->layer[1].interleaving = (val[3] & 0x1c) >> 2;
}
/* layer C */
v = (val[5] & 0x1e) >> 1;
if (v == 0x0f)
c->layer[2].segment_count = 0;
else {
layers++;
c->layer[2].segment_count = v;
c->layer[2].fec = fec_conv_ter[(val[4] & 0x07)];
c->layer[2].modulation = mod_conv[(val[4] & 0x38) >> 3];
c->layer[2].interleaving = (val[5] & 0xe0) >> 5;
}
}
/* statistics */
stats = &c->strength;
stats->len = 0;
/* let the connected tuner set RSSI property cache */
if (fe->ops.tuner_ops.get_rf_strength) {
u16 dummy;
fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
}
stats = &c->cnr;
stats->len = 1;
stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
cndat = 0;
ret = reg_read(state, 0x8b, val, 3);
if (ret == 0)
cndat = val[0] << 16 | val[1] << 8 | val[2];
if (cndat != 0) {
u32 p, tmp;
s64 cn;
/*
* cnr[mdB] = 0.024 P^4 - 1.6 P^3 + 39.8 P^2 + 549.1 P + 3096.5
* (P = 10log10(5505024/cndat))
*/
/* cn = cnr << 3 (61.3 fixed point float */
/* p = 10log10(5505024/cndat) << 24 (8.24 fixed point float)*/
p = intlog10(5505024) - intlog10(cndat);
p *= 10;
cn = 24772;
cn += div64_s64(43827LL * p, 10) >> 24;
tmp = p >> 8;
cn += div64_s64(3184LL * tmp * tmp, 10) >> 32;
tmp = p >> 13;
cn -= div64_s64(128LL * tmp * tmp * tmp, 10) >> 33;
tmp = p >> 18;
cn += div64_s64(192LL * tmp * tmp * tmp * tmp, 1000) >> 24;
stats->stat[0].svalue = cn >> 3;
stats->stat[0].scale = FE_SCALE_DECIBEL;
}
/* per-layer post viterbi BER (or PER? config dependent?) */
stats = &c->post_bit_error;
memset(stats, 0, sizeof(*stats));
stats->len = layers;
ret = reg_read(state, 0x9d, val, 15);
if (ret < 0)
for (i = 0; i < layers; i++)
stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
else {
for (i = 0; i < layers; i++) {
stats->stat[i].scale = FE_SCALE_COUNTER;
stats->stat[i].uvalue = val[i * 3] << 16
| val[i * 3 + 1] << 8 | val[i * 3 + 2];
}
}
stats = &c->post_bit_count;
memset(stats, 0, sizeof(*stats));
stats->len = layers;
if (ret < 0)
for (i = 0; i < layers; i++)
stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
else {
for (i = 0; i < layers; i++) {
stats->stat[i].scale = FE_SCALE_COUNTER;
stats->stat[i].uvalue =
val[9 + i * 2] << 8 | val[9 + i * 2 + 1];
stats->stat[i].uvalue *= 204 * 8;
}
}
return 0;
}
static const struct reg_val reset_sat = { 0x03, 0x01 };
static const struct reg_val reset_ter = { 0x01, 0x40 };
static int tc90522_set_frontend(struct dvb_frontend *fe)
{
struct tc90522_state *state;
int ret;
state = fe->demodulator_priv;
if (fe->ops.tuner_ops.set_params)
ret = fe->ops.tuner_ops.set_params(fe);
else
ret = -ENODEV;
if (ret < 0)
goto failed;
if (fe->ops.delsys[0] == SYS_ISDBS) {
ret = tc90522s_set_tsid(fe);
if (ret < 0)
goto failed;
ret = reg_write(state, &reset_sat, 1);
} else {
ret = tc90522t_set_layers(fe);
if (ret < 0)
goto failed;
ret = reg_write(state, &reset_ter, 1);
}
if (ret < 0)
goto failed;
return 0;
failed:
dev_warn(&state->tuner_i2c.dev, "(%s) failed. [adap%d-fe%d]\n",
__func__, fe->dvb->num, fe->id);
return ret;
}
static int tc90522_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *settings)
{
if (fe->ops.delsys[0] == SYS_ISDBS) {
settings->min_delay_ms = 250;
settings->step_size = 1000;
settings->max_drift = settings->step_size * 2;
} else {
settings->min_delay_ms = 400;
settings->step_size = 142857;
settings->max_drift = settings->step_size;
}
return 0;
}
static int tc90522_set_if_agc(struct dvb_frontend *fe, bool on)
{
struct reg_val agc_sat[] = {
{ 0x0a, 0x00 },
{ 0x10, 0x30 },
{ 0x11, 0x00 },
{ 0x03, 0x01 },
};
struct reg_val agc_ter[] = {
{ 0x25, 0x00 },
{ 0x23, 0x4c },
{ 0x01, 0x40 },
};
struct tc90522_state *state;
struct reg_val *rv;
int num;
state = fe->demodulator_priv;
if (fe->ops.delsys[0] == SYS_ISDBS) {
agc_sat[0].val = on ? 0xff : 0x00;
agc_sat[1].val |= 0x80;
agc_sat[1].val |= on ? 0x01 : 0x00;
agc_sat[2].val |= on ? 0x40 : 0x00;
rv = agc_sat;
num = ARRAY_SIZE(agc_sat);
} else {
agc_ter[0].val = on ? 0x40 : 0x00;
agc_ter[1].val |= on ? 0x00 : 0x01;
rv = agc_ter;
num = ARRAY_SIZE(agc_ter);
}
return reg_write(state, rv, num);
}
static const struct reg_val sleep_sat = { 0x17, 0x01 };
static const struct reg_val sleep_ter = { 0x03, 0x90 };
static int tc90522_sleep(struct dvb_frontend *fe)
{
struct tc90522_state *state;
int ret;
state = fe->demodulator_priv;
if (fe->ops.delsys[0] == SYS_ISDBS)
ret = reg_write(state, &sleep_sat, 1);
else {
ret = reg_write(state, &sleep_ter, 1);
if (ret == 0 && fe->ops.set_lna &&
fe->dtv_property_cache.lna == LNA_AUTO) {
fe->dtv_property_cache.lna = 0;
ret = fe->ops.set_lna(fe);
fe->dtv_property_cache.lna = LNA_AUTO;
}
}
if (ret < 0)
dev_warn(&state->tuner_i2c.dev,
"(%s) failed. [adap%d-fe%d]\n",
__func__, fe->dvb->num, fe->id);
return ret;
}
static const struct reg_val wakeup_sat = { 0x17, 0x00 };
static const struct reg_val wakeup_ter = { 0x03, 0x80 };
static int tc90522_init(struct dvb_frontend *fe)
{
struct tc90522_state *state;
int ret;
/*
* Because the init sequence is not public,
* the parent device/driver should have init'ed the device before.
* just wake up the device here.
*/
state = fe->demodulator_priv;
if (fe->ops.delsys[0] == SYS_ISDBS)
ret = reg_write(state, &wakeup_sat, 1);
else {
ret = reg_write(state, &wakeup_ter, 1);
if (ret == 0 && fe->ops.set_lna &&
fe->dtv_property_cache.lna == LNA_AUTO) {
fe->dtv_property_cache.lna = 1;
ret = fe->ops.set_lna(fe);
fe->dtv_property_cache.lna = LNA_AUTO;
}
}
if (ret < 0) {
dev_warn(&state->tuner_i2c.dev,
"(%s) failed. [adap%d-fe%d]\n",
__func__, fe->dvb->num, fe->id);
return ret;
}
/* prefer 'all-layers' to 'none' as a default */
if (fe->dtv_property_cache.isdbt_layer_enabled == 0)
fe->dtv_property_cache.isdbt_layer_enabled = 7;
return tc90522_set_if_agc(fe, true);
}
/*
* tuner I2C adapter functions
*/
static int
tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct tc90522_state *state;
struct i2c_msg *new_msgs;
int i, j;
int ret, rd_num;
u8 wbuf[256];
u8 *p, *bufend;
if (num <= 0)
return -EINVAL;
rd_num = 0;
for (i = 0; i < num; i++)
if (msgs[i].flags & I2C_M_RD)
rd_num++;
new_msgs = kmalloc(sizeof(*new_msgs) * (num + rd_num), GFP_KERNEL);
if (!new_msgs)
return -ENOMEM;
state = i2c_get_adapdata(adap);
p = wbuf;
bufend = wbuf + sizeof(wbuf);
for (i = 0, j = 0; i < num; i++, j++) {
new_msgs[j].addr = state->i2c_client->addr;
new_msgs[j].flags = msgs[i].flags;
if (msgs[i].flags & I2C_M_RD) {
new_msgs[j].flags &= ~I2C_M_RD;
if (p + 2 > bufend)
break;
p[0] = TC90522_I2C_THRU_REG;
p[1] = msgs[i].addr << 1 | 0x01;
new_msgs[j].buf = p;
new_msgs[j].len = 2;
p += 2;
j++;
new_msgs[j].addr = state->i2c_client->addr;
new_msgs[j].flags = msgs[i].flags;
new_msgs[j].buf = msgs[i].buf;
new_msgs[j].len = msgs[i].len;
continue;
}
if (p + msgs[i].len + 2 > bufend)
break;
p[0] = TC90522_I2C_THRU_REG;
p[1] = msgs[i].addr << 1;
memcpy(p + 2, msgs[i].buf, msgs[i].len);
new_msgs[j].buf = p;
new_msgs[j].len = msgs[i].len + 2;
p += new_msgs[j].len;
}
if (i < num)
ret = -ENOMEM;
else
ret = i2c_transfer(state->i2c_client->adapter, new_msgs, j);
if (ret >= 0 && ret < j)
ret = -EIO;
kfree(new_msgs);
return (ret == j) ? num : ret;
}
static u32 tc90522_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C;
}
static const struct i2c_algorithm tc90522_tuner_i2c_algo = {
.master_xfer = &tc90522_master_xfer,
.functionality = &tc90522_functionality,
};
/*
* I2C driver functions
*/
static const struct dvb_frontend_ops tc90522_ops_sat = {
.delsys = { SYS_ISDBS },
.info = {
.name = "Toshiba TC90522 ISDB-S module",
.frequency_min = 950000,
.frequency_max = 2150000,
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
},
.init = tc90522_init,
.sleep = tc90522_sleep,
.set_frontend = tc90522_set_frontend,
.get_tune_settings = tc90522_get_tune_settings,
.get_frontend = tc90522s_get_frontend,
.read_status = tc90522s_read_status,
};
static const struct dvb_frontend_ops tc90522_ops_ter = {
.delsys = { SYS_ISDBT },
.info = {
.name = "Toshiba TC90522 ISDB-T module",
.frequency_min = 470000000,
.frequency_max = 770000000,
.frequency_stepsize = 142857,
.caps = FE_CAN_INVERSION_AUTO |
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_RECOVER |
FE_CAN_HIERARCHY_AUTO,
},
.init = tc90522_init,
.sleep = tc90522_sleep,
.set_frontend = tc90522_set_frontend,
.get_tune_settings = tc90522_get_tune_settings,
.get_frontend = tc90522t_get_frontend,
.read_status = tc90522t_read_status,
};
static int tc90522_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tc90522_state *state;
struct tc90522_config *cfg;
const struct dvb_frontend_ops *ops;
struct i2c_adapter *adap;
int ret;
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
state->i2c_client = client;
cfg = client->dev.platform_data;
memcpy(&state->cfg, cfg, sizeof(state->cfg));
cfg->fe = state->cfg.fe = &state->fe;
ops = id->driver_data == 0 ? &tc90522_ops_sat : &tc90522_ops_ter;
memcpy(&state->fe.ops, ops, sizeof(*ops));
state->fe.demodulator_priv = state;
adap = &state->tuner_i2c;
adap->owner = THIS_MODULE;
adap->algo = &tc90522_tuner_i2c_algo;
adap->dev.parent = &client->dev;
strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
i2c_set_adapdata(adap, state);
ret = i2c_add_adapter(adap);
if (ret < 0)
goto err;
cfg->tuner_i2c = state->cfg.tuner_i2c = adap;
i2c_set_clientdata(client, &state->cfg);
dev_info(&client->dev, "Toshiba TC90522 attached.\n");
return 0;
err:
kfree(state);
return ret;
}
static int tc90522_remove(struct i2c_client *client)
{
struct tc90522_state *state;
state = cfg_to_state(i2c_get_clientdata(client));
i2c_del_adapter(&state->tuner_i2c);
kfree(state);
return 0;
}
static const struct i2c_device_id tc90522_id[] = {
{ TC90522_I2C_DEV_SAT, 0 },
{ TC90522_I2C_DEV_TER, 1 },
{}
};
MODULE_DEVICE_TABLE(i2c, tc90522_id);
static struct i2c_driver tc90522_driver = {
.driver = {
.name = "tc90522",
},
.probe = tc90522_probe,
.remove = tc90522_remove,
.id_table = tc90522_id,
};
module_i2c_driver(tc90522_driver);
MODULE_DESCRIPTION("Toshiba TC90522 frontend");
MODULE_AUTHOR("Akihiro TSUKADA");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,42 @@
/*
* Toshiba TC90522 Demodulator
*
* Copyright (C) 2014 Akihiro Tsukada <tskd08@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 version 2.
*
*
* 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.
*/
/*
* The demod has 4 input (2xISDB-T and 2xISDB-S),
* and provides independent sub modules for each input.
* As the sub modules work in parallel and have the separate i2c addr's,
* this driver treats each sub module as one demod device.
*/
#ifndef TC90522_H
#define TC90522_H
#include <linux/i2c.h>
#include "dvb_frontend.h"
/* I2C device types */
#define TC90522_I2C_DEV_SAT "tc90522sat"
#define TC90522_I2C_DEV_TER "tc90522ter"
struct tc90522_config {
/* [OUT] frontend returned by driver */
struct dvb_frontend *fe;
/* [OUT] tuner I2C adapter returned by driver */
struct i2c_adapter *tuner_i2c;
};
#endif /* TC90522_H */

View File

@ -1037,7 +1037,7 @@ static int tda10071_init(struct dvb_frontend *fe)
ret = -EFAULT;
goto error;
} else {
priv->warm = 1;
priv->warm = true;
}
cmd.args[0] = CMD_GET_FW_VERSION;

View File

@ -111,7 +111,7 @@ static int zl10039_write(struct zl10039_state *state,
if (1 + count > sizeof(buf)) {
printk(KERN_WARNING
"%s: i2c wr reg=%04x: len=%zd is too big!\n",
"%s: i2c wr reg=%04x: len=%zu is too big!\n",
KBUILD_MODNAME, reg, count);
return -EINVAL;
}

View File

@ -1157,6 +1157,10 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
dev_err(fdtv->device,
"invalid pmt_cmd_id %d\n", pmt_cmd_id);
if (program_info_length > sizeof(c->operand) - 4 - write_pos) {
ret = -EINVAL;
goto out;
}
memcpy(&c->operand[write_pos], &msg[read_pos],
program_info_length);
@ -1180,6 +1184,12 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
dev_err(fdtv->device, "invalid pmt_cmd_id %d "
"at stream level\n", pmt_cmd_id);
if (es_info_length > sizeof(c->operand) - 4 -
write_pos) {
ret = -EINVAL;
goto out;
}
memcpy(&c->operand[write_pos], &msg[read_pos],
es_info_length);
read_pos += es_info_length;

View File

@ -13,7 +13,7 @@
* GNU General Public License for more details.
*/
#ifndef ADV7343_REG_H
#ifndef ADV7343_REGS_H
#define ADV7343_REGS_H
struct adv7343_std_info {

View File

@ -1593,7 +1593,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
bt->height += hdmi_read16(sd, 0x0b, 0xfff);
bt->il_vfrontporch = hdmi_read16(sd, 0x2c, 0x1fff) / 2;
bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2;
bt->vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
}
adv7604_fill_optional_dv_timings_fields(sd, timings);
} else {

View File

@ -1435,6 +1435,8 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
v4l2_dbg(1, debug, sd, "%s:\n", __func__);
memset(timings, 0, sizeof(struct v4l2_dv_timings));
/* SDP block */
if (state->mode == ADV7842_MODE_SDP)
return -ENODATA;
@ -1483,7 +1485,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
hdmi_read(sd, 0x2d)) / 2;
bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
hdmi_read(sd, 0x31)) / 2;
bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
bt->il_vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
hdmi_read(sd, 0x35)) / 2;
}
adv7842_fill_optional_dv_timings_fields(sd, timings);

View File

@ -224,7 +224,7 @@ static inline unsigned int lpf_count_to_us(unsigned int count)
}
/*
* FIFO register pulse width count compuations
* FIFO register pulse width count computations
*/
static u32 clock_divider_to_resolution(u16 divider)
{

View File

@ -100,14 +100,14 @@ static int lm3560_enable_ctrl(struct lm3560_flash *flash,
int rval;
if (led_no == LM3560_LED0) {
if (on == true)
if (on)
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x08, 0x08);
else
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x08, 0x00);
} else {
if (on == true)
if (on)
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x10, 0x10);
else

View File

@ -19,6 +19,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-image-sizes.h>
#include <media/ov7670.h>
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
@ -29,19 +30,6 @@ static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
/*
* Basic window sizes. These probably belong somewhere more globally
* useful.
*/
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define CIF_WIDTH 352
#define CIF_HEIGHT 288
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 144
/*
* The 7670 sits on i2c with ID 0x42
*/

View File

@ -816,7 +816,7 @@ static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
"error setting frame interval: %d\n", err);
state->error = -EINVAL;
}
};
}
v4l2_err(&state->sd, "cannot find correct frame interval\n");
state->error = -ERANGE;
}

View File

@ -660,7 +660,7 @@ static const struct v4l2_subdev_ops saa6752hs_ops = {
static int saa6752hs_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
struct saa6752hs_state *h;
struct v4l2_subdev *sd;
struct v4l2_ctrl_handler *hdl;
u8 addr = 0x13;
@ -668,6 +668,8 @@ static int saa6752hs_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
h = devm_kzalloc(&client->dev, sizeof(*h), GFP_KERNEL);
if (h == NULL)
return -ENOMEM;
sd = &h->sd;
@ -752,7 +754,6 @@ static int saa6752hs_probe(struct i2c_client *client,
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
kfree(h);
return err;
}
v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
@ -767,7 +768,6 @@ static int saa6752hs_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&to_state(sd)->hdl);
kfree(to_state(sd));
return 0;
}

View File

@ -31,8 +31,9 @@
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/smiapp.h>
#include <linux/v4l2-mediabus.h>
#include <media/v4l2-device.h>
@ -297,8 +298,9 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
if (rval < 0)
return rval;
*sensor->pixel_rate_parray->p_cur.p_s64 = pll->vt_pix_clk_freq_hz;
*sensor->pixel_rate_csi->p_cur.p_s64 = pll->pixel_rate_csi;
__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray,
pll->vt_pix_clk_freq_hz);
__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi);
return 0;
}
@ -319,13 +321,7 @@ static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
+ sensor->vblank->val
- sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
ctrl->maximum = max;
if (ctrl->default_value > max)
ctrl->default_value = max;
if (ctrl->val > max)
ctrl->val = max;
if (ctrl->cur.val > max)
ctrl->cur.val = max;
__v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);
}
/*
@ -404,6 +400,14 @@ static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
pixel_order_str[pixel_order]);
}
static const char * const smiapp_test_patterns[] = {
"Disabled",
"Solid Colour",
"Eight Vertical Colour Bars",
"Colour Bars With Fade to Grey",
"Pseudorandom Sequence (PN9)",
};
static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct smiapp_sensor *sensor =
@ -477,6 +481,39 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
return smiapp_pll_update(sensor);
case V4L2_CID_TEST_PATTERN: {
unsigned int i;
for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
v4l2_ctrl_activate(
sensor->test_data[i],
ctrl->val ==
V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
}
case V4L2_CID_TEST_PATTERN_RED:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
case V4L2_CID_TEST_PATTERN_GREENR:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
case V4L2_CID_TEST_PATTERN_BLUE:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
case V4L2_CID_TEST_PATTERN_GREENB:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
case V4L2_CID_PIXEL_RATE:
/* For v4l2_ctrl_s_ctrl_int64() used internally. */
return 0;
default:
return -EINVAL;
}
@ -489,10 +526,10 @@ static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
static int smiapp_init_controls(struct smiapp_sensor *sensor)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
unsigned int max;
unsigned int max, i;
int rval;
rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7);
rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 12);
if (rval)
return rval;
sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
@ -535,6 +572,20 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
&sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
v4l2_ctrl_new_std_menu_items(&sensor->pixel_array->ctrl_handler,
&smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN,
ARRAY_SIZE(smiapp_test_patterns) - 1,
0, 0, smiapp_test_patterns);
for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) {
int max_value = (1 << sensor->csi_format->width) - 1;
sensor->test_data[i] =
v4l2_ctrl_new_std(
&sensor->pixel_array->ctrl_handler,
&smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN_RED + i,
0, max_value, 1, max_value);
}
if (sensor->pixel_array->ctrl_handler.error) {
dev_err(&client->dev,
"pixel array controls initialization failed (%d)\n",
@ -782,36 +833,25 @@ static void smiapp_update_blanking(struct smiapp_sensor *sensor)
{
struct v4l2_ctrl *vblank = sensor->vblank;
struct v4l2_ctrl *hblank = sensor->hblank;
int min, max;
vblank->minimum =
max_t(int,
sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
vblank->maximum =
sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
min = max_t(int,
sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
max = sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
vblank->val = clamp_t(int, vblank->val,
vblank->minimum, vblank->maximum);
vblank->default_value = vblank->minimum;
vblank->val = vblank->val;
vblank->cur.val = vblank->val;
__v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min);
hblank->minimum =
max_t(int,
sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
hblank->maximum =
sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
min = max_t(int,
sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
max = sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
hblank->val = clamp_t(int, hblank->val,
hblank->minimum, hblank->maximum);
hblank->default_value = hblank->minimum;
hblank->val = hblank->val;
hblank->cur.val = hblank->val;
__v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min);
__smiapp_update_exposure_limits(sensor);
}
@ -1272,7 +1312,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
regulator_disable(sensor->vana);
sensor->streaming = 0;
sensor->streaming = false;
}
static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
@ -1462,13 +1502,13 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
return 0;
if (enable) {
sensor->streaming = 1;
sensor->streaming = true;
rval = smiapp_start_streaming(sensor);
if (rval < 0)
sensor->streaming = 0;
sensor->streaming = false;
} else {
rval = smiapp_stop_streaming(sensor);
sensor->streaming = 0;
sensor->streaming = false;
}
return rval;
@ -1664,17 +1704,34 @@ static int smiapp_set_format(struct v4l2_subdev *subdev,
if (fmt->pad == ssd->source_pad) {
u32 code = fmt->format.code;
int rval = __smiapp_get_format(subdev, fh, fmt);
bool range_changed = false;
unsigned int i;
if (!rval && subdev == &sensor->src->sd) {
const struct smiapp_csi_data_format *csi_format =
smiapp_validate_csi_data_format(sensor, code);
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
if (csi_format->width !=
sensor->csi_format->width)
range_changed = true;
sensor->csi_format = csi_format;
}
fmt->format.code = csi_format->code;
}
mutex_unlock(&sensor->mutex);
return rval;
if (rval || !range_changed)
return rval;
for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
v4l2_ctrl_modify_range(
sensor->test_data[i],
0, (1 << sensor->csi_format->width) - 1, 1, 0);
return 0;
}
/* Sink pad. Width and height are changeable here. */

View File

@ -54,6 +54,8 @@
(1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \
+ (clk) / 1000 - 1) / ((clk) / 1000))
#define SMIAPP_COLOUR_COMPONENTS 4
#include "smiapp-limits.h"
struct smiapp_quirk;
@ -241,6 +243,8 @@ struct smiapp_sensor {
/* src controls */
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate_csi;
/* test pattern colour components */
struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS];
};
#define to_smiapp_subdev(_sd) \

View File

@ -29,6 +29,7 @@
#include <media/soc_camera.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-image-sizes.h>
/* you can check PLL/clock info */
/* #define EXT_CLOCK 24000000 */
@ -42,9 +43,6 @@
#define MAX_WIDTH 2048
#define MAX_HEIGHT 1536
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
/*
* macro of read/write
*/

View File

@ -29,6 +29,7 @@
#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-image-sizes.h>
/*
* register offset
@ -360,10 +361,6 @@
#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define OV772X_MAX_WIDTH VGA_WIDTH
#define OV772X_MAX_HEIGHT VGA_HEIGHT

View File

@ -564,13 +564,13 @@ static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
u32 y_start;
u32 x_end;
u32 y_end;
bool scaling = 0;
bool scaling = false;
u32 scale_input_x;
u32 scale_input_y;
int ret;
if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
scaling = 1;
scaling = true;
/*
* Try to use as much of the sensor area as possible when supporting

View File

@ -293,7 +293,7 @@ static int tda7432_s_ctrl(struct v4l2_ctrl *ctrl)
if (t->mute->val) {
lf |= TDA7432_MUTE;
lr |= TDA7432_MUTE;
lf |= TDA7432_MUTE;
rf |= TDA7432_MUTE;
rr |= TDA7432_MUTE;
}
/* Mute & update balance*/

View File

@ -775,25 +775,20 @@ static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
{
struct tvp7002 *device = to_tvp7002(sd);
int error = 0;
int error;
if (device->streaming == enable)
return 0;
if (enable) {
/* Set output state on (low impedance means stream on) */
error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
device->streaming = enable;
} else {
/* Set output state off (high impedance means stream off) */
error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
if (error)
v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
device->streaming = enable;
/* low impedance: on, high impedance: off */
error = tvp7002_write(sd, TVP7002_MISC_CTL_2, enable ? 0x00 : 0x03);
if (error) {
v4l2_dbg(1, debug, sd, "Fail to set streaming\n");
return error;
}
return error;
device->streaming = enable;
return 0;
}
/*

View File

@ -30,22 +30,10 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-image-sizes.h>
#include "vs6624_regs.h"
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define QQVGA_WIDTH 160
#define QQVGA_HEIGHT 120
#define CIF_WIDTH 352
#define CIF_HEIGHT 288
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 144
#define QQCIF_WIDTH 88
#define QQCIF_HEIGHT 72
#define MAX_FRAME_RATE 30
struct vs6624 {

View File

@ -103,10 +103,8 @@ static long media_device_enum_entities(struct media_device *mdev,
return -EINVAL;
u_ent.id = ent->id;
if (ent->name) {
strncpy(u_ent.name, ent->name, sizeof(u_ent.name));
u_ent.name[sizeof(u_ent.name) - 1] = '\0';
}
if (ent->name)
strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
u_ent.type = ent->type;
u_ent.revision = ent->revision;
u_ent.flags = ent->flags;

View File

@ -192,7 +192,6 @@ static int media_open(struct inode *inode, struct file *filp)
static int media_release(struct inode *inode, struct file *filp)
{
struct media_devnode *mdev = media_devnode_data(filp);
int ret = 0;
if (mdev->fops->release)
mdev->fops->release(filp);
@ -201,7 +200,7 @@ static int media_release(struct inode *inode, struct file *filp)
return value is ignored. */
put_device(&mdev->dev);
filp->private_data = NULL;
return ret;
return 0;
}
static const struct file_operations media_devnode_fops = {

View File

@ -629,11 +629,15 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
{
int y;
int dw = 2 * dev->width;
char tmp[dw + 32]; /* using a temp buffer is faster than direct */
char *tmp; /* using a temp buffer is faster than direct */
int cnt = 0;
int len = 0;
unsigned char r8 = 0x5; /* value for reg8 */
tmp = kmalloc(dw + 32, GFP_KERNEL);
if (!tmp)
return 0;
if (rgb555)
r8 |= 0x20; /* else use untranslated rgb = 565 */
mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
@ -664,6 +668,7 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
len += dt;
}
}
kfree(tmp);
return len;
}

View File

@ -20,6 +20,7 @@ source "drivers/media/pci/ivtv/Kconfig"
source "drivers/media/pci/zoran/Kconfig"
source "drivers/media/pci/saa7146/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw68/Kconfig"
endif
if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
@ -41,6 +42,7 @@ source "drivers/media/pci/b2c2/Kconfig"
source "drivers/media/pci/pluto2/Kconfig"
source "drivers/media/pci/dm1105/Kconfig"
source "drivers/media/pci/pt1/Kconfig"
source "drivers/media/pci/pt3/Kconfig"
source "drivers/media/pci/mantis/Kconfig"
source "drivers/media/pci/ngene/Kconfig"
source "drivers/media/pci/ddbridge/Kconfig"

View File

@ -7,10 +7,10 @@ obj-y += ttpci/ \
pluto2/ \
dm1105/ \
pt1/ \
pt3/ \
mantis/ \
ngene/ \
ddbridge/ \
b2c2/ \
saa7146/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
@ -22,6 +22,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
obj-$(CONFIG_VIDEO_TW68) += tw68/
obj-$(CONFIG_VIDEO_MEYE) += meye/
obj-$(CONFIG_STA2X11_VIP) += sta2x11/
obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/

View File

@ -1531,7 +1531,6 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
{
struct bttv_buffer *old;
unsigned long flags;
int retval = 0;
dprintk("switch_overlay: enter [new=%p]\n", new);
if (new)
@ -1551,7 +1550,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
if (NULL == new)
free_btres_lock(btv,fh,RESOURCE_OVERLAY);
dprintk("switch_overlay: done\n");
return retval;
return 0;
}
/* ----------------------------------------------------------------------- */
@ -3856,7 +3855,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
BT848_INT_MASK);
};
}
bttv_print_irqbits(stat,astat);

View File

@ -674,11 +674,9 @@ static int dst_ca_release(struct inode *inode, struct file *file)
static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
ssize_t bytes_read = 0;
dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
return bytes_read;
return 0;
}
static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)

View File

@ -80,7 +80,7 @@ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
int period_elapsed = 0;
int length;
dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zu\n", cxsc,
pcm_data, num_bytes);
substream = cxsc->capture_pcm_substream;

View File

@ -130,7 +130,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
}
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
CX18_INFO("loaded %s firmware (%zu bytes)\n", fn, fw->size);
size = fw->size;
release_firmware(fw);
cx18_setup_page(cx, SCB_OFFSET);
@ -164,7 +164,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
while (offset + sizeof(seghdr) < fw->size) {
const u32 *shptr = src + offset / 4;
const __le32 *shptr = (__force __le32 *)src + offset / 4;
seghdr.sync1 = le32_to_cpu(shptr[0]);
seghdr.sync2 = le32_to_cpu(shptr[1]);
@ -202,7 +202,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
offset += seghdr.size;
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
CX18_INFO("loaded %s firmware V%08x (%zu bytes)\n",
fn, apu_version, fw->size);
size = fw->size;
release_firmware(fw);

View File

@ -364,7 +364,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
((char __iomem *)cx->scb->cpu_mdl));
CX18_ERR("Too many buffers, cannot fit in SCB area\n");
CX18_ERR("Max buffers = %zd\n",
CX18_ERR("Max buffers = %zu\n",
bufsz / sizeof(struct cx18_mdl_ent));
return -ENOMEM;
}

View File

@ -3,12 +3,11 @@ config VIDEO_CX23885
depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
select SND_PCM
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEO_TUNER
select VIDEO_TVEEPROM
depends on RC_CORE
select VIDEOBUF_DVB
select VIDEOBUF_DMA_SG
select VIDEOBUF2_DVB
select VIDEOBUF2_DMA_SG
select VIDEO_CX25840
select VIDEO_CX2341X
select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
@ -32,12 +31,16 @@ config VIDEO_CX23885
select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Conexant 23885 based

View File

@ -8,7 +8,6 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
ccflags-y += -Idrivers/media/i2c
ccflags-y += -Idrivers/media/common
ccflags-y += -Idrivers/media/tuners
ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends

View File

@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
@ -52,8 +48,8 @@
* | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
#include <dvb_demux.h>
#include <dvb_frontend.h>
#include "altera-ci.h"
#include "dvb_ca_en50221.h"

View File

@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ALTERA_CI_H
#define __ALTERA_CI_H

View File

@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "cx23885.h"

View File

@ -17,10 +17,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef CIMAX2_H

View File

@ -18,10 +18,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
@ -865,6 +861,11 @@ static int cx23885_api_cmd(struct cx23885_dev *dev,
return err;
}
static int cx23885_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
{
return cx23885_mbox_func(priv, cmd, in, out, data);
}
static int cx23885_find_mailbox(struct cx23885_dev *dev)
{
u32 signature[4] = {
@ -941,7 +942,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
printk(KERN_ERR "ERROR: Firmware size mismatch "
"(have %zd, expected %d)\n",
"(have %zu, expected %d)\n",
firmware->size, CX23885_FIRM_IMAGE_SIZE);
release_firmware(firmware);
return -1;
@ -1033,12 +1034,12 @@ static void cx23885_codec_settings(struct cx23885_dev *dev)
cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
dev->ts1.height, dev->ts1.width);
dev->mpeg_params.width = dev->ts1.width;
dev->mpeg_params.height = dev->ts1.height;
dev->mpeg_params.is_50hz =
dev->cxhdl.width = dev->ts1.width;
dev->cxhdl.height = dev->ts1.height;
dev->cxhdl.is_50hz =
(dev->encodernorm.id & V4L2_STD_625_50) != 0;
cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);
cx2341x_handler_setup(&dev->cxhdl);
cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
@ -1137,85 +1138,107 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
/* ------------------------------------------------------------------ */
static int bb_buf_setup(struct videobuf_queue *q,
unsigned int *count, unsigned int *size)
static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
unsigned int *num_buffers, unsigned int *num_planes,
unsigned int sizes[], void *alloc_ctxs[])
{
struct cx23885_fh *fh = q->priv_data;
fh->dev->ts1.ts_packet_size = mpeglinesize;
fh->dev->ts1.ts_packet_count = mpeglines;
*size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
*count = mpegbufs;
struct cx23885_dev *dev = q->drv_priv;
dev->ts1.ts_packet_size = mpeglinesize;
dev->ts1.ts_packet_count = mpeglines;
*num_planes = 1;
sizes[0] = mpeglinesize * mpeglines;
*num_buffers = mpegbufs;
return 0;
}
static int bb_buf_prepare(struct videobuf_queue *q,
struct videobuf_buffer *vb, enum v4l2_field field)
static int buffer_prepare(struct vb2_buffer *vb)
{
struct cx23885_fh *fh = q->priv_data;
return cx23885_buf_prepare(q, &fh->dev->ts1,
(struct cx23885_buffer *)vb,
field);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf =
container_of(vb, struct cx23885_buffer, vb);
return cx23885_buf_prepare(buf, &dev->ts1);
}
static void bb_buf_queue(struct videobuf_queue *q,
struct videobuf_buffer *vb)
static void buffer_finish(struct vb2_buffer *vb)
{
struct cx23885_fh *fh = q->priv_data;
cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf = container_of(vb,
struct cx23885_buffer, vb);
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
cx23885_free_buffer(dev, buf);
dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
}
static void bb_buf_release(struct videobuf_queue *q,
struct videobuf_buffer *vb)
static void buffer_queue(struct vb2_buffer *vb)
{
cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
struct cx23885_buffer *buf = container_of(vb,
struct cx23885_buffer, vb);
cx23885_buf_queue(&dev->ts1, buf);
}
static struct videobuf_queue_ops cx23885_qops = {
.buf_setup = bb_buf_setup,
.buf_prepare = bb_buf_prepare,
.buf_queue = bb_buf_queue,
.buf_release = bb_buf_release,
static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct cx23885_dev *dev = q->drv_priv;
struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
unsigned long flags;
int ret;
ret = cx23885_initialize_codec(dev, 1);
if (ret == 0) {
struct cx23885_buffer *buf = list_entry(dmaq->active.next,
struct cx23885_buffer, queue);
cx23885_start_dma(&dev->ts1, dmaq, buf);
return 0;
}
spin_lock_irqsave(&dev->slock, flags);
while (!list_empty(&dmaq->active)) {
struct cx23885_buffer *buf = list_entry(dmaq->active.next,
struct cx23885_buffer, queue);
list_del(&buf->queue);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
}
spin_unlock_irqrestore(&dev->slock, flags);
return ret;
}
static void cx23885_stop_streaming(struct vb2_queue *q)
{
struct cx23885_dev *dev = q->drv_priv;
/* stop mpeg capture */
cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
CX23885_END_NOW, CX23885_MPEG_CAPTURE,
CX23885_RAW_BITS_NONE);
msleep(500);
cx23885_417_check_encoder(dev);
cx23885_cancel_buffers(&dev->ts1);
}
static struct vb2_ops cx23885_qops = {
.queue_setup = queue_setup,
.buf_prepare = buffer_prepare,
.buf_finish = buffer_finish,
.buf_queue = buffer_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
.start_streaming = cx23885_start_streaming,
.stop_streaming = cx23885_stop_streaming,
};
/* ------------------------------------------------------------------ */
static const u32 *ctrl_classes[] = {
cx2341x_mpeg_ctrls,
NULL
};
static int cx23885_queryctrl(struct cx23885_dev *dev,
struct v4l2_queryctrl *qctrl)
{
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
/* MPEG V4L2 controls */
if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
}
static int cx23885_querymenu(struct cx23885_dev *dev,
struct v4l2_querymenu *qmenu)
{
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
cx23885_queryctrl(dev, &qctrl);
return v4l2_ctrl_query_menu(qmenu, &qctrl,
cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
}
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
*id = dev->tvnorm;
return 0;
@ -1223,29 +1246,26 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
unsigned int i;
int ret;
for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
if (id & cx23885_tvnorms[i].id)
break;
if (i == ARRAY_SIZE(cx23885_tvnorms))
return -EINVAL;
dev->encodernorm = cx23885_tvnorms[i];
/* Have the drier core notify the subdevices */
mutex_lock(&dev->lock);
cx23885_set_tvnorm(dev, id);
mutex_unlock(&dev->lock);
return 0;
ret = cx23885_set_tvnorm(dev, id);
if (!ret)
dev->encodernorm = cx23885_tvnorms[i];
return ret;
}
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
struct cx23885_dev *dev = video_drvdata(file);
dprintk(1, "%s()\n", __func__);
return cx23885_enum_input(dev, i);
}
@ -1263,8 +1283,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *t)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@ -1281,8 +1300,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@ -1296,8 +1314,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
@ -1315,27 +1332,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return cx23885_set_frequency(file, priv, f);
}
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctl)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
return cx23885_get_control(dev, ctl);
}
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctl)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
return cx23885_set_control(dev, ctl);
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
struct cx23885_tsport *tsport = &dev->ts1;
strlcpy(cap->driver, dev->name, sizeof(cap->driver));
@ -1368,8 +1368,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
@ -1378,285 +1377,63 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.colorspace = 0;
f->fmt.pix.width = dev->ts1.width;
f->fmt.pix.height = dev->ts1.height;
f->fmt.pix.field = fh->mpegq.field;
dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
dev->ts1.width, dev->ts1.height, fh->mpegq.field);
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
dev->ts1.width, dev->ts1.height);
return 0;
}
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
f->fmt.pix.colorspace = 0;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->ts1.width, dev->ts1.height, fh->mpegq.field);
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
dev->ts1.width, dev->ts1.height);
return 0;
}
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
f->fmt.pix.colorspace = 0;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
return 0;
}
static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
struct cx23885_fh *fh = file->private_data;
return videobuf_reqbufs(&fh->mpegq, p);
}
static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *p)
{
struct cx23885_fh *fh = file->private_data;
return videobuf_querybuf(&fh->mpegq, p);
}
static int vidioc_qbuf(struct file *file, void *priv,
struct v4l2_buffer *p)
{
struct cx23885_fh *fh = file->private_data;
return videobuf_qbuf(&fh->mpegq, p);
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
struct cx23885_fh *fh = priv;
return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
}
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type i)
{
struct cx23885_fh *fh = file->private_data;
return videobuf_streamon(&fh->mpegq);
}
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct cx23885_fh *fh = file->private_data;
return videobuf_streamoff(&fh->mpegq);
}
static int vidioc_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *f)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
}
static int vidioc_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *f)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
struct cx2341x_mpeg_params p;
int err;
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
p = dev->mpeg_params;
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
if (err == 0) {
err = cx2341x_update(dev, cx23885_mbox_func,
&dev->mpeg_params, &p);
dev->mpeg_params = p;
}
return err;
}
static int vidioc_try_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *f)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
struct cx2341x_mpeg_params p;
int err;
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
p = dev->mpeg_params;
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
return err;
}
static int vidioc_log_status(struct file *file, void *priv)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
struct cx23885_dev *dev = video_drvdata(file);
char name[32 + 2];
snprintf(name, sizeof(name), "%s/2", dev->name);
printk(KERN_INFO
"%s/2: ============ START LOG STATUS ============\n",
dev->name);
call_all(dev, core, log_status);
cx2341x_log_status(&dev->mpeg_params, name);
printk(KERN_INFO
"%s/2: ============= END LOG STATUS =============\n",
dev->name);
v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
return 0;
}
static int vidioc_querymenu(struct file *file, void *priv,
struct v4l2_querymenu *a)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
return cx23885_querymenu(dev, a);
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
return cx23885_queryctrl(dev, c);
}
static int mpeg_open(struct file *file)
{
struct cx23885_dev *dev = video_drvdata(file);
struct cx23885_fh *fh;
dprintk(2, "%s()\n", __func__);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (!fh)
return -ENOMEM;
file->private_data = fh;
fh->dev = dev;
videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
&dev->pci->dev, &dev->ts1.slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct cx23885_buffer),
fh, NULL);
return 0;
}
static int mpeg_release(struct file *file)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
dprintk(2, "%s()\n", __func__);
/* FIXME: Review this crap */
/* Shut device down on last close */
if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
/* stop mpeg capture */
cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
CX23885_END_NOW, CX23885_MPEG_CAPTURE,
CX23885_RAW_BITS_NONE);
msleep(500);
cx23885_417_check_encoder(dev);
cx23885_cancel_buffers(&fh->dev->ts1);
}
}
if (fh->mpegq.streaming)
videobuf_streamoff(&fh->mpegq);
if (fh->mpegq.reading)
videobuf_read_stop(&fh->mpegq);
videobuf_mmap_free(&fh->mpegq);
file->private_data = NULL;
kfree(fh);
return 0;
}
static ssize_t mpeg_read(struct file *file, char __user *data,
size_t count, loff_t *ppos)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
dprintk(2, "%s()\n", __func__);
/* Deal w/ A/V decoder * and mpeg encoder sync issues. */
/* Start mpeg encoder on first read. */
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
if (cx23885_initialize_codec(dev, 1) < 0)
return -EINVAL;
}
}
return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
file->f_flags & O_NONBLOCK);
}
static unsigned int mpeg_poll(struct file *file,
struct poll_table_struct *wait)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
dprintk(2, "%s\n", __func__);
return videobuf_poll_stream(file, &fh->mpegq, wait);
}
static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
dprintk(2, "%s()\n", __func__);
return videobuf_mmap_mapper(&fh->mpegq, vma);
}
static struct v4l2_file_operations mpeg_fops = {
.owner = THIS_MODULE,
.open = mpeg_open,
.release = mpeg_release,
.read = mpeg_read,
.poll = mpeg_poll,
.mmap = mpeg_mmap,
.ioctl = video_ioctl2,
.open = v4l2_fh_open,
.release = vb2_fop_release,
.read = vb2_fop_read,
.poll = vb2_fop_poll,
.unlocked_ioctl = video_ioctl2,
.mmap = vb2_fop_mmap,
};
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
@ -1669,25 +1446,19 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
.vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_log_status = vidioc_log_status,
.vidioc_querymenu = vidioc_querymenu,
.vidioc_queryctrl = vidioc_queryctrl,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_chip_info = cx23885_g_chip_info,
.vidioc_g_register = cx23885_g_register,
@ -1711,6 +1482,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
video_unregister_device(dev->v4l_device);
else
video_device_release(dev->v4l_device);
v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
dev->v4l_device = NULL;
}
}
@ -1742,6 +1514,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
/* FIXME: Port1 hardcoded here */
int err = -ENODEV;
struct cx23885_tsport *tsport = &dev->ts1;
struct vb2_queue *q;
dprintk(1, "%s()\n", __func__);
@ -1757,14 +1530,36 @@ int cx23885_417_register(struct cx23885_dev *dev)
tsport->height = 576;
tsport->width = 720;
cx2341x_fill_defaults(&dev->mpeg_params);
dev->mpeg_params.port = CX2341X_PORT_SERIAL;
dev->cxhdl.port = CX2341X_PORT_SERIAL;
err = cx2341x_handler_init(&dev->cxhdl, 50);
if (err)
return err;
dev->cxhdl.priv = dev;
dev->cxhdl.func = cx23885_api_func;
cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL);
/* Allocate and initialize V4L video device */
dev->v4l_device = cx23885_video_dev_alloc(tsport,
dev->pci, &cx23885_mpeg_template, "mpeg");
q = &dev->vb2_mpegq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->gfp_flags = GFP_DMA32;
q->min_buffers_needed = 2;
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct cx23885_buffer);
q->ops = &cx23885_qops;
q->mem_ops = &vb2_dma_sg_memops;
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &dev->lock;
err = vb2_queue_init(q);
if (err < 0)
return err;
video_set_drvdata(dev->v4l_device, dev);
dev->v4l_device->lock = &dev->lock;
dev->v4l_device->queue = q;
err = video_register_device(dev->v4l_device,
VFL_TYPE_GRABBER, -1);
if (err < 0) {

View File

@ -15,10 +15,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
@ -84,6 +80,82 @@ MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]");
#define AUD_INT_MCHG_IRQ (1 << 21)
#define GP_COUNT_CONTROL_RESET 0x3
static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages)
{
struct cx23885_audio_buffer *buf = chip->buf;
struct page *pg;
int i;
buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
if (NULL == buf->vaddr) {
dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
return -ENOMEM;
}
dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
(unsigned long)buf->vaddr,
nr_pages << PAGE_SHIFT);
memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
buf->nr_pages = nr_pages;
buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
if (NULL == buf->sglist)
goto vzalloc_err;
sg_init_table(buf->sglist, buf->nr_pages);
for (i = 0; i < buf->nr_pages; i++) {
pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
if (NULL == pg)
goto vmalloc_to_page_err;
sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
}
return 0;
vmalloc_to_page_err:
vfree(buf->sglist);
buf->sglist = NULL;
vzalloc_err:
vfree(buf->vaddr);
buf->vaddr = NULL;
return -ENOMEM;
}
static int cx23885_alsa_dma_map(struct cx23885_audio_dev *dev)
{
struct cx23885_audio_buffer *buf = dev->buf;
buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist,
buf->nr_pages, PCI_DMA_FROMDEVICE);
if (0 == buf->sglen) {
pr_warn("%s: cx23885_alsa_map_sg failed\n", __func__);
return -ENOMEM;
}
return 0;
}
static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev)
{
struct cx23885_audio_buffer *buf = dev->buf;
if (!buf->sglen)
return 0;
dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE);
buf->sglen = 0;
return 0;
}
static int cx23885_alsa_dma_free(struct cx23885_audio_buffer *buf)
{
vfree(buf->sglist);
buf->sglist = NULL;
vfree(buf->vaddr);
buf->vaddr = NULL;
return 0;
}
/*
* BOARD Specific: Sets audio DMA
*/
@ -198,15 +270,18 @@ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask)
static int dsp_buffer_free(struct cx23885_audio_dev *chip)
{
struct cx23885_riscmem *risc;
BUG_ON(!chip->dma_size);
dprintk(2, "Freeing buffer\n");
videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
videobuf_dma_free(chip->dma_risc);
btcx_riscmem_free(chip->pci, &chip->buf->risc);
cx23885_alsa_dma_unmap(chip);
cx23885_alsa_dma_free(chip->buf);
risc = &chip->buf->risc;
pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma);
kfree(chip->buf);
chip->dma_risc = NULL;
chip->buf = NULL;
chip->dma_size = 0;
return 0;
@ -289,6 +364,7 @@ static int snd_cx23885_close(struct snd_pcm_substream *substream)
return 0;
}
/*
* hw_params callback
*/
@ -296,8 +372,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
struct videobuf_dmabuf *dma;
struct cx23885_audio_buffer *buf;
int ret;
@ -318,19 +392,18 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
return -ENOMEM;
buf->bpl = chip->period_size;
chip->buf = buf;
dma = &buf->dma;
videobuf_dma_init(dma);
ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
ret = cx23885_alsa_dma_init(chip,
(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
if (ret < 0)
goto error;
ret = videobuf_dma_map(&chip->pci->dev, dma);
ret = cx23885_alsa_dma_map(chip);
if (ret < 0)
goto error;
ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
chip->period_size, chip->num_periods, 1);
if (ret < 0)
goto error;
@ -340,10 +413,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
chip->buf = buf;
chip->dma_risc = dma;
substream->runtime->dma_area = chip->dma_risc->vaddr;
substream->runtime->dma_area = chip->buf->vaddr;
substream->runtime->dma_bytes = chip->dma_size;
substream->runtime->dma_addr = 0;
@ -351,6 +421,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
error:
kfree(buf);
chip->buf = NULL;
return ret;
}

View File

@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "cx23885.h"

View File

@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef _CX23885_AV_H_

Some files were not shown because too many files have changed in this diff Show More