Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:
 "This series include:
   - a new Remote Controller driver for ST SoC with the corresponding DT
     bindings
   - a new frontend (cx24117)
   - a new I2C camera flash driver (lm3560)
   - a new mem2mem driver for TI SoC (ti-vpe)
   - support for Raphael r828d added to r820t driver
   - some improvements on buffer allocation at VB2 core
   - usual driver fixes and improvements

  PS this time, we have a smaller number of patches.  While it is hard
  to pinpoint to the reasons, I believe that it is mainly due to:

   1) there are several patch series ready, but depending on DT review.
      I decided to grant some extra time for DT maintainers to look on
      it, as they're expecting to have more time with the changes agreed
      during ARM mini-summit and KS.  If they can't review in time for
      3.14, I'll review myself and apply for the next merge window.

   2) I suspect that having both LinuxCon EU and LinuxCon NA happening
      during the same merge window affected the development
      productivity, as several core media developers participated on
      both events"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (151 commits)
  [media] media: st-rc: Add ST remote control driver
  [media] gpio-ir-recv: Include linux/of.h header
  [media] tvp7002: Include linux/of.h header
  [media] tvp514x: Include linux/of.h header
  [media] ths8200: Include linux/of.h header
  [media] adv7343: Include linux/of.h header
  [media] v4l: Fix typo in v4l2_subdev_get_try_crop()
  [media] media: i2c: add driver for dual LED Flash, lm3560
  [media] rtl28xxu: add 15f4:0131 Astrometa DVB-T2
  [media] rtl28xxu: add RTL2832P + R828D support
  [media] rtl2832: add new tuner R828D
  [media] r820t: add support for R828D
  [media] media/i2c: ths8200: fix build failure with gcc 4.5.4
  [media] Add support for KWorld UB435-Q V2
  [media] staging/media: fix msi3101 build errors
  [media] ddbridge: Remove casting the return value which is a void pointer
  [media] ngene: Remove casting the return value which is a void pointer
  [media] dm1105: remove unneeded not-null test
  [media] sh_mobile_ceu_camera: remove deprecated IRQF_DISABLED
  [media] media: rcar_vin: Add preliminary r8a7790 support
  ...
This commit is contained in:
Linus Torvalds 2013-11-18 15:08:02 -08:00
commit a310410f61
181 changed files with 8873 additions and 952 deletions

View File

@ -0,0 +1,29 @@
Device-Tree bindings for ST IRB IP
Required properties:
- compatible: Should contain "st,comms-irb".
- 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.
- rx-mode: can be "infrared" or "uhf". This property specifies the L1
protocol used for receiving remote control signals. rx-mode should
be present iff the rx pins are wired up.
- tx-mode: should be "infrared". This property specifies the L1
protocol used for transmitting remote control signals. tx-mode should
be present iff the tx pins are wired up.
Optional properties:
- pinctrl-names, pinctrl-0: the pincontrol settings to configure muxing
properly for IRB pins.
- clocks : phandle with clock-specifier pair for IRB.
Example node:
rc: rc@fe518000 {
compatible = "st,comms-irb";
reg = <0xfe518000 0x234>;
interrupts = <0 203 0>;
rx-mode = "infrared";
};

View File

@ -85,7 +85,7 @@ static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1); mdelay(1);
retries--; retries--;
}; }
if (retries == 0) if (retries == 0)
printk("%s: SRAM timeout\n", __func__); printk("%s: SRAM timeout\n", __func__);
@ -110,7 +110,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1); mdelay(1);
retries--; retries--;
}; }
if (retries == 0) if (retries == 0)
printk("%s: SRAM timeout\n", __func__); printk("%s: SRAM timeout\n", __func__);
@ -122,7 +122,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1); mdelay(1);
retries--; retries--;
}; }
if (retries == 0) if (retries == 0)
printk("%s: SRAM timeout\n", __func__); printk("%s: SRAM timeout\n", __func__);

View File

@ -411,7 +411,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
saa7146_write(dev, MC2, 0xf8000000); saa7146_write(dev, MC2, 0xf8000000);
/* request an interrupt for the saa7146 */ /* request an interrupt for the saa7146 */
err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED, err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED,
dev->name, dev); dev->name, dev);
if (err < 0) { if (err < 0) {
ERR("request_irq() failed\n"); ERR("request_irq() failed\n");
@ -524,8 +524,6 @@ static void saa7146_remove_one(struct pci_dev *pdev)
DEB_EE("dev:%p\n", dev); DEB_EE("dev:%p\n", dev);
dev->ext->detach(dev); dev->ext->detach(dev);
/* Zero the PCI drvdata after use. */
pci_set_drvdata(pdev, NULL);
/* shut down all video dma transfers */ /* shut down all video dma transfers */
saa7146_write(dev, MC1, 0x00ff0000); saa7146_write(dev, MC1, 0x00ff0000);

View File

@ -922,8 +922,8 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
u32 i, *ptr; u32 i, *ptr;
u8 *payload = firmware->payload; u8 *payload = firmware->payload;
int rc = 0; int rc = 0;
firmware->start_address = le32_to_cpu(firmware->start_address); firmware->start_address = le32_to_cpup((__le32 *)&firmware->start_address);
firmware->length = le32_to_cpu(firmware->length); firmware->length = le32_to_cpup((__le32 *)&firmware->length);
mem_address = firmware->start_address; mem_address = firmware->start_address;
@ -982,7 +982,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
if (rc < 0) if (rc < 0)
goto exit_fw_download; goto exit_fw_download;
sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", sms_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x",
calc_checksum); calc_checksum);
SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ, SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ,
sizeof(msg->x_msg_header) + sizeof(msg->x_msg_header) +
@ -1562,7 +1562,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
{ {
struct sms_msg_data *validity = (struct sms_msg_data *) phdr; struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", sms_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x",
validity->msg_data[0]); validity->msg_data[0]);
complete(&coredev->data_validity_done); complete(&coredev->data_validity_done);
break; break;

View File

@ -44,14 +44,14 @@ module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
u32 sms_to_guard_interval_table[] = { static u32 sms_to_guard_interval_table[] = {
[0] = GUARD_INTERVAL_1_32, [0] = GUARD_INTERVAL_1_32,
[1] = GUARD_INTERVAL_1_16, [1] = GUARD_INTERVAL_1_16,
[2] = GUARD_INTERVAL_1_8, [2] = GUARD_INTERVAL_1_8,
[3] = GUARD_INTERVAL_1_4, [3] = GUARD_INTERVAL_1_4,
}; };
u32 sms_to_code_rate_table[] = { static u32 sms_to_code_rate_table[] = {
[0] = FEC_1_2, [0] = FEC_1_2,
[1] = FEC_2_3, [1] = FEC_2_3,
[2] = FEC_3_4, [2] = FEC_3_4,
@ -60,14 +60,14 @@ u32 sms_to_code_rate_table[] = {
}; };
u32 sms_to_hierarchy_table[] = { static u32 sms_to_hierarchy_table[] = {
[0] = HIERARCHY_NONE, [0] = HIERARCHY_NONE,
[1] = HIERARCHY_1, [1] = HIERARCHY_1,
[2] = HIERARCHY_2, [2] = HIERARCHY_2,
[3] = HIERARCHY_4, [3] = HIERARCHY_4,
}; };
u32 sms_to_modulation_table[] = { static u32 sms_to_modulation_table[] = {
[0] = QPSK, [0] = QPSK,
[1] = QAM_16, [1] = QAM_16,
[2] = QAM_64, [2] = QAM_64,

View File

@ -476,7 +476,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count) size_t count)
{ {
spin_lock(&demux->lock); unsigned long flags;
spin_lock_irqsave(&demux->lock, flags);
while (count--) { while (count--) {
if (buf[0] == 0x47) if (buf[0] == 0x47)
@ -484,7 +486,7 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
buf += 188; buf += 188;
} }
spin_unlock(&demux->lock); spin_unlock_irqrestore(&demux->lock, flags);
} }
EXPORT_SYMBOL(dvb_dmx_swfilter_packets); EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
@ -519,8 +521,9 @@ static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
{ {
int p = 0, i, j; int p = 0, i, j;
const u8 *q; const u8 *q;
unsigned long flags;
spin_lock(&demux->lock); spin_lock_irqsave(&demux->lock, flags);
if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */ if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
i = demux->tsbufp; i = demux->tsbufp;
@ -564,7 +567,7 @@ static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
} }
bailout: bailout:
spin_unlock(&demux->lock); spin_unlock_irqrestore(&demux->lock, flags);
} }
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
@ -581,11 +584,13 @@ EXPORT_SYMBOL(dvb_dmx_swfilter_204);
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
{ {
spin_lock(&demux->lock); unsigned long flags;
spin_lock_irqsave(&demux->lock, flags);
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK); demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK);
spin_unlock(&demux->lock); spin_unlock_irqrestore(&demux->lock, flags);
} }
EXPORT_SYMBOL(dvb_dmx_swfilter_raw); EXPORT_SYMBOL(dvb_dmx_swfilter_raw);

View File

@ -200,6 +200,13 @@ config DVB_CX24116
help help
A DVB-S/S2 tuner module. Say Y when you want to support this frontend. A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_CX24117
tristate "Conexant CX24117 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Dual DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_SI21XX config DVB_SI21XX
tristate "Silicon Labs SI21XX based" tristate "Silicon Labs SI21XX based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C

View File

@ -76,6 +76,7 @@ obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
obj-$(CONFIG_DVB_AF9013) += af9013.o obj-$(CONFIG_DVB_AF9013) += af9013.o
obj-$(CONFIG_DVB_CX24116) += cx24116.o obj-$(CONFIG_DVB_CX24116) += cx24116.o
obj-$(CONFIG_DVB_CX24117) += cx24117.o
obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_STB6000) += stb6000.o

View File

@ -378,7 +378,7 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40); return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
default: default:
return -EINVAL; return -EINVAL;
}; }
} }
static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/*
Conexant cx24117/cx24132 - Dual DVBS/S2 Satellite demod/tuner driver
Copyright (C) 2013 Luis Alves <ljalvs@gmail.com>
(based on cx24116.h by Steven Toth)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef CX24117_H
#define CX24117_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cx24117_config {
/* the demodulator's i2c address */
u8 demod_address;
};
#if IS_ENABLED(CONFIG_DVB_CX24117)
extern struct dvb_frontend *cx24117_attach(
const struct cx24117_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *cx24117_attach(
const struct cx24117_config *config,
struct i2c_adapter *i2c)
{
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* CX24117_H */

View File

@ -739,7 +739,7 @@ static int cx24123_set_voltage(struct dvb_frontend *fe,
return 0; return 0;
default: default:
return -EINVAL; return -EINVAL;
}; }
return 0; return 0;
} }

View File

@ -31,7 +31,7 @@ static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
{ {
.addr = i2c, .addr = i2c,
.flags = 0, .flags = 0,
.len = sizeof(buf), .len = len + 1,
.buf = buf, .buf = buf,
} }
}; };
@ -65,7 +65,7 @@ static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
}, { }, {
.addr = i2c, .addr = i2c,
.flags = I2C_M_RD, .flags = I2C_M_RD,
.len = sizeof(buf), .len = len,
.buf = buf, .buf = buf,
} }
}; };

View File

@ -649,9 +649,9 @@ static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 si
b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */ b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
if (*b == '~') { if (*b == '~') {
b++; b++;
dprintk(b); dprintk("%s", b);
} else } else
dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>"); dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<empty>");
return 1; return 1;
} }

View File

@ -46,10 +46,6 @@
#define DRX_I2C_MODEFLAGS 0xC0 #define DRX_I2C_MODEFLAGS 0xC0
#define DRX_I2C_FLAGS 0xF0 #define DRX_I2C_FLAGS 0xF0
#ifndef SIZEOF_ARRAY
#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
#endif
#define DEFAULT_LOCK_TIMEOUT 1100 #define DEFAULT_LOCK_TIMEOUT 1100
#define DRX_CHANNEL_AUTO 0 #define DRX_CHANNEL_AUTO 0
@ -1018,7 +1014,7 @@ static int HI_CfgCommand(struct drxd_state *state)
status = Write16(state, HI_RA_RAM_SRV_CMD__A, status = Write16(state, HI_RA_RAM_SRV_CMD__A,
HI_RA_RAM_SRV_CMD_CONFIG, 0); HI_RA_RAM_SRV_CMD_CONFIG, 0);
else else
status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0); status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, NULL);
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return status; return status;
} }
@ -1039,7 +1035,7 @@ static int HI_ResetCommand(struct drxd_state *state)
status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A, status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
HI_RA_RAM_SRV_RST_KEY_ACT, 0); HI_RA_RAM_SRV_RST_KEY_ACT, 0);
if (status == 0) if (status == 0)
status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0); status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, NULL);
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
msleep(1); msleep(1);
return status; return status;
@ -2837,7 +2833,7 @@ static int drxd_init(struct dvb_frontend *fe)
int err = 0; int err = 0;
/* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */ /* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
return DRXD_init(state, 0, 0); return DRXD_init(state, NULL, 0);
err = DRXD_init(state, state->fw->data, state->fw->size); err = DRXD_init(state, state->fw->data, state->fw->size);
release_firmware(state->fw); release_firmware(state->fw);
@ -2973,7 +2969,7 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config,
mutex_init(&state->mutex); mutex_init(&state->mutex);
if (Read16(state, 0, 0, 0) < 0) if (Read16(state, 0, NULL, 0) < 0)
goto error; goto error;
state->frontend.ops = drxd_ops; state->frontend.ops = drxd_ops;

View File

@ -1083,7 +1083,7 @@ static int hi_cfg_command(struct drxk_state *state)
SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
if (status < 0) if (status < 0)
goto error; goto error;
status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0); status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL);
if (status < 0) if (status < 0)
goto error; goto error;
@ -2781,7 +2781,7 @@ static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
goto error; goto error;
} }
status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0); status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL);
error: error:
if (status < 0) if (status < 0)

View File

@ -489,6 +489,7 @@ static int rtl2832_init(struct dvb_frontend *fe)
init = rtl2832_tuner_init_e4000; init = rtl2832_tuner_init_e4000;
break; break;
case RTL2832_TUNER_R820T: case RTL2832_TUNER_R820T:
case RTL2832_TUNER_R828D:
len = ARRAY_SIZE(rtl2832_tuner_init_r820t); len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
init = rtl2832_tuner_init_r820t; init = rtl2832_tuner_init_r820t;
break; break;

View File

@ -53,6 +53,7 @@ struct rtl2832_config {
#define RTL2832_TUNER_E4000 0x27 #define RTL2832_TUNER_E4000 0x27
#define RTL2832_TUNER_FC0013 0x29 #define RTL2832_TUNER_FC0013 0x29
#define RTL2832_TUNER_R820T 0x2a #define RTL2832_TUNER_R820T 0x2a
#define RTL2832_TUNER_R828D 0x2b
u8 tuner; u8 tuner;
}; };

View File

@ -189,7 +189,7 @@ static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t ton
return tda8083_writereg (state, 0x29, 0x80); return tda8083_writereg (state, 0x29, 0x80);
default: default:
return -EINVAL; return -EINVAL;
}; }
} }
static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
@ -201,7 +201,7 @@ static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t vo
return tda8083_writereg (state, 0x20, 0x11); return tda8083_writereg (state, 0x20, 0x11);
default: default:
return -EINVAL; return -EINVAL;
}; }
} }
static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)

View File

@ -31,6 +31,7 @@ struct ts2020_priv {
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
u8 clk_out_div; u8 clk_out_div;
u32 frequency; u32 frequency;
u32 frequency_div;
}; };
static int ts2020_release(struct dvb_frontend *fe) static int ts2020_release(struct dvb_frontend *fe)
@ -193,7 +194,7 @@ static int ts2020_set_params(struct dvb_frontend *fe)
u8 lo = 0x01, div4 = 0x0; u8 lo = 0x01, div4 = 0x0;
/* Calculate frequency divider */ /* Calculate frequency divider */
if (frequency < 1060000) { if (frequency < priv->frequency_div) {
lo |= 0x10; lo |= 0x10;
div4 = 0x1; div4 = 0x1;
ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ; ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ;
@ -340,8 +341,12 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
priv->i2c_address = config->tuner_address; priv->i2c_address = config->tuner_address;
priv->i2c = i2c; priv->i2c = i2c;
priv->clk_out_div = config->clk_out_div; priv->clk_out_div = config->clk_out_div;
priv->frequency_div = config->frequency_div;
fe->tuner_priv = priv; fe->tuner_priv = priv;
if (!priv->frequency_div)
priv->frequency_div = 1060000;
/* Wake Up the tuner */ /* Wake Up the tuner */
if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) { if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) {
ts2020_writereg(fe, 0x00, 0x01); ts2020_writereg(fe, 0x00, 0x01);

View File

@ -28,6 +28,7 @@
struct ts2020_config { struct ts2020_config {
u8 tuner_address; u8 tuner_address;
u8 clk_out_div; u8 clk_out_div;
u32 frequency_div;
}; };
#if IS_ENABLED(CONFIG_DVB_TS2020) #if IS_ENABLED(CONFIG_DVB_TS2020)

View File

@ -621,6 +621,15 @@ config VIDEO_AS3645A
This is a driver for the AS3645A and LM3555 flash controllers. It has This is a driver for the AS3645A and LM3555 flash controllers. It has
build in control for flash, torch and indicator LEDs. build in control for flash, torch and indicator LEDs.
config VIDEO_LM3560
tristate "LM3560 dual flash driver support"
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
depends on MEDIA_CAMERA_SUPPORT
select REGMAP_I2C
---help---
This is a driver for the lm3560 dual flash controllers. It controls
flash, torch LEDs.
comment "Video improvement chips" comment "Video improvement chips"
config VIDEO_UPD64031A config VIDEO_UPD64031A

View File

@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o
obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
obj-$(CONFIG_VIDEO_LM3560) += lm3560.o
obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
obj-$(CONFIG_VIDEO_AK881X) += ak881x.o obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o

View File

@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/of.h>
#include <media/adv7343.h> #include <media/adv7343.h>
#include <media/v4l2-async.h> #include <media/v4l2-async.h>

488
drivers/media/i2c/lm3560.c Normal file
View File

@ -0,0 +1,488 @@
/*
* drivers/media/i2c/lm3560.c
* General device driver for TI lm3560, FLASH LED Driver
*
* Copyright (C) 2013 Texas Instruments
*
* Contact: Daniel Jeong <gshark.jeong@gmail.com>
* Ldd-Mlp <ldd-mlp@list.ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/videodev2.h>
#include <media/lm3560.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
/* registers definitions */
#define REG_ENABLE 0x10
#define REG_TORCH_BR 0xa0
#define REG_FLASH_BR 0xb0
#define REG_FLASH_TOUT 0xc0
#define REG_FLAG 0xd0
#define REG_CONFIG1 0xe0
/* Fault Mask */
#define FAULT_TIMEOUT (1<<0)
#define FAULT_OVERTEMP (1<<1)
#define FAULT_SHORT_CIRCUIT (1<<2)
enum led_enable {
MODE_SHDN = 0x0,
MODE_TORCH = 0x2,
MODE_FLASH = 0x3,
};
/* struct lm3560_flash
*
* @pdata: platform data
* @regmap: reg. map for i2c
* @lock: muxtex for serial access.
* @led_mode: V4L2 LED mode
* @ctrls_led: V4L2 contols
* @subdev_led: V4L2 subdev
*/
struct lm3560_flash {
struct device *dev;
struct lm3560_platform_data *pdata;
struct regmap *regmap;
struct mutex lock;
enum v4l2_flash_led_mode led_mode;
struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX];
struct v4l2_subdev subdev_led[LM3560_LED_MAX];
};
#define to_lm3560_flash(_ctrl, _no) \
container_of(_ctrl->handler, struct lm3560_flash, ctrls_led[_no])
/* enable mode control */
static int lm3560_mode_ctrl(struct lm3560_flash *flash)
{
int rval = -EINVAL;
switch (flash->led_mode) {
case V4L2_FLASH_LED_MODE_NONE:
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x03, MODE_SHDN);
break;
case V4L2_FLASH_LED_MODE_TORCH:
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x03, MODE_TORCH);
break;
case V4L2_FLASH_LED_MODE_FLASH:
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x03, MODE_FLASH);
break;
}
return rval;
}
/* led1/2 enable/disable */
static int lm3560_enable_ctrl(struct lm3560_flash *flash,
enum lm3560_led_id led_no, bool on)
{
int rval;
if (led_no == LM3560_LED0) {
if (on == true)
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)
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x10, 0x10);
else
rval = regmap_update_bits(flash->regmap,
REG_ENABLE, 0x10, 0x00);
}
return rval;
}
/* torch1/2 brightness control */
static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash,
enum lm3560_led_id led_no, unsigned int brt)
{
int rval;
u8 br_bits;
if (brt < LM3560_TORCH_BRT_MIN)
return lm3560_enable_ctrl(flash, led_no, false);
else
rval = lm3560_enable_ctrl(flash, led_no, true);
br_bits = LM3560_TORCH_BRT_uA_TO_REG(brt);
if (led_no == LM3560_LED0)
rval = regmap_update_bits(flash->regmap,
REG_TORCH_BR, 0x07, br_bits);
else
rval = regmap_update_bits(flash->regmap,
REG_TORCH_BR, 0x38, br_bits << 3);
return rval;
}
/* flash1/2 brightness control */
static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash,
enum lm3560_led_id led_no, unsigned int brt)
{
int rval;
u8 br_bits;
if (brt < LM3560_FLASH_BRT_MIN)
return lm3560_enable_ctrl(flash, led_no, false);
else
rval = lm3560_enable_ctrl(flash, led_no, true);
br_bits = LM3560_FLASH_BRT_uA_TO_REG(brt);
if (led_no == LM3560_LED0)
rval = regmap_update_bits(flash->regmap,
REG_FLASH_BR, 0x0f, br_bits);
else
rval = regmap_update_bits(flash->regmap,
REG_FLASH_BR, 0xf0, br_bits << 4);
return rval;
}
/* V4L2 controls */
static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
{
struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
mutex_lock(&flash->lock);
if (ctrl->id == V4L2_CID_FLASH_FAULT) {
int rval;
s32 fault = 0;
unsigned int reg_val;
rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
if (rval < 0)
return rval;
if (rval & FAULT_SHORT_CIRCUIT)
fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
if (rval & FAULT_OVERTEMP)
fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
if (rval & FAULT_TIMEOUT)
fault |= V4L2_FLASH_FAULT_TIMEOUT;
ctrl->cur.val = fault;
return 0;
}
mutex_unlock(&flash->lock);
return -EINVAL;
}
static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
{
struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
u8 tout_bits;
int rval = -EINVAL;
mutex_lock(&flash->lock);
switch (ctrl->id) {
case V4L2_CID_FLASH_LED_MODE:
flash->led_mode = ctrl->val;
if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
rval = lm3560_mode_ctrl(flash);
break;
case V4L2_CID_FLASH_STROBE_SOURCE:
rval = regmap_update_bits(flash->regmap,
REG_CONFIG1, 0x04, (ctrl->val) << 2);
if (rval < 0)
goto err_out;
break;
case V4L2_CID_FLASH_STROBE:
if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
return -EBUSY;
flash->led_mode = V4L2_FLASH_LED_MODE_FLASH;
rval = lm3560_mode_ctrl(flash);
break;
case V4L2_CID_FLASH_STROBE_STOP:
if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
return -EBUSY;
flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
rval = lm3560_mode_ctrl(flash);
break;
case V4L2_CID_FLASH_TIMEOUT:
tout_bits = LM3560_FLASH_TOUT_ms_TO_REG(ctrl->val);
rval = regmap_update_bits(flash->regmap,
REG_FLASH_TOUT, 0x1f, tout_bits);
break;
case V4L2_CID_FLASH_INTENSITY:
rval = lm3560_flash_brt_ctrl(flash, led_no, ctrl->val);
break;
case V4L2_CID_FLASH_TORCH_INTENSITY:
rval = lm3560_torch_brt_ctrl(flash, led_no, ctrl->val);
break;
}
mutex_unlock(&flash->lock);
err_out:
return rval;
}
static int lm3560_led1_get_ctrl(struct v4l2_ctrl *ctrl)
{
return lm3560_get_ctrl(ctrl, LM3560_LED1);
}
static int lm3560_led1_set_ctrl(struct v4l2_ctrl *ctrl)
{
return lm3560_set_ctrl(ctrl, LM3560_LED1);
}
static int lm3560_led0_get_ctrl(struct v4l2_ctrl *ctrl)
{
return lm3560_get_ctrl(ctrl, LM3560_LED0);
}
static int lm3560_led0_set_ctrl(struct v4l2_ctrl *ctrl)
{
return lm3560_set_ctrl(ctrl, LM3560_LED0);
}
static const struct v4l2_ctrl_ops lm3560_led_ctrl_ops[LM3560_LED_MAX] = {
[LM3560_LED0] = {
.g_volatile_ctrl = lm3560_led0_get_ctrl,
.s_ctrl = lm3560_led0_set_ctrl,
},
[LM3560_LED1] = {
.g_volatile_ctrl = lm3560_led1_get_ctrl,
.s_ctrl = lm3560_led1_set_ctrl,
}
};
static int lm3560_init_controls(struct lm3560_flash *flash,
enum lm3560_led_id led_no)
{
struct v4l2_ctrl *fault;
u32 max_flash_brt = flash->pdata->max_flash_brt[led_no];
u32 max_torch_brt = flash->pdata->max_torch_brt[led_no];
struct v4l2_ctrl_handler *hdl = &flash->ctrls_led[led_no];
const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no];
v4l2_ctrl_handler_init(hdl, 8);
/* flash mode */
v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
V4L2_FLASH_LED_MODE_TORCH, ~0x7,
V4L2_FLASH_LED_MODE_NONE);
flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
/* flash source */
v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE,
0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
/* flash strobe */
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
/* flash strobe stop */
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
/* flash strobe timeout */
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT,
LM3560_FLASH_TOUT_MIN,
flash->pdata->max_flash_timeout,
LM3560_FLASH_TOUT_STEP,
flash->pdata->max_flash_timeout);
/* flash brt */
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
LM3560_FLASH_BRT_MIN, max_flash_brt,
LM3560_FLASH_BRT_STEP, max_flash_brt);
/* torch brt */
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY,
LM3560_TORCH_BRT_MIN, max_torch_brt,
LM3560_TORCH_BRT_STEP, max_torch_brt);
/* fault */
fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0,
V4L2_FLASH_FAULT_OVER_VOLTAGE
| V4L2_FLASH_FAULT_OVER_TEMPERATURE
| V4L2_FLASH_FAULT_SHORT_CIRCUIT
| V4L2_FLASH_FAULT_TIMEOUT, 0, 0);
if (fault != NULL)
fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
if (hdl->error)
return hdl->error;
flash->subdev_led[led_no].ctrl_handler = hdl;
return 0;
}
/* initialize device */
static const struct v4l2_subdev_ops lm3560_ops = {
.core = NULL,
};
static const struct regmap_config lm3560_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xFF,
};
static int lm3560_subdev_init(struct lm3560_flash *flash,
enum lm3560_led_id led_no, char *led_name)
{
struct i2c_client *client = to_i2c_client(flash->dev);
int rval;
v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops);
flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
strcpy(flash->subdev_led[led_no].name, led_name);
rval = lm3560_init_controls(flash, led_no);
if (rval)
goto err_out;
rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0);
if (rval < 0)
goto err_out;
flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
return rval;
err_out:
v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]);
return rval;
}
static int lm3560_init_device(struct lm3560_flash *flash)
{
int rval;
unsigned int reg_val;
/* set peak current */
rval = regmap_update_bits(flash->regmap,
REG_FLASH_TOUT, 0x60, flash->pdata->peak);
if (rval < 0)
return rval;
/* output disable */
flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
rval = lm3560_mode_ctrl(flash);
if (rval < 0)
return rval;
/* Reset faults */
rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
return rval;
}
static int lm3560_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
struct lm3560_flash *flash;
struct lm3560_platform_data *pdata = dev_get_platdata(&client->dev);
int rval;
flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
if (flash == NULL)
return -ENOMEM;
flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap);
if (IS_ERR(flash->regmap)) {
rval = PTR_ERR(flash->regmap);
return rval;
}
/* if there is no platform data, use chip default value */
if (pdata == NULL) {
pdata =
kzalloc(sizeof(struct lm3560_platform_data), GFP_KERNEL);
if (pdata == NULL)
return -ENODEV;
pdata->peak = LM3560_PEAK_3600mA;
pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX;
/* led 1 */
pdata->max_flash_brt[LM3560_LED0] = LM3560_FLASH_BRT_MAX;
pdata->max_torch_brt[LM3560_LED0] = LM3560_TORCH_BRT_MAX;
/* led 2 */
pdata->max_flash_brt[LM3560_LED1] = LM3560_FLASH_BRT_MAX;
pdata->max_torch_brt[LM3560_LED1] = LM3560_TORCH_BRT_MAX;
}
flash->pdata = pdata;
flash->dev = &client->dev;
mutex_init(&flash->lock);
rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0");
if (rval < 0)
return rval;
rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1");
if (rval < 0)
return rval;
rval = lm3560_init_device(flash);
if (rval < 0)
return rval;
return 0;
}
static int lm3560_remove(struct i2c_client *client)
{
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
struct lm3560_flash *flash = container_of(subdev, struct lm3560_flash,
subdev_led[LM3560_LED_MAX]);
unsigned int i;
for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
v4l2_device_unregister_subdev(&flash->subdev_led[i]);
v4l2_ctrl_handler_free(&flash->ctrls_led[i]);
media_entity_cleanup(&flash->subdev_led[i].entity);
}
return 0;
}
static const struct i2c_device_id lm3560_id_table[] = {
{LM3560_NAME, 0},
{}
};
MODULE_DEVICE_TABLE(i2c, lm3560_id_table);
static struct i2c_driver lm3560_i2c_driver = {
.driver = {
.name = LM3560_NAME,
.pm = NULL,
},
.probe = lm3560_probe,
.remove = lm3560_remove,
.id_table = lm3560_id_table,
};
module_i2c_driver(lm3560_i2c_driver);
MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>");
MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");
MODULE_DESCRIPTION("Texas Instruments LM3560 LED flash driver");
MODULE_LICENSE("GPL");

View File

@ -451,7 +451,9 @@ static int imx074_probe(struct i2c_client *client,
if (ret < 0) if (ret < 0)
goto eprobe; goto eprobe;
return v4l2_async_register_subdev(&priv->subdev); ret = v4l2_async_register_subdev(&priv->subdev);
if (!ret)
return 0;
epwrinit: epwrinit:
eprobe: eprobe:

View File

@ -371,7 +371,7 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code,
alt->com13 = OV9640_COM13_RGB_AVG; alt->com13 = OV9640_COM13_RGB_AVG;
alt->com15 = OV9640_COM15_RGB_565; alt->com15 = OV9640_COM15_RGB_565;
break; break;
}; }
} }
/* Setup registers according to resolution and color encoding */ /* Setup registers according to resolution and color encoding */

View File

@ -19,6 +19,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/v4l2-dv-timings.h> #include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dv-timings.h> #include <media/v4l2-dv-timings.h>

View File

@ -35,6 +35,7 @@
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/v4l2-mediabus.h> #include <linux/v4l2-mediabus.h>
#include <linux/of.h>
#include <media/v4l2-async.h> #include <media/v4l2-async.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>

View File

@ -29,6 +29,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/v4l2-dv-timings.h> #include <linux/v4l2-dv-timings.h>
#include <media/tvp7002.h> #include <media/tvp7002.h>
#include <media/v4l2-async.h> #include <media/v4l2-async.h>

View File

@ -319,7 +319,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
err_pci_iounmap: err_pci_iounmap:
pci_iounmap(fc_pci->pdev, fc_pci->io_mem); pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
pci_set_drvdata(fc_pci->pdev, NULL);
err_pci_release_regions: err_pci_release_regions:
pci_release_regions(fc_pci->pdev); pci_release_regions(fc_pci->pdev);
err_pci_disable_device: err_pci_disable_device:
@ -332,7 +331,6 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
if (fc_pci->init_state & FC_PCI_INIT) { if (fc_pci->init_state & FC_PCI_INIT) {
free_irq(fc_pci->pdev->irq, fc_pci); free_irq(fc_pci->pdev->irq, fc_pci);
pci_iounmap(fc_pci->pdev, fc_pci->io_mem); pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
pci_set_drvdata(fc_pci->pdev, NULL);
pci_release_regions(fc_pci->pdev); pci_release_regions(fc_pci->pdev);
pci_disable_device(fc_pci->pdev); pci_disable_device(fc_pci->pdev);
} }

View File

@ -488,8 +488,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
btwrite(0, BT848_INT_MASK); btwrite(0, BT848_INT_MASK);
result = request_irq(bt->irq, bt878_irq, result = request_irq(bt->irq, bt878_irq,
IRQF_SHARED | IRQF_DISABLED, "bt878", IRQF_SHARED, "bt878", (void *) bt);
(void *) bt);
if (result == -EINVAL) { if (result == -EINVAL) {
printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
bt878_num); bt878_num);
@ -563,7 +562,6 @@ static void bt878_remove(struct pci_dev *pci_dev)
bt->shutdown = 1; bt->shutdown = 1;
bt878_mem_free(bt); bt878_mem_free(bt);
pci_set_drvdata(pci_dev, NULL);
pci_disable_device(pci_dev); pci_disable_device(pci_dev);
return; return;
} }

View File

@ -4086,7 +4086,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
/* disable irqs, register irq handler */ /* disable irqs, register irq handler */
btwrite(0, BT848_INT_MASK); btwrite(0, BT848_INT_MASK);
result = request_irq(btv->c.pci->irq, bttv_irq, result = request_irq(btv->c.pci->irq, bttv_irq,
IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv); IRQF_SHARED, btv->c.v4l2_dev.name, (void *)btv);
if (result < 0) { if (result < 0) {
pr_err("%d: can't get IRQ %d\n", pr_err("%d: can't get IRQ %d\n",
bttv_num, btv->c.pci->irq); bttv_num, btv->c.pci->irq);

View File

@ -1031,8 +1031,7 @@ static int cx18_probe(struct pci_dev *pci_dev,
/* Register IRQ */ /* Register IRQ */
retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
IRQF_SHARED | IRQF_DISABLED, IRQF_SHARED, cx->v4l2_dev.name, (void *)cx);
cx->v4l2_dev.name, (void *)cx);
if (retval) { if (retval) {
CX18_ERR("Failed to register irq %d\n", retval); CX18_ERR("Failed to register irq %d\n", retval);
goto free_i2c; goto free_i2c;

View File

@ -23,6 +23,7 @@ config VIDEO_CX23885
select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT
select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
select DVB_CX24117 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT

View File

@ -223,6 +223,39 @@ struct cx23885_board cx23885_boards[] = {
.name = "Leadtek Winfast PxDVR3200 H", .name = "Leadtek Winfast PxDVR3200 H",
.portc = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB,
}, },
[CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200] = {
.name = "Leadtek Winfast PxPVR2200",
.porta = CX23885_ANALOG_VIDEO,
.tuner_type = TUNER_XC2028,
.tuner_addr = 0x61,
.tuner_bus = 1,
.input = {{
.type = CX23885_VMUX_TELEVISION,
.vmux = CX25840_VIN2_CH1 |
CX25840_VIN5_CH2,
.amux = CX25840_AUDIO8,
.gpio0 = 0x704040,
}, {
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_COMPOSITE1,
.amux = CX25840_AUDIO7,
.gpio0 = 0x704040,
}, {
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_SVIDEO_LUMA3 |
CX25840_SVIDEO_CHROMA4,
.amux = CX25840_AUDIO7,
.gpio0 = 0x704040,
}, {
.type = CX23885_VMUX_COMPONENT,
.vmux = CX25840_VIN7_CH1 |
CX25840_VIN6_CH2 |
CX25840_VIN8_CH3 |
CX25840_COMPONENT_ON,
.amux = CX25840_AUDIO7,
.gpio0 = 0x704040,
} },
},
[CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = { [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = {
.name = "Leadtek Winfast PxDVR3200 H XC4000", .name = "Leadtek Winfast PxDVR3200 H XC4000",
.porta = CX23885_ANALOG_VIDEO, .porta = CX23885_ANALOG_VIDEO,
@ -259,6 +292,16 @@ struct cx23885_board cx23885_boards[] = {
.name = "TurboSight TBS 6920", .name = "TurboSight TBS 6920",
.portb = CX23885_MPEG_DVB, .portb = CX23885_MPEG_DVB,
}, },
[CX23885_BOARD_TBS_6980] = {
.name = "TurboSight TBS 6980",
.portb = CX23885_MPEG_DVB,
.portc = CX23885_MPEG_DVB,
},
[CX23885_BOARD_TBS_6981] = {
.name = "TurboSight TBS 6981",
.portb = CX23885_MPEG_DVB,
.portc = CX23885_MPEG_DVB,
},
[CX23885_BOARD_TEVII_S470] = { [CX23885_BOARD_TEVII_S470] = {
.name = "TeVii S470", .name = "TeVii S470",
.portb = CX23885_MPEG_DVB, .portb = CX23885_MPEG_DVB,
@ -686,6 +729,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x107d, .subvendor = 0x107d,
.subdevice = 0x6681, .subdevice = 0x6681,
.card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H,
}, {
.subvendor = 0x107d,
.subdevice = 0x6f21,
.card = CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200,
}, { }, {
.subvendor = 0x107d, .subvendor = 0x107d,
.subdevice = 0x6f39, .subdevice = 0x6f39,
@ -698,6 +745,14 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x6920, .subvendor = 0x6920,
.subdevice = 0x8888, .subdevice = 0x8888,
.card = CX23885_BOARD_TBS_6920, .card = CX23885_BOARD_TBS_6920,
}, {
.subvendor = 0x6980,
.subdevice = 0x8888,
.card = CX23885_BOARD_TBS_6980,
}, {
.subvendor = 0x6981,
.subdevice = 0x8888,
.card = CX23885_BOARD_TBS_6981,
}, { }, {
.subvendor = 0xd470, .subvendor = 0xd470,
.subdevice = 0x9022, .subdevice = 0x9022,
@ -1023,6 +1078,35 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
dev->name, tv.model); dev->name, tv.model);
} }
/* Some TBS cards require initing a chip using a bitbanged SPI attached
to the cx23885 gpio's. If this chip doesn't get init'ed the demod
doesn't respond to any command. */
static void tbs_card_init(struct cx23885_dev *dev)
{
int i;
const u8 buf[] = {
0xe0, 0x06, 0x66, 0x33, 0x65,
0x01, 0x17, 0x06, 0xde};
switch (dev->board) {
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
cx_set(GP0_IO, 0x00070007);
usleep_range(1000, 10000);
cx_clear(GP0_IO, 2);
usleep_range(1000, 10000);
for (i = 0; i < 9 * 8; i++) {
cx_clear(GP0_IO, 7);
usleep_range(1000, 10000);
cx_set(GP0_IO,
((buf[i >> 3] >> (7 - (i & 7))) & 1) | 4);
usleep_range(1000, 10000);
}
cx_set(GP0_IO, 7);
break;
}
}
int cx23885_tuner_callback(void *priv, int component, int command, int arg) int cx23885_tuner_callback(void *priv, int component, int command, int arg)
{ {
struct cx23885_tsport *port = priv; struct cx23885_tsport *port = priv;
@ -1043,6 +1127,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
@ -1208,6 +1293,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x000f000f); cx_set(GP0_IO, 0x000f000f);
break; break;
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
@ -1225,6 +1311,8 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x00040004); cx_set(GP0_IO, 0x00040004);
break; break;
case CX23885_BOARD_TBS_6920: case CX23885_BOARD_TBS_6920:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
case CX23885_BOARD_PROF_8000: case CX23885_BOARD_PROF_8000:
cx_write(MC417_CTL, 0x00000036); cx_write(MC417_CTL, 0x00000036);
cx_write(MC417_OEN, 0x00001000); cx_write(MC417_OEN, 0x00001000);
@ -1473,6 +1561,8 @@ int cx23885_ir_init(struct cx23885_dev *dev)
case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
if (!enable_885_ir) if (!enable_885_ir)
break; break;
dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE);
@ -1516,6 +1606,8 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
cx23885_irq_remove(dev, PCI_MSK_AV_CORE); cx23885_irq_remove(dev, PCI_MSK_AV_CORE);
/* sd_ir is a duplicate pointer to the AV Core, just clear it */ /* sd_ir is a duplicate pointer to the AV Core, just clear it */
dev->sd_ir = NULL; dev->sd_ir = NULL;
@ -1561,6 +1653,8 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
if (dev->sd_ir) if (dev->sd_ir)
cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE);
break; break;
@ -1676,6 +1770,16 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break; break;
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
tbs_card_init(dev);
break;
case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MYGICA_X8506:
case CX23885_BOARD_MAGICPRO_PROHDTVE2: case CX23885_BOARD_MAGICPRO_PROHDTVE2:
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
@ -1704,6 +1808,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1400:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1270:
@ -1733,6 +1838,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
@ -1752,6 +1858,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_AVERMEDIA_HC81R: case CX23885_BOARD_AVERMEDIA_HC81R:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap, &dev->i2c_bus[2].i2c_adap,
"cx25840", 0x88 >> 1, NULL); "cx25840", 0x88 >> 1, NULL);

View File

@ -2129,7 +2129,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
} }
err = request_irq(pci_dev->irq, cx23885_irq, err = request_irq(pci_dev->irq, cx23885_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev); IRQF_SHARED, dev->name, dev);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n", printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->name, pci_dev->irq); dev->name, pci_dev->irq);

View File

@ -51,6 +51,7 @@
#include "stv6110.h" #include "stv6110.h"
#include "lnbh24.h" #include "lnbh24.h"
#include "cx24116.h" #include "cx24116.h"
#include "cx24117.h"
#include "cimax2.h" #include "cimax2.h"
#include "lgs8gxx.h" #include "lgs8gxx.h"
#include "netup-eeprom.h" #include "netup-eeprom.h"
@ -461,6 +462,10 @@ static struct cx24116_config tbs_cx24116_config = {
.demod_address = 0x55, .demod_address = 0x55,
}; };
static struct cx24117_config tbs_cx24117_config = {
.demod_address = 0x55,
};
static struct ds3000_config tevii_ds3000_config = { static struct ds3000_config tevii_ds3000_config = {
.demod_address = 0x68, .demod_address = 0x68,
}; };
@ -1044,6 +1049,25 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
break; break;
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
i2c_bus = &dev->i2c_bus[1];
switch (port->nr) {
/* PORT B */
case 1:
fe0->dvb.frontend = dvb_attach(cx24117_attach,
&tbs_cx24117_config,
&i2c_bus->i2c_adap);
break;
/* PORT C */
case 2:
fe0->dvb.frontend = dvb_attach(cx24117_attach,
&tbs_cx24117_config,
&i2c_bus->i2c_adap);
break;
}
break;
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
i2c_bus = &dev->i2c_bus[1]; i2c_bus = &dev->i2c_bus[1];

View File

@ -90,6 +90,8 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MYGICA_X8507:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
/* /*
* The only boards we handle right now. However other boards * The only boards we handle right now. However other boards
* using the CX2388x integrated IR controller should be similar * using the CX2388x integrated IR controller should be similar
@ -168,6 +170,8 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)
break; break;
case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
/* /*
* The IR controller on this board only returns pulse widths. * The IR controller on this board only returns pulse widths.
* Any other mode setting will fail to set up the device. * Any other mode setting will fail to set up the device.
@ -298,6 +302,14 @@ int cx23885_input_init(struct cx23885_dev *dev)
/* A guess at the remote */ /* A guess at the remote */
rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
break; break;
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
/* Integrated CX23885 IR controller */
driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TBS_NEC;
break;
default: default:
return -ENODEV; return -ENODEV;
} }

View File

@ -1865,7 +1865,8 @@ int cx23885_video_register(struct cx23885_dev *dev)
v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) { if ((dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) ||
(dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200)) {
struct xc2028_ctrl ctrl = { struct xc2028_ctrl ctrl = {
.fname = XC2028_DEFAULT_FIRMWARE, .fname = XC2028_DEFAULT_FIRMWARE,
.max_len = 64 .max_len = 64

View File

@ -93,6 +93,9 @@
#define CX23885_BOARD_PROF_8000 37 #define CX23885_BOARD_PROF_8000 37
#define CX23885_BOARD_HAUPPAUGE_HVR4400 38 #define CX23885_BOARD_HAUPPAUGE_HVR4400 38
#define CX23885_BOARD_AVERMEDIA_HC81R 39 #define CX23885_BOARD_AVERMEDIA_HC81R 39
#define CX23885_BOARD_TBS_6981 40
#define CX23885_BOARD_TBS_6980 41
#define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42
#define GPIO_0 0x00000001 #define GPIO_0 0x00000001
#define GPIO_1 0x00000002 #define GPIO_1 0x00000002

View File

@ -45,5 +45,3 @@ struct cx25821_board cx25821_boards[] = {
}, },
}; };
const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);

View File

@ -438,7 +438,7 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
decoder_count = decoder_select + 1; decoder_count = decoder_select + 1;
} else { } else {
decoder = 0; decoder = 0;
decoder_count = _num_decoders; decoder_count = dev->_max_num_decoders;
} }
switch (width) { switch (width) {
@ -506,8 +506,6 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
break; break;
} }
_display_field_cnt[decoder] = duration;
/* update hardware */ /* update hardware */
fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
@ -667,8 +665,6 @@ int medusa_video_init(struct cx25821_dev *dev)
int ret_val = 0; int ret_val = 0;
int i = 0; int i = 0;
_num_decoders = dev->_max_num_decoders;
/* disable Auto source selection on all video decoders */ /* disable Auto source selection on all video decoders */
value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
value &= 0xFFFFF0FF; value &= 0xFFFFF0FF;
@ -685,8 +681,14 @@ int medusa_video_init(struct cx25821_dev *dev)
if (ret_val < 0) if (ret_val < 0)
goto error; goto error;
for (i = 0; i < _num_decoders; i++) /*
medusa_set_decoderduration(dev, i, _display_field_cnt[i]); * FIXME: due to a coding bug the duration was always 0. It's
* likely that it really should be something else, but due to the
* lack of documentation I have no idea what it should be. For
* now just fill in 0 as the duration.
*/
for (i = 0; i < dev->_max_num_decoders; i++)
medusa_set_decoderduration(dev, i, 0);
/* Select monitor as DENC A input, power up the DAC */ /* Select monitor as DENC A input, power up the DAC */
value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
@ -717,7 +719,7 @@ int medusa_video_init(struct cx25821_dev *dev)
/* Turn on all of the data out and control output pins. */ /* Turn on all of the data out and control output pins. */
value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
value &= 0xFEF0FE00; value &= 0xFEF0FE00;
if (_num_decoders == MAX_DECODERS) { if (dev->_max_num_decoders == MAX_DECODERS) {
/* /*
* Note: The octal board does not support control pins(bit16-19) * Note: The octal board does not support control pins(bit16-19)
* These bits are ignored in the octal board. * These bits are ignored in the octal board.

View File

@ -40,10 +40,4 @@
#define CONTRAST_DEFAULT 5000 #define CONTRAST_DEFAULT 5000
#define HUE_DEFAULT 5000 #define HUE_DEFAULT 5000
unsigned short _num_decoders;
unsigned short _num_cameras;
unsigned int _video_standard;
int _display_field_cnt[MAX_DECODERS];
#endif #endif

View File

@ -159,10 +159,10 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32
* For the upstream video channel, the risc engine will enable * For the upstream video channel, the risc engine will enable
* the FIFO. */ * the FIFO. */
if (fifo_enable && line == 3) { if (fifo_enable && line == 3) {
*(rp++) = RISC_WRITECR; *(rp++) = cpu_to_le32(RISC_WRITECR);
*(rp++) = sram_ch->dma_ctl; *(rp++) = cpu_to_le32(sram_ch->dma_ctl);
*(rp++) = FLD_VID_FIFO_EN; *(rp++) = cpu_to_le32(FLD_VID_FIFO_EN);
*(rp++) = 0x00000001; *(rp++) = cpu_to_le32(0x00000001);
} }
} }

View File

@ -834,7 +834,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,
/* get irq */ /* get irq */
err = request_irq(chip->pci->irq, cx8801_irq, err = request_irq(chip->pci->irq, cx8801_irq,
IRQF_SHARED | IRQF_DISABLED, chip->core->name, chip); IRQF_SHARED, chip->core->name, chip);
if (err < 0) { if (err < 0) {
dprintk(0, "%s: can't get IRQ %d\n", dprintk(0, "%s: can't get IRQ %d\n",
chip->core->name, chip->pci->irq); chip->core->name, chip->pci->irq);
@ -935,8 +935,6 @@ static void cx88_audio_finidev(struct pci_dev *pci)
snd_card_free((void *)card); snd_card_free((void *)card);
pci_set_drvdata(pci, NULL);
devno--; devno--;
} }
@ -951,27 +949,4 @@ static struct pci_driver cx88_audio_pci_driver = {
.remove = cx88_audio_finidev, .remove = cx88_audio_finidev,
}; };
/**************************************************************************** module_pci_driver(cx88_audio_pci_driver);
LINUX MODULE INIT
****************************************************************************/
/*
* module init
*/
static int __init cx88_audio_init(void)
{
printk(KERN_INFO "cx2388x alsa driver version %s loaded\n",
CX88_VERSION);
return pci_register_driver(&cx88_audio_pci_driver);
}
/*
* module remove
*/
static void __exit cx88_audio_fini(void)
{
pci_unregister_driver(&cx88_audio_pci_driver);
}
module_init(cx88_audio_init);
module_exit(cx88_audio_fini);

View File

@ -499,7 +499,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)
/* get irq */ /* get irq */
err = request_irq(dev->pci->irq, cx8802_irq, err = request_irq(dev->pci->irq, cx8802_irq,
IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev); IRQF_SHARED, dev->core->name, dev);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n", printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->core->name, dev->pci->irq); dev->core->name, dev->pci->irq);
@ -520,7 +520,6 @@ static void cx8802_fini_common(struct cx8802_dev *dev)
/* unregister stuff */ /* unregister stuff */
free_irq(dev->pci->irq, dev); free_irq(dev->pci->irq, dev);
pci_set_drvdata(dev->pci, NULL);
/* free memory */ /* free memory */
btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
@ -903,20 +902,8 @@ static struct pci_driver cx8802_pci_driver = {
.remove = cx8802_remove, .remove = cx8802_remove,
}; };
static int __init cx8802_init(void) module_pci_driver(cx8802_pci_driver);
{
printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %s loaded\n",
CX88_VERSION);
return pci_register_driver(&cx8802_pci_driver);
}
static void __exit cx8802_fini(void)
{
pci_unregister_driver(&cx8802_pci_driver);
}
module_init(cx8802_init);
module_exit(cx8802_fini);
EXPORT_SYMBOL(cx8802_buf_prepare); EXPORT_SYMBOL(cx8802_buf_prepare);
EXPORT_SYMBOL(cx8802_buf_queue); EXPORT_SYMBOL(cx8802_buf_queue);
EXPORT_SYMBOL(cx8802_cancel_buffers); EXPORT_SYMBOL(cx8802_cancel_buffers);

View File

@ -1738,7 +1738,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
/* get irq */ /* get irq */
err = request_irq(pci_dev->irq, cx8800_irq, err = request_irq(pci_dev->irq, cx8800_irq,
IRQF_SHARED | IRQF_DISABLED, core->name, dev); IRQF_SHARED, core->name, dev);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "%s/0: can't get IRQ %d\n", printk(KERN_ERR "%s/0: can't get IRQ %d\n",
core->name,pci_dev->irq); core->name,pci_dev->irq);
@ -1922,7 +1922,6 @@ static void cx8800_finidev(struct pci_dev *pci_dev)
free_irq(pci_dev->irq, dev); free_irq(pci_dev->irq, dev);
cx8800_unregister_video(dev); cx8800_unregister_video(dev);
pci_set_drvdata(pci_dev, NULL);
/* free memory */ /* free memory */
btcx_riscmem_free(dev->pci,&dev->vidq.stopper); btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
@ -2039,17 +2038,4 @@ static struct pci_driver cx8800_pci_driver = {
#endif #endif
}; };
static int __init cx8800_init(void) module_pci_driver(cx8800_pci_driver);
{
printk(KERN_INFO "cx88/0: cx2388x v4l2 driver version %s loaded\n",
CX88_VERSION);
return pci_register_driver(&cx8800_pci_driver);
}
static void __exit cx8800_fini(void)
{
pci_unregister_driver(&cx8800_pci_driver);
}
module_init(cx8800_init);
module_exit(cx8800_fini);

View File

@ -1544,7 +1544,7 @@ static void ddb_unmap(struct ddb *dev)
static void ddb_remove(struct pci_dev *pdev) static void ddb_remove(struct pci_dev *pdev)
{ {
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); struct ddb *dev = pci_get_drvdata(pdev);
ddb_ports_detach(dev); ddb_ports_detach(dev);
ddb_i2c_release(dev); ddb_i2c_release(dev);

View File

@ -1178,7 +1178,6 @@ static int dm1105_probe(struct pci_dev *pdev,
err_pci_disable_device: err_pci_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
err_kfree: err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(dev); kfree(dev);
return ret; return ret;
} }
@ -1202,8 +1201,7 @@ static void dm1105_remove(struct pci_dev *pdev)
dvb_dmxdev_release(&dev->dmxdev); dvb_dmxdev_release(&dev->dmxdev);
dvb_dmx_release(dvbdemux); dvb_dmx_release(dvbdemux);
dvb_unregister_adapter(dvb_adapter); dvb_unregister_adapter(dvb_adapter);
if (&dev->i2c_adap) i2c_del_adapter(&dev->i2c_adap);
i2c_del_adapter(&dev->i2c_adap);
dm1105_hw_exit(dev); dm1105_hw_exit(dev);
synchronize_irq(pdev->irq); synchronize_irq(pdev->irq);
@ -1211,7 +1209,6 @@ static void dm1105_remove(struct pci_dev *pdev)
pci_iounmap(pdev, dev->io_mem); pci_iounmap(pdev, dev->io_mem);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
dm1105_devcount--; dm1105_devcount--;
kfree(dev); kfree(dev);
} }

View File

@ -1261,7 +1261,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
/* Register IRQ */ /* Register IRQ */
retval = request_irq(itv->pdev->irq, ivtv_irq_handler, retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); IRQF_SHARED, itv->v4l2_dev.name, (void *)itv);
if (retval) { if (retval) {
IVTV_ERR("Failed to register irq %d\n", retval); IVTV_ERR("Failed to register irq %d\n", retval);
goto free_i2c; goto free_i2c;

View File

@ -143,7 +143,6 @@ int mantis_pci_init(struct mantis_pci *mantis)
fail0: fail0:
dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
pci_set_drvdata(pdev, NULL);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(mantis_pci_init); EXPORT_SYMBOL_GPL(mantis_pci_init);
@ -161,7 +160,6 @@ void mantis_pci_exit(struct mantis_pci *mantis)
} }
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
} }
EXPORT_SYMBOL_GPL(mantis_pci_exit); EXPORT_SYMBOL_GPL(mantis_pci_exit);

View File

@ -1698,7 +1698,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
meye.mchip_irq = pcidev->irq; meye.mchip_irq = pcidev->irq;
if (request_irq(meye.mchip_irq, meye_irq, if (request_irq(meye.mchip_irq, meye_irq,
IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) { IRQF_SHARED, "meye", meye_irq)) {
v4l2_err(v4l2_dev, "request_irq failed\n"); v4l2_err(v4l2_dev, "request_irq failed\n");
goto outreqirq; goto outreqirq;
} }

View File

@ -1622,7 +1622,7 @@ static void ngene_unlink(struct ngene *dev)
void ngene_shutdown(struct pci_dev *pdev) void ngene_shutdown(struct pci_dev *pdev)
{ {
struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); struct ngene *dev = pci_get_drvdata(pdev);
if (!dev || !shutdown_workaround) if (!dev || !shutdown_workaround)
return; return;
@ -1648,7 +1648,6 @@ void ngene_remove(struct pci_dev *pdev)
cxd_detach(dev); cxd_detach(dev);
ngene_stop(dev); ngene_stop(dev);
ngene_release_buffers(dev); ngene_release_buffers(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev); pci_disable_device(pdev);
} }
@ -1702,6 +1701,5 @@ int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
ngene_release_buffers(dev); ngene_release_buffers(dev);
fail0: fail0:
pci_disable_device(pci_dev); pci_disable_device(pci_dev);
pci_set_drvdata(pci_dev, NULL);
return stat; return stat;
} }

View File

@ -736,7 +736,6 @@ static int pluto2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_pci_disable_device: err_pci_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
err_kfree: err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(pluto); kfree(pluto);
goto out; goto out;
} }
@ -765,7 +764,6 @@ static void pluto2_remove(struct pci_dev *pdev)
pci_iounmap(pdev, pluto->io_mem); pci_iounmap(pdev, pluto->io_mem);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
kfree(pluto); kfree(pluto);
} }

View File

@ -1076,7 +1076,6 @@ static void pt1_remove(struct pci_dev *pdev)
pt1_update_power(pt1); pt1_update_power(pt1);
pt1_cleanup_adapters(pt1); pt1_cleanup_adapters(pt1);
i2c_del_adapter(&pt1->i2c_adap); i2c_del_adapter(&pt1->i2c_adap);
pci_set_drvdata(pdev, NULL);
kfree(pt1); kfree(pt1);
pci_iounmap(pdev, regs); pci_iounmap(pdev, regs);
pci_release_regions(pdev); pci_release_regions(pdev);
@ -1198,7 +1197,6 @@ static int pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_pt1_cleanup_adapters: err_pt1_cleanup_adapters:
pt1_cleanup_adapters(pt1); pt1_cleanup_adapters(pt1);
err_kfree: err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(pt1); kfree(pt1);
err_pci_iounmap: err_pci_iounmap:
pci_iounmap(pdev, regs); pci_iounmap(pdev, regs);

View File

@ -1096,7 +1096,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
err = request_irq(dev->pci->irq, saa7134_alsa_irq, err = request_irq(dev->pci->irq, saa7134_alsa_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, IRQF_SHARED, dev->name,
(void*) &dev->dmasound); (void*) &dev->dmasound);
if (err < 0) { if (err < 0) {

View File

@ -992,7 +992,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
/* get irq */ /* get irq */
err = request_irq(pci_dev->irq, saa7134_irq, err = request_irq(pci_dev->irq, saa7134_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev); IRQF_SHARED, dev->name, dev);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n", printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->name,pci_dev->irq); dev->name,pci_dev->irq);

View File

@ -1232,7 +1232,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
} }
err = request_irq(pci_dev->irq, saa7164_irq, err = request_irq(pci_dev->irq, saa7164_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev); IRQF_SHARED, dev->name, dev);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
pci_dev->irq); pci_dev->irq);
@ -1439,7 +1439,6 @@ static void saa7164_finidev(struct pci_dev *pci_dev)
/* unregister stuff */ /* unregister stuff */
free_irq(pci_dev->irq, dev); free_irq(pci_dev->irq, dev);
pci_set_drvdata(pci_dev, NULL);
mutex_lock(&devlist); mutex_lock(&devlist);
list_del(&dev->devlist); list_del(&dev->devlist);

View File

@ -1293,7 +1293,7 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
result = request_irq(zr->pci_dev->irq, zoran_irq, result = request_irq(zr->pci_dev->irq, zoran_irq,
IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); IRQF_SHARED, ZR_DEVNAME(zr), zr);
if (result < 0) { if (result < 0) {
if (result == -EINVAL) { if (result == -EINVAL) {
dprintk(1, dprintk(1,

View File

@ -143,6 +143,7 @@ if V4L_MEM2MEM_DRIVERS
config VIDEO_CODA config VIDEO_CODA
tristate "Chips&Media Coda multi-standard codec IP" tristate "Chips&Media Coda multi-standard codec IP"
depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
select SRAM
select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV select V4L2_MEM2MEM_DEV
---help--- ---help---
@ -212,7 +213,7 @@ config VIDEO_SH_VEU
config VIDEO_RENESAS_VSP1 config VIDEO_RENESAS_VSP1
tristate "Renesas VSP1 Video Processing Engine" tristate "Renesas VSP1 Video Processing Engine"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_DMA_CONTIG
---help--- ---help---
This is a V4L2 driver for the Renesas VSP1 video processing engine. This is a V4L2 driver for the Renesas VSP1 video processing engine.
@ -220,6 +221,22 @@ config VIDEO_RENESAS_VSP1
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called vsp1. will be called vsp1.
config VIDEO_TI_VPE
tristate "TI VPE (Video Processing Engine) driver"
depends on VIDEO_DEV && VIDEO_V4L2 && SOC_DRA7XX
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
default n
---help---
Support for the TI VPE(Video Processing Engine) block
found on DRA7XX SoC.
config VIDEO_TI_VPE_DEBUG
bool "VPE debug messages"
depends on VIDEO_TI_VPE
---help---
Enable debug messages on VPE driver.
endif # V4L_MEM2MEM_DRIVERS endif # V4L_MEM2MEM_DRIVERS
menuconfig V4L_TEST_DRIVERS menuconfig V4L_TEST_DRIVERS

View File

@ -22,6 +22,8 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
obj-$(CONFIG_VIDEO_CODA) += coda.o obj-$(CONFIG_VIDEO_CODA) += coda.o

View File

@ -39,7 +39,7 @@
#define CODA_NAME "coda" #define CODA_NAME "coda"
#define CODA_MAX_INSTANCES 4 #define CODADX6_MAX_INSTANCES 4
#define CODA_FMO_BUF_SIZE 32 #define CODA_FMO_BUF_SIZE 32
#define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
@ -54,8 +54,6 @@
#define CODA_MAX_FRAMEBUFFERS 8 #define CODA_MAX_FRAMEBUFFERS 8
#define MAX_W 8192
#define MAX_H 8192
#define CODA_MAX_FRAME_SIZE 0x100000 #define CODA_MAX_FRAME_SIZE 0x100000
#define FMO_SLICE_SAVE_BUF_SIZE (32) #define FMO_SLICE_SAVE_BUF_SIZE (32)
#define CODA_DEFAULT_GAMMA 4096 #define CODA_DEFAULT_GAMMA 4096
@ -394,14 +392,57 @@ static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc,
return &codecs[k]; return &codecs[k];
} }
static void coda_get_max_dimensions(struct coda_dev *dev,
struct coda_codec *codec,
int *max_w, int *max_h)
{
struct coda_codec *codecs = dev->devtype->codecs;
int num_codecs = dev->devtype->num_codecs;
unsigned int w, h;
int k;
if (codec) {
w = codec->max_w;
h = codec->max_h;
} else {
for (k = 0, w = 0, h = 0; k < num_codecs; k++) {
w = max(w, codecs[k].max_w);
h = max(h, codecs[k].max_h);
}
}
if (max_w)
*max_w = w;
if (max_h)
*max_h = h;
}
static char *coda_product_name(int product)
{
static char buf[9];
switch (product) {
case CODA_DX6:
return "CodaDx6";
case CODA_7541:
return "CODA7541";
default:
snprintf(buf, sizeof(buf), "(0x%04x)", product);
return buf;
}
}
/* /*
* V4L2 ioctl() operations. * V4L2 ioctl() operations.
*/ */
static int vidioc_querycap(struct file *file, void *priv, static int coda_querycap(struct file *file, void *priv,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv);
strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
strlcpy(cap->card, CODA_NAME, sizeof(cap->card)); strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product),
sizeof(cap->card));
strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
/* /*
* This is only a mem-to-mem video device. The capture and output * This is only a mem-to-mem video device. The capture and output
@ -457,6 +498,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
fmt = &formats[i]; fmt = &formats[i];
strlcpy(f->description, fmt->name, sizeof(f->description)); strlcpy(f->description, fmt->name, sizeof(f->description));
f->pixelformat = fmt->fourcc; f->pixelformat = fmt->fourcc;
if (!coda_format_is_yuv(fmt->fourcc))
f->flags |= V4L2_FMT_FLAG_COMPRESSED;
return 0; return 0;
} }
@ -464,8 +507,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
return -EINVAL; return -EINVAL;
} }
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int coda_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
struct vb2_queue *src_vq; struct vb2_queue *src_vq;
@ -483,13 +526,14 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0);
} }
static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, static int coda_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0);
} }
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) static int coda_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{ {
struct vb2_queue *vq; struct vb2_queue *vq;
struct coda_q_data *q_data; struct coda_q_data *q_data;
@ -516,8 +560,11 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
return 0; return 0;
} }
static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f) static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
struct v4l2_format *f)
{ {
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data;
unsigned int max_w, max_h; unsigned int max_w, max_h;
enum v4l2_field field; enum v4l2_field field;
@ -531,32 +578,48 @@ static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
* if any of the dimensions is unsupported */ * if any of the dimensions is unsupported */
f->fmt.pix.field = field; f->fmt.pix.field = field;
if (codec) { coda_get_max_dimensions(dev, codec, &max_w, &max_h);
max_w = codec->max_w; v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN,
max_h = codec->max_h; &f->fmt.pix.height, MIN_H, max_h, H_ALIGN,
} else { S_ALIGN);
max_w = MAX_W;
max_h = MAX_H;
}
v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
W_ALIGN, &f->fmt.pix.height,
MIN_H, max_h, H_ALIGN, S_ALIGN);
if (coda_format_is_yuv(f->fmt.pix.pixelformat)) { switch (f->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
case V4L2_PIX_FMT_H264:
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_JPEG:
break;
default:
q_data = get_q_data(ctx, f->type);
f->fmt.pix.pixelformat = q_data->fourcc;
}
switch (f->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
/* Frame stride must be multiple of 8 */ /* Frame stride must be multiple of 8 */
f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8); f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
f->fmt.pix.height * 3 / 2; f->fmt.pix.height * 3 / 2;
} else { /*encoded formats h.264/mpeg4 */ break;
case V4L2_PIX_FMT_H264:
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_JPEG:
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
break;
default:
BUG();
} }
f->fmt.pix.priv = 0;
return 0; return 0;
} }
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int coda_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
struct coda_codec *codec; struct coda_codec *codec;
@ -584,7 +647,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.colorspace = ctx->colorspace; f->fmt.pix.colorspace = ctx->colorspace;
ret = vidioc_try_fmt(codec, f); ret = coda_try_fmt(ctx, codec, f);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -600,8 +663,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return 0; return 0;
} }
static int vidioc_try_fmt_vid_out(struct file *file, void *priv, static int coda_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
struct coda_codec *codec; struct coda_codec *codec;
@ -613,10 +676,10 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
if (!f->fmt.pix.colorspace) if (!f->fmt.pix.colorspace)
f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
return vidioc_try_fmt(codec, f); return coda_try_fmt(ctx, codec, f);
} }
static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
{ {
struct coda_q_data *q_data; struct coda_q_data *q_data;
struct vb2_queue *vq; struct vb2_queue *vq;
@ -646,61 +709,62 @@ static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
return 0; return 0;
} }
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int coda_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
int ret; int ret;
ret = vidioc_try_fmt_vid_cap(file, priv, f); ret = coda_try_fmt_vid_cap(file, priv, f);
if (ret) if (ret)
return ret; return ret;
return vidioc_s_fmt(ctx, f); return coda_s_fmt(ctx, f);
} }
static int vidioc_s_fmt_vid_out(struct file *file, void *priv, static int coda_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
int ret; int ret;
ret = vidioc_try_fmt_vid_out(file, priv, f); ret = coda_try_fmt_vid_out(file, priv, f);
if (ret) if (ret)
return ret; return ret;
ret = vidioc_s_fmt(ctx, f); ret = coda_s_fmt(ctx, f);
if (ret) if (ret)
ctx->colorspace = f->fmt.pix.colorspace; ctx->colorspace = f->fmt.pix.colorspace;
return ret; return ret;
} }
static int vidioc_reqbufs(struct file *file, void *priv, static int coda_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *reqbufs) struct v4l2_requestbuffers *reqbufs)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
} }
static int vidioc_querybuf(struct file *file, void *priv, static int coda_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf) struct v4l2_buffer *buf)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
} }
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) static int coda_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
} }
static int vidioc_expbuf(struct file *file, void *priv, static int coda_expbuf(struct file *file, void *priv,
struct v4l2_exportbuffer *eb) struct v4l2_exportbuffer *eb)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
@ -718,7 +782,8 @@ static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx,
(buf->sequence == (ctx->qsequence - 1))); (buf->sequence == (ctx->qsequence - 1)));
} }
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) static int coda_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
int ret; int ret;
@ -738,24 +803,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
return ret; return ret;
} }
static int vidioc_create_bufs(struct file *file, void *priv, static int coda_create_bufs(struct file *file, void *priv,
struct v4l2_create_buffers *create) struct v4l2_create_buffers *create)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create);
} }
static int vidioc_streamon(struct file *file, void *priv, static int coda_streamon(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
} }
static int vidioc_streamoff(struct file *file, void *priv, static int coda_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct coda_ctx *ctx = fh_to_ctx(priv); struct coda_ctx *ctx = fh_to_ctx(priv);
int ret; int ret;
@ -772,23 +837,34 @@ static int vidioc_streamoff(struct file *file, void *priv,
return ret; return ret;
} }
static int vidioc_decoder_cmd(struct file *file, void *fh, static int coda_try_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *dc) struct v4l2_decoder_cmd *dc)
{ {
struct coda_ctx *ctx = fh_to_ctx(fh);
if (dc->cmd != V4L2_DEC_CMD_STOP) if (dc->cmd != V4L2_DEC_CMD_STOP)
return -EINVAL; return -EINVAL;
if ((dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) || if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY))
return -EINVAL; return -EINVAL;
if (dc->stop.pts != 0) if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0))
return -EINVAL; return -EINVAL;
return 0;
}
static int coda_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *dc)
{
struct coda_ctx *ctx = fh_to_ctx(fh);
int ret;
ret = coda_try_decoder_cmd(file, fh, dc);
if (ret < 0)
return ret;
/* Ignore decoder stop command silently in encoder context */
if (ctx->inst_type != CODA_INST_DECODER) if (ctx->inst_type != CODA_INST_DECODER)
return -EINVAL; return 0;
/* Set the strem-end flag on this context */ /* Set the strem-end flag on this context */
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
@ -796,8 +872,8 @@ static int vidioc_decoder_cmd(struct file *file, void *fh,
return 0; return 0;
} }
static int vidioc_subscribe_event(struct v4l2_fh *fh, static int coda_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub) const struct v4l2_event_subscription *sub)
{ {
switch (sub->type) { switch (sub->type) {
case V4L2_EVENT_EOS: case V4L2_EVENT_EOS:
@ -808,32 +884,33 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh,
} }
static const struct v4l2_ioctl_ops coda_ioctl_ops = { static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_querycap = vidioc_querycap, .vidioc_querycap = coda_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_enum_fmt_vid_cap = coda_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt, .vidioc_g_fmt_vid_cap = coda_g_fmt,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_try_fmt_vid_cap = coda_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_s_fmt_vid_cap = coda_s_fmt_vid_cap,
.vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, .vidioc_enum_fmt_vid_out = coda_enum_fmt_vid_out,
.vidioc_g_fmt_vid_out = vidioc_g_fmt, .vidioc_g_fmt_vid_out = coda_g_fmt,
.vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out,
.vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out,
.vidioc_reqbufs = vidioc_reqbufs, .vidioc_reqbufs = coda_reqbufs,
.vidioc_querybuf = vidioc_querybuf, .vidioc_querybuf = coda_querybuf,
.vidioc_qbuf = vidioc_qbuf, .vidioc_qbuf = coda_qbuf,
.vidioc_expbuf = vidioc_expbuf, .vidioc_expbuf = coda_expbuf,
.vidioc_dqbuf = vidioc_dqbuf, .vidioc_dqbuf = coda_dqbuf,
.vidioc_create_bufs = vidioc_create_bufs, .vidioc_create_bufs = coda_create_bufs,
.vidioc_streamon = vidioc_streamon, .vidioc_streamon = coda_streamon,
.vidioc_streamoff = vidioc_streamoff, .vidioc_streamoff = coda_streamoff,
.vidioc_decoder_cmd = vidioc_decoder_cmd, .vidioc_try_decoder_cmd = coda_try_decoder_cmd,
.vidioc_decoder_cmd = coda_decoder_cmd,
.vidioc_subscribe_event = vidioc_subscribe_event, .vidioc_subscribe_event = coda_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
}; };
@ -1928,8 +2005,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
if (!(ctx->streamon_out & ctx->streamon_cap)) if (!(ctx->streamon_out & ctx->streamon_cap))
return 0; return 0;
/* Allow device_run with no buffers queued and after streamoff */ /* Allow decoder device_run with no new buffers queued */
v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true); if (ctx->inst_type == CODA_INST_DECODER)
v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true);
ctx->gopcounter = ctx->params.gop_size - 1; ctx->gopcounter = ctx->params.gop_size - 1;
buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
@ -2071,10 +2149,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
coda_setup_iram(ctx); coda_setup_iram(ctx);
if (dst_fourcc == V4L2_PIX_FMT_H264) { if (dst_fourcc == V4L2_PIX_FMT_H264) {
value = (FMO_SLICE_SAVE_BUF_SIZE << 7);
value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
value |= 0 & CODA_FMOPARAM_SLICENUM_MASK;
if (dev->devtype->product == CODA_DX6) { if (dev->devtype->product == CODA_DX6) {
value = FMO_SLICE_SAVE_BUF_SIZE << 7;
coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
} else { } else {
coda_write(dev, ctx->iram_info.search_ram_paddr, coda_write(dev, ctx->iram_info.search_ram_paddr,
@ -2371,7 +2447,13 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
static int coda_next_free_instance(struct coda_dev *dev) static int coda_next_free_instance(struct coda_dev *dev)
{ {
return ffz(dev->instance_mask); int idx = ffz(dev->instance_mask);
if ((idx < 0) ||
(dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES))
return -EBUSY;
return idx;
} }
static int coda_open(struct file *file) static int coda_open(struct file *file)
@ -2386,8 +2468,8 @@ static int coda_open(struct file *file)
return -ENOMEM; return -ENOMEM;
idx = coda_next_free_instance(dev); idx = coda_next_free_instance(dev);
if (idx >= CODA_MAX_INSTANCES) { if (idx < 0) {
ret = -EBUSY; ret = idx;
goto err_coda_max; goto err_coda_max;
} }
set_bit(idx, &dev->instance_mask); set_bit(idx, &dev->instance_mask);
@ -2719,7 +2801,6 @@ static void coda_finish_encode(struct coda_ctx *ctx)
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
/* Get results from the coda */ /* Get results from the coda */
coda_read(dev, CODA_RET_ENC_PIC_TYPE);
start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
@ -2739,7 +2820,7 @@ static void coda_finish_encode(struct coda_ctx *ctx)
coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM);
coda_read(dev, CODA_RET_ENC_PIC_FLAG); coda_read(dev, CODA_RET_ENC_PIC_FLAG);
if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) {
dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
} else { } else {
@ -2861,21 +2942,6 @@ static bool coda_firmware_supported(u32 vernum)
return false; return false;
} }
static char *coda_product_name(int product)
{
static char buf[9];
switch (product) {
case CODA_DX6:
return "CodaDx6";
case CODA_7541:
return "CODA7541";
default:
snprintf(buf, sizeof(buf), "(0x%04x)", product);
return buf;
}
}
static int coda_hw_init(struct coda_dev *dev) static int coda_hw_init(struct coda_dev *dev)
{ {
u16 product, major, minor, release; u16 product, major, minor, release;

View File

@ -1785,7 +1785,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
} }
irq = res->start; irq = res->start;
err = devm_request_irq(&pdev->dev, irq, venc_isr, IRQF_DISABLED, err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
VPBE_DISPLAY_DRIVER, disp_dev); VPBE_DISPLAY_DRIVER, disp_dev);
if (err) { if (err) {
v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,

View File

@ -688,7 +688,7 @@ static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
frame_format = ccdc_dev->hw_ops.get_frame_format(); frame_format = ccdc_dev->hw_ops.get_frame_format();
if (frame_format == CCDC_FRMFMT_PROGRESSIVE) { if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr, return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
IRQF_DISABLED, "vpfe_capture1", 0, "vpfe_capture1",
vpfe_dev); vpfe_dev);
} }
return 0; return 0;
@ -1863,7 +1863,7 @@ static int vpfe_probe(struct platform_device *pdev)
} }
vpfe_dev->ccdc_irq1 = res1->start; vpfe_dev->ccdc_irq1 = res1->start;
ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
"vpfe_capture0", vpfe_dev); "vpfe_capture0", vpfe_dev);
if (0 != ret) { if (0 != ret) {

View File

@ -2154,7 +2154,7 @@ static __init int vpif_probe(struct platform_device *pdev)
if (!vpif_obj.sd[i]) { if (!vpif_obj.sd[i]) {
vpif_err("Error registering v4l2 subdevice\n"); vpif_err("Error registering v4l2 subdevice\n");
err = -ENOMEM; err = -ENODEV;
goto probe_subdev_out; goto probe_subdev_out;
} }
v4l2_info(&vpif_obj.v4l2_dev, v4l2_info(&vpif_obj.v4l2_dev,

View File

@ -45,6 +45,7 @@
#define GSC_DST_FMT (1 << 2) #define GSC_DST_FMT (1 << 2)
#define GSC_CTX_M2M (1 << 3) #define GSC_CTX_M2M (1 << 3)
#define GSC_CTX_STOP_REQ (1 << 6) #define GSC_CTX_STOP_REQ (1 << 6)
#define GSC_CTX_ABORT (1 << 7)
enum gsc_dev_flags { enum gsc_dev_flags {
/* for global */ /* for global */

View File

@ -46,6 +46,17 @@ static int gsc_m2m_ctx_stop_req(struct gsc_ctx *ctx)
return ret == 0 ? -ETIMEDOUT : ret; return ret == 0 ? -ETIMEDOUT : ret;
} }
static void __gsc_m2m_job_abort(struct gsc_ctx *ctx)
{
int ret;
ret = gsc_m2m_ctx_stop_req(ctx);
if ((ret == -ETIMEDOUT) || (ctx->state & GSC_CTX_ABORT)) {
gsc_ctx_state_lock_clear(GSC_CTX_STOP_REQ | GSC_CTX_ABORT, ctx);
gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
}
}
static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
{ {
struct gsc_ctx *ctx = q->drv_priv; struct gsc_ctx *ctx = q->drv_priv;
@ -58,11 +69,8 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
static int gsc_m2m_stop_streaming(struct vb2_queue *q) static int gsc_m2m_stop_streaming(struct vb2_queue *q)
{ {
struct gsc_ctx *ctx = q->drv_priv; struct gsc_ctx *ctx = q->drv_priv;
int ret;
ret = gsc_m2m_ctx_stop_req(ctx); __gsc_m2m_job_abort(ctx);
if (ret == -ETIMEDOUT)
gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
pm_runtime_put(&ctx->gsc_dev->pdev->dev); pm_runtime_put(&ctx->gsc_dev->pdev->dev);
@ -91,15 +99,9 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
} }
} }
static void gsc_m2m_job_abort(void *priv) static void gsc_m2m_job_abort(void *priv)
{ {
struct gsc_ctx *ctx = priv; __gsc_m2m_job_abort((struct gsc_ctx *)priv);
int ret;
ret = gsc_m2m_ctx_stop_req(ctx);
if (ret == -ETIMEDOUT)
gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
} }
static int gsc_get_bufs(struct gsc_ctx *ctx) static int gsc_get_bufs(struct gsc_ctx *ctx)
@ -150,9 +152,10 @@ static void gsc_m2m_device_run(void *priv)
gsc->m2m.ctx = ctx; gsc->m2m.ctx = ctx;
} }
is_set = (ctx->state & GSC_CTX_STOP_REQ) ? 1 : 0; is_set = ctx->state & GSC_CTX_STOP_REQ;
ctx->state &= ~GSC_CTX_STOP_REQ;
if (is_set) { if (is_set) {
ctx->state &= ~GSC_CTX_STOP_REQ;
ctx->state |= GSC_CTX_ABORT;
wake_up(&gsc->irq_queue); wake_up(&gsc->irq_queue);
goto put_device; goto put_device;
} }

View File

@ -511,7 +511,7 @@ static int __ctrl_set_metering(struct fimc_is *is, unsigned int value)
break; break;
default: default:
return -EINVAL; return -EINVAL;
}; }
__is_set_isp_metering(is, IS_METERING_CONFIG_CMD, val); __is_set_isp_metering(is, IS_METERING_CONFIG_CMD, val);
return 0; return 0;

View File

@ -1084,8 +1084,7 @@ static int deinterlace_probe(struct platform_device *pdev)
static int deinterlace_remove(struct platform_device *pdev) static int deinterlace_remove(struct platform_device *pdev)
{ {
struct deinterlace_dev *pcdev = struct deinterlace_dev *pcdev = platform_get_drvdata(pdev);
(struct deinterlace_dev *)platform_get_drvdata(pdev);
v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
v4l2_m2m_release(pcdev->m2m_dev); v4l2_m2m_release(pcdev->m2m_dev);

View File

@ -1221,16 +1221,16 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
{ {
struct mcam_vb_buffer *mvb = vb_to_mvb(vb); struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
struct mcam_dma_desc *desc = mvb->dma_desc; struct mcam_dma_desc *desc = mvb->dma_desc;
struct scatterlist *sg; struct scatterlist *sg;
int i; int i;
mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages, mvb->dma_desc_nent = dma_map_sg(cam->dev, sg_table->sgl,
DMA_FROM_DEVICE); sg_table->nents, DMA_FROM_DEVICE);
if (mvb->dma_desc_nent <= 0) if (mvb->dma_desc_nent <= 0)
return -EIO; /* Not sure what's right here */ return -EIO; /* Not sure what's right here */
for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) { for_each_sg(sg_table->sgl, sg, mvb->dma_desc_nent, i) {
desc->dma_addr = sg_dma_address(sg); desc->dma_addr = sg_dma_address(sg);
desc->segment_len = sg_dma_len(sg); desc->segment_len = sg_dma_len(sg);
desc++; desc++;
@ -1241,9 +1241,11 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
{ {
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE); if (sg_table)
dma_unmap_sg(cam->dev, sg_table->sgl,
sg_table->nents, DMA_FROM_DEVICE);
return 0; return 0;
} }

View File

@ -481,7 +481,6 @@ static int mmpcam_remove(struct mmp_camera *cam)
struct mmp_camera_platform_data *pdata; struct mmp_camera_platform_data *pdata;
mmpcam_remove_device(cam); mmpcam_remove_device(cam);
free_irq(cam->irq, mcam);
mccic_shutdown(mcam); mccic_shutdown(mcam);
mmpcam_power_down(mcam); mmpcam_power_down(mcam);
pdata = cam->pdev->dev.platform_data; pdata = cam->pdev->dev.platform_data;

View File

@ -1090,8 +1090,7 @@ static int m2mtest_probe(struct platform_device *pdev)
static int m2mtest_remove(struct platform_device *pdev) static int m2mtest_remove(struct platform_device *pdev)
{ {
struct m2mtest_dev *dev = struct m2mtest_dev *dev = platform_get_drvdata(pdev);
(struct m2mtest_dev *)platform_get_drvdata(pdev);
v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
v4l2_m2m_release(dev->m2m_dev); v4l2_m2m_release(dev->m2m_dev);

View File

@ -840,7 +840,7 @@ static int g2d_probe(struct platform_device *pdev)
static int g2d_remove(struct platform_device *pdev) static int g2d_remove(struct platform_device *pdev)
{ {
struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev); struct g2d_dev *dev = platform_get_drvdata(pdev);
v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME); v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME);
v4l2_m2m_release(dev->m2m_dev); v4l2_m2m_release(dev->m2m_dev);

View File

@ -404,7 +404,11 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
if (test_and_clear_bit(0, &dev->hw_lock) == 0) if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG(); BUG();
s5p_mfc_clock_off(); s5p_mfc_clock_off();
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); /* if suspending, wake up device and do not try_run again*/
if (test_bit(0, &dev->enter_suspend))
wake_up_dev(dev, reason, err);
else
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
} }
/* Error handling for interrupt */ /* Error handling for interrupt */
@ -1101,7 +1105,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
} }
dev->irq = res->start; dev->irq = res->start;
ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq, ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq,
IRQF_DISABLED, pdev->name, dev); 0, pdev->name, dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
goto err_res; goto err_res;
@ -1286,9 +1290,7 @@ static int s5p_mfc_suspend(struct device *dev)
/* Try and lock the HW */ /* Try and lock the HW */
/* Wait on the interrupt waitqueue */ /* Wait on the interrupt waitqueue */
ret = wait_event_interruptible_timeout(m_dev->queue, ret = wait_event_interruptible_timeout(m_dev->queue,
m_dev->int_cond || m_dev->ctx[m_dev->curr_ctx]->int_cond, m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT));
msecs_to_jiffies(MFC_INT_TIMEOUT));
if (ret == 0) { if (ret == 0) {
mfc_err("Waiting for hardware to finish timed out\n"); mfc_err("Waiting for hardware to finish timed out\n");
return -EIO; return -EIO;

View File

@ -111,7 +111,7 @@ static int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
break; break;
default: default:
h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; h2r_args.arg[0] = S5P_FIMV_CODEC_NONE;
}; }
h2r_args.arg[1] = 0; /* no crc & no pixelcache */ h2r_args.arg[1] = 0; /* no crc & no pixelcache */
h2r_args.arg[2] = ctx->ctx.ofs; h2r_args.arg[2] = ctx->ctx.ofs;
h2r_args.arg[3] = ctx->ctx.size; h2r_args.arg[3] = ctx->ctx.size;

View File

@ -113,7 +113,7 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
break; break;
default: default:
codec_type = S5P_FIMV_CODEC_NONE_V6; codec_type = S5P_FIMV_CODEC_NONE_V6;
}; }
mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6); mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6);
mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6); mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6);

View File

@ -113,7 +113,7 @@ static struct mfc_control controls[] = {
.minimum = 0, .minimum = 0,
.maximum = (1 << 16) - 1, .maximum = (1 << 16) - 1,
.step = 1, .step = 1,
.default_value = 0, .default_value = 12,
}, },
{ {
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
@ -356,7 +356,7 @@ static struct mfc_control controls[] = {
.minimum = 0, .minimum = 0,
.maximum = 51, .maximum = 51,
.step = 1, .step = 1,
.default_value = 1, .default_value = 51,
}, },
{ {
.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
@ -399,7 +399,7 @@ static struct mfc_control controls[] = {
.minimum = 1, .minimum = 1,
.maximum = 31, .maximum = 31,
.step = 1, .step = 1,
.default_value = 1, .default_value = 31,
}, },
{ {
.id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
@ -444,7 +444,7 @@ static struct mfc_control controls[] = {
.minimum = 0, .minimum = 0,
.maximum = 51, .maximum = 51,
.step = 1, .step = 1,
.default_value = 1, .default_value = 51,
}, },
{ {
.id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,

View File

@ -1582,7 +1582,7 @@ static int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev)
break; break;
default: default:
reason = S5P_MFC_R2H_CMD_EMPTY; reason = S5P_MFC_R2H_CMD_EMPTY;
}; }
return reason; return reason;
} }

View File

@ -226,7 +226,7 @@ static void mxr_graph_fix_geometry(struct mxr_layer *layer,
src->width + src->x_offset, 32767); src->width + src->x_offset, 32767);
src->full_height = clamp_val(src->full_height, src->full_height = clamp_val(src->full_height,
src->height + src->y_offset, 2047); src->height + src->y_offset, 2047);
}; }
} }
/* PUBLIC API */ /* PUBLIC API */

View File

@ -197,7 +197,7 @@ static void mxr_vp_fix_geometry(struct mxr_layer *layer,
ALIGN(src->width + src->x_offset, 8), 8192U); ALIGN(src->width + src->x_offset, 8), 8192U);
src->full_height = clamp(src->full_height, src->full_height = clamp(src->full_height,
src->height + src->y_offset, 8192U); src->height + src->y_offset, 8192U);
}; }
} }
/* PUBLIC API */ /* PUBLIC API */

View File

@ -105,6 +105,7 @@
#define VIN_MAX_HEIGHT 2048 #define VIN_MAX_HEIGHT 2048
enum chip_id { enum chip_id {
RCAR_H2,
RCAR_H1, RCAR_H1,
RCAR_M1, RCAR_M1,
RCAR_E1, RCAR_E1,
@ -300,7 +301,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
dmr = 0; dmr = 0;
break; break;
case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_RGB32:
if (priv->chip == RCAR_H1 || priv->chip == RCAR_E1) { if (priv->chip == RCAR_H2 || priv->chip == RCAR_H1 ||
priv->chip == RCAR_E1) {
dmr = VNDMR_EXRGB; dmr = VNDMR_EXRGB;
break; break;
} }
@ -1381,6 +1383,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
}; };
static struct platform_device_id rcar_vin_id_table[] = { static struct platform_device_id rcar_vin_id_table[] = {
{ "r8a7790-vin", RCAR_H2 },
{ "r8a7779-vin", RCAR_H1 }, { "r8a7779-vin", RCAR_H1 },
{ "r8a7778-vin", RCAR_M1 }, { "r8a7778-vin", RCAR_M1 },
{ "uPD35004-vin", RCAR_E1 }, { "uPD35004-vin", RCAR_E1 },

View File

@ -1800,7 +1800,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
/* request irq */ /* request irq */
err = devm_request_irq(&pdev->dev, pcdev->irq, sh_mobile_ceu_irq, err = devm_request_irq(&pdev->dev, pcdev->irq, sh_mobile_ceu_irq,
IRQF_DISABLED, dev_name(&pdev->dev), pcdev); 0, dev_name(&pdev->dev), pcdev);
if (err) { if (err) {
dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
goto exit_release_mem; goto exit_release_mem;

View File

@ -71,13 +71,23 @@ static int video_dev_create(struct soc_camera_device *icd);
int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
struct v4l2_clk *clk) struct v4l2_clk *clk)
{ {
int ret = clk ? v4l2_clk_enable(clk) : 0; int ret;
if (ret < 0) { bool clock_toggle;
dev_err(dev, "Cannot enable clock: %d\n", ret);
return ret; if (clk && (!ssdd->unbalanced_power ||
!test_and_set_bit(0, &ssdd->clock_state))) {
ret = v4l2_clk_enable(clk);
if (ret < 0) {
dev_err(dev, "Cannot enable clock: %d\n", ret);
return ret;
}
clock_toggle = true;
} else {
clock_toggle = false;
} }
ret = regulator_bulk_enable(ssdd->num_regulators,
ssdd->regulators); ret = regulator_bulk_enable(ssdd->sd_pdata.num_regulators,
ssdd->sd_pdata.regulators);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Cannot enable regulators\n"); dev_err(dev, "Cannot enable regulators\n");
goto eregenable; goto eregenable;
@ -95,10 +105,10 @@ int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
return 0; return 0;
epwron: epwron:
regulator_bulk_disable(ssdd->num_regulators, regulator_bulk_disable(ssdd->sd_pdata.num_regulators,
ssdd->regulators); ssdd->sd_pdata.regulators);
eregenable: eregenable:
if (clk) if (clock_toggle)
v4l2_clk_disable(clk); v4l2_clk_disable(clk);
return ret; return ret;
@ -120,14 +130,14 @@ int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd
} }
} }
err = regulator_bulk_disable(ssdd->num_regulators, err = regulator_bulk_disable(ssdd->sd_pdata.num_regulators,
ssdd->regulators); ssdd->sd_pdata.regulators);
if (err < 0) { if (err < 0) {
dev_err(dev, "Cannot disable regulators\n"); dev_err(dev, "Cannot disable regulators\n");
ret = ret ? : err; ret = ret ? : err;
} }
if (clk) if (clk && (!ssdd->unbalanced_power || test_and_clear_bit(0, &ssdd->clock_state)))
v4l2_clk_disable(clk); v4l2_clk_disable(clk);
return ret; return ret;
@ -137,8 +147,8 @@ EXPORT_SYMBOL(soc_camera_power_off);
int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd)
{ {
/* Should not have any effect in synchronous case */ /* Should not have any effect in synchronous case */
return devm_regulator_bulk_get(dev, ssdd->num_regulators, return devm_regulator_bulk_get(dev, ssdd->sd_pdata.num_regulators,
ssdd->regulators); ssdd->sd_pdata.regulators);
} }
EXPORT_SYMBOL(soc_camera_power_init); EXPORT_SYMBOL(soc_camera_power_init);
@ -1346,8 +1356,8 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd,
* soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try
* to allocate them again. * to allocate them again.
*/ */
ssdd->num_regulators = 0; ssdd->sd_pdata.num_regulators = 0;
ssdd->regulators = NULL; ssdd->sd_pdata.regulators = NULL;
shd->board_info->platform_data = ssdd; shd->board_info->platform_data = ssdd;
snprintf(clk_name, sizeof(clk_name), "%d-%04x", snprintf(clk_name, sizeof(clk_name), "%d-%04x",
@ -2020,8 +2030,8 @@ static int soc_camera_pdrv_probe(struct platform_device *pdev)
* that case regulators are attached to the I2C device and not to the * that case regulators are attached to the I2C device and not to the
* camera platform device. * camera platform device.
*/ */
ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators, ret = devm_regulator_bulk_get(&pdev->dev, ssdd->sd_pdata.num_regulators,
ssdd->regulators); ssdd->sd_pdata.regulators);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -0,0 +1,5 @@
obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
ti-vpe-y := vpe.o vpdma.o
ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG

View File

@ -0,0 +1,846 @@
/*
* VPDMA helper library
*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include "vpdma.h"
#include "vpdma_priv.h"
#define VPDMA_FIRMWARE "vpdma-1b8.bin"
const struct vpdma_data_format vpdma_yuv_fmts[] = {
[VPDMA_DATA_FMT_Y444] = {
.data_type = DATA_TYPE_Y444,
.depth = 8,
},
[VPDMA_DATA_FMT_Y422] = {
.data_type = DATA_TYPE_Y422,
.depth = 8,
},
[VPDMA_DATA_FMT_Y420] = {
.data_type = DATA_TYPE_Y420,
.depth = 8,
},
[VPDMA_DATA_FMT_C444] = {
.data_type = DATA_TYPE_C444,
.depth = 8,
},
[VPDMA_DATA_FMT_C422] = {
.data_type = DATA_TYPE_C422,
.depth = 8,
},
[VPDMA_DATA_FMT_C420] = {
.data_type = DATA_TYPE_C420,
.depth = 4,
},
[VPDMA_DATA_FMT_YC422] = {
.data_type = DATA_TYPE_YC422,
.depth = 16,
},
[VPDMA_DATA_FMT_YC444] = {
.data_type = DATA_TYPE_YC444,
.depth = 24,
},
[VPDMA_DATA_FMT_CY422] = {
.data_type = DATA_TYPE_CY422,
.depth = 16,
},
};
const struct vpdma_data_format vpdma_rgb_fmts[] = {
[VPDMA_DATA_FMT_RGB565] = {
.data_type = DATA_TYPE_RGB16_565,
.depth = 16,
},
[VPDMA_DATA_FMT_ARGB16_1555] = {
.data_type = DATA_TYPE_ARGB_1555,
.depth = 16,
},
[VPDMA_DATA_FMT_ARGB16] = {
.data_type = DATA_TYPE_ARGB_4444,
.depth = 16,
},
[VPDMA_DATA_FMT_RGBA16_5551] = {
.data_type = DATA_TYPE_RGBA_5551,
.depth = 16,
},
[VPDMA_DATA_FMT_RGBA16] = {
.data_type = DATA_TYPE_RGBA_4444,
.depth = 16,
},
[VPDMA_DATA_FMT_ARGB24] = {
.data_type = DATA_TYPE_ARGB24_6666,
.depth = 24,
},
[VPDMA_DATA_FMT_RGB24] = {
.data_type = DATA_TYPE_RGB24_888,
.depth = 24,
},
[VPDMA_DATA_FMT_ARGB32] = {
.data_type = DATA_TYPE_ARGB32_8888,
.depth = 32,
},
[VPDMA_DATA_FMT_RGBA24] = {
.data_type = DATA_TYPE_RGBA24_6666,
.depth = 24,
},
[VPDMA_DATA_FMT_RGBA32] = {
.data_type = DATA_TYPE_RGBA32_8888,
.depth = 32,
},
[VPDMA_DATA_FMT_BGR565] = {
.data_type = DATA_TYPE_BGR16_565,
.depth = 16,
},
[VPDMA_DATA_FMT_ABGR16_1555] = {
.data_type = DATA_TYPE_ABGR_1555,
.depth = 16,
},
[VPDMA_DATA_FMT_ABGR16] = {
.data_type = DATA_TYPE_ABGR_4444,
.depth = 16,
},
[VPDMA_DATA_FMT_BGRA16_5551] = {
.data_type = DATA_TYPE_BGRA_5551,
.depth = 16,
},
[VPDMA_DATA_FMT_BGRA16] = {
.data_type = DATA_TYPE_BGRA_4444,
.depth = 16,
},
[VPDMA_DATA_FMT_ABGR24] = {
.data_type = DATA_TYPE_ABGR24_6666,
.depth = 24,
},
[VPDMA_DATA_FMT_BGR24] = {
.data_type = DATA_TYPE_BGR24_888,
.depth = 24,
},
[VPDMA_DATA_FMT_ABGR32] = {
.data_type = DATA_TYPE_ABGR32_8888,
.depth = 32,
},
[VPDMA_DATA_FMT_BGRA24] = {
.data_type = DATA_TYPE_BGRA24_6666,
.depth = 24,
},
[VPDMA_DATA_FMT_BGRA32] = {
.data_type = DATA_TYPE_BGRA32_8888,
.depth = 32,
},
};
const struct vpdma_data_format vpdma_misc_fmts[] = {
[VPDMA_DATA_FMT_MV] = {
.data_type = DATA_TYPE_MV,
.depth = 4,
},
};
struct vpdma_channel_info {
int num; /* VPDMA channel number */
int cstat_offset; /* client CSTAT register offset */
};
static const struct vpdma_channel_info chan_info[] = {
[VPE_CHAN_LUMA1_IN] = {
.num = VPE_CHAN_NUM_LUMA1_IN,
.cstat_offset = VPDMA_DEI_LUMA1_CSTAT,
},
[VPE_CHAN_CHROMA1_IN] = {
.num = VPE_CHAN_NUM_CHROMA1_IN,
.cstat_offset = VPDMA_DEI_CHROMA1_CSTAT,
},
[VPE_CHAN_LUMA2_IN] = {
.num = VPE_CHAN_NUM_LUMA2_IN,
.cstat_offset = VPDMA_DEI_LUMA2_CSTAT,
},
[VPE_CHAN_CHROMA2_IN] = {
.num = VPE_CHAN_NUM_CHROMA2_IN,
.cstat_offset = VPDMA_DEI_CHROMA2_CSTAT,
},
[VPE_CHAN_LUMA3_IN] = {
.num = VPE_CHAN_NUM_LUMA3_IN,
.cstat_offset = VPDMA_DEI_LUMA3_CSTAT,
},
[VPE_CHAN_CHROMA3_IN] = {
.num = VPE_CHAN_NUM_CHROMA3_IN,
.cstat_offset = VPDMA_DEI_CHROMA3_CSTAT,
},
[VPE_CHAN_MV_IN] = {
.num = VPE_CHAN_NUM_MV_IN,
.cstat_offset = VPDMA_DEI_MV_IN_CSTAT,
},
[VPE_CHAN_MV_OUT] = {
.num = VPE_CHAN_NUM_MV_OUT,
.cstat_offset = VPDMA_DEI_MV_OUT_CSTAT,
},
[VPE_CHAN_LUMA_OUT] = {
.num = VPE_CHAN_NUM_LUMA_OUT,
.cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
},
[VPE_CHAN_CHROMA_OUT] = {
.num = VPE_CHAN_NUM_CHROMA_OUT,
.cstat_offset = VPDMA_VIP_UP_UV_CSTAT,
},
[VPE_CHAN_RGB_OUT] = {
.num = VPE_CHAN_NUM_RGB_OUT,
.cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
},
};
static u32 read_reg(struct vpdma_data *vpdma, int offset)
{
return ioread32(vpdma->base + offset);
}
static void write_reg(struct vpdma_data *vpdma, int offset, u32 value)
{
iowrite32(value, vpdma->base + offset);
}
static int read_field_reg(struct vpdma_data *vpdma, int offset,
u32 mask, int shift)
{
return (read_reg(vpdma, offset) & (mask << shift)) >> shift;
}
static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field,
u32 mask, int shift)
{
u32 val = read_reg(vpdma, offset);
val &= ~(mask << shift);
val |= (field & mask) << shift;
write_reg(vpdma, offset, val);
}
void vpdma_dump_regs(struct vpdma_data *vpdma)
{
struct device *dev = &vpdma->pdev->dev;
#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r))
dev_dbg(dev, "VPDMA Registers:\n");
DUMPREG(PID);
DUMPREG(LIST_ADDR);
DUMPREG(LIST_ATTR);
DUMPREG(LIST_STAT_SYNC);
DUMPREG(BG_RGB);
DUMPREG(BG_YUV);
DUMPREG(SETUP);
DUMPREG(MAX_SIZE1);
DUMPREG(MAX_SIZE2);
DUMPREG(MAX_SIZE3);
/*
* dumping registers of only group0 and group3, because VPE channels
* lie within group0 and group3 registers
*/
DUMPREG(INT_CHAN_STAT(0));
DUMPREG(INT_CHAN_MASK(0));
DUMPREG(INT_CHAN_STAT(3));
DUMPREG(INT_CHAN_MASK(3));
DUMPREG(INT_CLIENT0_STAT);
DUMPREG(INT_CLIENT0_MASK);
DUMPREG(INT_CLIENT1_STAT);
DUMPREG(INT_CLIENT1_MASK);
DUMPREG(INT_LIST0_STAT);
DUMPREG(INT_LIST0_MASK);
/*
* these are registers specific to VPE clients, we can make this
* function dump client registers specific to VPE or VIP based on
* who is using it
*/
DUMPREG(DEI_CHROMA1_CSTAT);
DUMPREG(DEI_LUMA1_CSTAT);
DUMPREG(DEI_CHROMA2_CSTAT);
DUMPREG(DEI_LUMA2_CSTAT);
DUMPREG(DEI_CHROMA3_CSTAT);
DUMPREG(DEI_LUMA3_CSTAT);
DUMPREG(DEI_MV_IN_CSTAT);
DUMPREG(DEI_MV_OUT_CSTAT);
DUMPREG(VIP_UP_Y_CSTAT);
DUMPREG(VIP_UP_UV_CSTAT);
DUMPREG(VPI_CTL_CSTAT);
}
/*
* Allocate a DMA buffer
*/
int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
{
buf->size = size;
buf->mapped = false;
buf->addr = kzalloc(size, GFP_KERNEL);
if (!buf->addr)
return -ENOMEM;
WARN_ON((u32) buf->addr & VPDMA_DESC_ALIGN);
return 0;
}
void vpdma_free_desc_buf(struct vpdma_buf *buf)
{
WARN_ON(buf->mapped);
kfree(buf->addr);
buf->addr = NULL;
buf->size = 0;
}
/*
* map descriptor/payload DMA buffer, enabling DMA access
*/
int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
{
struct device *dev = &vpdma->pdev->dev;
WARN_ON(buf->mapped);
buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, buf->dma_addr)) {
dev_err(dev, "failed to map buffer\n");
return -EINVAL;
}
buf->mapped = true;
return 0;
}
/*
* unmap descriptor/payload DMA buffer, disabling DMA access and
* allowing the main processor to acces the data
*/
void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
{
struct device *dev = &vpdma->pdev->dev;
if (buf->mapped)
dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE);
buf->mapped = false;
}
/*
* create a descriptor list, the user of this list will append configuration,
* control and data descriptors to this list, this list will be submitted to
* VPDMA. VPDMA's list parser will go through each descriptor and perform the
* required DMA operations
*/
int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
{
int r;
r = vpdma_alloc_desc_buf(&list->buf, size);
if (r)
return r;
list->next = list->buf.addr;
list->type = type;
return 0;
}
/*
* once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
* to allow new descriptors to be added to the list.
*/
void vpdma_reset_desc_list(struct vpdma_desc_list *list)
{
list->next = list->buf.addr;
}
/*
* free the buffer allocated fot the VPDMA descriptor list, this should be
* called when the user doesn't want to use VPDMA any more.
*/
void vpdma_free_desc_list(struct vpdma_desc_list *list)
{
vpdma_free_desc_buf(&list->buf);
list->next = NULL;
}
static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
{
return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
}
/*
* submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
*/
int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
{
/* we always use the first list */
int list_num = 0;
int list_size;
if (vpdma_list_busy(vpdma, list_num))
return -EBUSY;
/* 16-byte granularity */
list_size = (list->next - list->buf.addr) >> 4;
write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
write_reg(vpdma, VPDMA_LIST_ATTR,
(list_num << VPDMA_LIST_NUM_SHFT) |
(list->type << VPDMA_LIST_TYPE_SHFT) |
list_size);
return 0;
}
static void dump_cfd(struct vpdma_cfd *cfd)
{
int class;
class = cfd_get_class(cfd);
pr_debug("config descriptor of payload class: %s\n",
class == CFD_CLS_BLOCK ? "simple block" :
"address data block");
if (class == CFD_CLS_BLOCK)
pr_debug("word0: dst_addr_offset = 0x%08x\n",
cfd->dest_addr_offset);
if (class == CFD_CLS_BLOCK)
pr_debug("word1: num_data_wrds = %d\n", cfd->block_len);
pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr);
pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, "
"payload_len = %d\n", cfd_get_pkt_type(cfd),
cfd_get_direct(cfd), class, cfd_get_dest(cfd),
cfd_get_payload_len(cfd));
}
/*
* append a configuration descriptor to the given descriptor list, where the
* payload is in the form of a simple data block specified in the descriptor
* header, this is used to upload scaler coefficients to the scaler module
*/
void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
struct vpdma_buf *blk, u32 dest_offset)
{
struct vpdma_cfd *cfd;
int len = blk->size;
WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
cfd = list->next;
WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
cfd->dest_addr_offset = dest_offset;
cfd->block_len = len;
cfd->payload_addr = (u32) blk->dma_addr;
cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK,
client, len >> 4);
list->next = cfd + 1;
dump_cfd(cfd);
}
/*
* append a configuration descriptor to the given descriptor list, where the
* payload is in the address data block format, this is used to a configure a
* discontiguous set of MMRs
*/
void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
struct vpdma_buf *adb)
{
struct vpdma_cfd *cfd;
unsigned int len = adb->size;
WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
cfd = list->next;
BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
cfd->w0 = 0;
cfd->w1 = 0;
cfd->payload_addr = (u32) adb->dma_addr;
cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB,
client, len >> 4);
list->next = cfd + 1;
dump_cfd(cfd);
};
/*
* control descriptor format change based on what type of control descriptor it
* is, we only use 'sync on channel' control descriptors for now, so assume it's
* that
*/
static void dump_ctd(struct vpdma_ctd *ctd)
{
pr_debug("control descriptor\n");
pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
}
/*
* append a 'sync on channel' type control descriptor to the given descriptor
* list, this descriptor stalls the VPDMA list till the time DMA is completed
* on the specified channel
*/
void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
enum vpdma_channel chan)
{
struct vpdma_ctd *ctd;
ctd = list->next;
WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
ctd->w0 = 0;
ctd->w1 = 0;
ctd->w2 = 0;
ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num,
CTD_TYPE_SYNC_ON_CHANNEL);
list->next = ctd + 1;
dump_ctd(ctd);
}
static void dump_dtd(struct vpdma_dtd *dtd)
{
int dir, chan;
dir = dtd_get_dir(dtd);
chan = dtd_get_chan(dtd);
pr_debug("%s data transfer descriptor for channel %d\n",
dir == DTD_DIR_OUT ? "outbound" : "inbound", chan);
pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, "
"even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n",
dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd),
dtd_get_1d(dtd), dtd_get_even_line_skip(dtd),
dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd));
if (dir == DTD_DIR_IN)
pr_debug("word1: line_length = %d, xfer_height = %d\n",
dtd_get_line_length(dtd), dtd_get_xfer_height(dtd));
pr_debug("word2: start_addr = 0x%08x\n", dtd->start_addr);
pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, "
"pri = %d, next_chan = %d\n", dtd_get_pkt_type(dtd),
dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd),
dtd_get_next_chan(dtd));
if (dir == DTD_DIR_IN)
pr_debug("word4: frame_width = %d, frame_height = %d\n",
dtd_get_frame_width(dtd), dtd_get_frame_height(dtd));
else
pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, "
"drp_data = %d, use_desc_reg = %d\n",
dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd),
dtd_get_drop_data(dtd), dtd_get_use_desc(dtd));
if (dir == DTD_DIR_IN)
pr_debug("word5: hor_start = %d, ver_start = %d\n",
dtd_get_h_start(dtd), dtd_get_v_start(dtd));
else
pr_debug("word5: max_width %d, max_height %d\n",
dtd_get_max_width(dtd), dtd_get_max_height(dtd));
pr_debug("word6: client specfic attr0 = 0x%08x\n", dtd->client_attr0);
pr_debug("word7: client specfic attr1 = 0x%08x\n", dtd->client_attr1);
}
/*
* append an outbound data transfer descriptor to the given descriptor list,
* this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
*/
void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, u32 flags)
{
int priority = 0;
int field = 0;
int notify = 1;
int channel, next_chan;
int depth = fmt->depth;
int stride;
struct vpdma_dtd *dtd;
channel = next_chan = chan_info[chan].num;
if (fmt->data_type == DATA_TYPE_C420)
depth = 8;
stride = (depth * c_rect->width) >> 3;
dma_addr += (c_rect->left * depth) >> 3;
dtd = list->next;
WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
notify,
field,
!!(flags & VPDMA_DATA_FRAME_1D),
!!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
!!(flags & VPDMA_DATA_ODD_LINE_SKIP),
stride);
dtd->w1 = 0;
dtd->start_addr = (u32) dma_addr;
dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
DTD_DIR_OUT, channel, priority, next_chan);
dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920,
MAX_OUT_HEIGHT_1080);
dtd->client_attr0 = 0;
dtd->client_attr1 = 0;
list->next = dtd + 1;
dump_dtd(dtd);
}
/*
* append an inbound data transfer descriptor to the given descriptor list,
* this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
*/
void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
int frame_height, struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, int field, u32 flags)
{
int priority = 0;
int notify = 1;
int depth = fmt->depth;
int channel, next_chan;
int stride;
int height = c_rect->height;
struct vpdma_dtd *dtd;
channel = next_chan = chan_info[chan].num;
if (fmt->data_type == DATA_TYPE_C420) {
height >>= 1;
frame_height >>= 1;
depth = 8;
}
stride = (depth * c_rect->width) >> 3;
dma_addr += (c_rect->left * depth) >> 3;
dtd = list->next;
WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
notify,
field,
!!(flags & VPDMA_DATA_FRAME_1D),
!!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
!!(flags & VPDMA_DATA_ODD_LINE_SKIP),
stride);
dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height);
dtd->start_addr = (u32) dma_addr;
dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
DTD_DIR_IN, channel, priority, next_chan);
dtd->frame_width_height = dtd_frame_width_height(frame_width,
frame_height);
dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top);
dtd->client_attr0 = 0;
dtd->client_attr1 = 0;
list->next = dtd + 1;
dump_dtd(dtd);
}
/* set or clear the mask for list complete interrupt */
void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
bool enable)
{
u32 val;
val = read_reg(vpdma, VPDMA_INT_LIST0_MASK);
if (enable)
val |= (1 << (list_num * 2));
else
val &= ~(1 << (list_num * 2));
write_reg(vpdma, VPDMA_INT_LIST0_MASK, val);
}
/* clear previosuly occured list intterupts in the LIST_STAT register */
void vpdma_clear_list_stat(struct vpdma_data *vpdma)
{
write_reg(vpdma, VPDMA_INT_LIST0_STAT,
read_reg(vpdma, VPDMA_INT_LIST0_STAT));
}
/*
* configures the output mode of the line buffer for the given client, the
* line buffer content can either be mirrored(each line repeated twice) or
* passed to the client as is
*/
void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
enum vpdma_channel chan)
{
int client_cstat = chan_info[chan].cstat_offset;
write_field_reg(vpdma, client_cstat, line_mode,
VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
}
/*
* configures the event which should trigger VPDMA transfer for the given
* client
*/
void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
enum vpdma_frame_start_event fs_event,
enum vpdma_channel chan)
{
int client_cstat = chan_info[chan].cstat_offset;
write_field_reg(vpdma, client_cstat, fs_event,
VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
}
static void vpdma_firmware_cb(const struct firmware *f, void *context)
{
struct vpdma_data *vpdma = context;
struct vpdma_buf fw_dma_buf;
int i, r;
dev_dbg(&vpdma->pdev->dev, "firmware callback\n");
if (!f || !f->data) {
dev_err(&vpdma->pdev->dev, "couldn't get firmware\n");
return;
}
/* already initialized */
if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
VPDMA_LIST_RDY_SHFT)) {
vpdma->ready = true;
return;
}
r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size);
if (r) {
dev_err(&vpdma->pdev->dev,
"failed to allocate dma buffer for firmware\n");
goto rel_fw;
}
memcpy(fw_dma_buf.addr, f->data, f->size);
vpdma_map_desc_buf(vpdma, &fw_dma_buf);
write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr);
for (i = 0; i < 100; i++) { /* max 1 second */
msleep_interruptible(10);
if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
VPDMA_LIST_RDY_SHFT))
break;
}
if (i == 100) {
dev_err(&vpdma->pdev->dev, "firmware upload failed\n");
goto free_buf;
}
vpdma->ready = true;
free_buf:
vpdma_unmap_desc_buf(vpdma, &fw_dma_buf);
vpdma_free_desc_buf(&fw_dma_buf);
rel_fw:
release_firmware(f);
}
static int vpdma_load_firmware(struct vpdma_data *vpdma)
{
int r;
struct device *dev = &vpdma->pdev->dev;
r = request_firmware_nowait(THIS_MODULE, 1,
(const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma,
vpdma_firmware_cb);
if (r) {
dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE);
return r;
} else {
dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE);
}
return 0;
}
struct vpdma_data *vpdma_create(struct platform_device *pdev)
{
struct resource *res;
struct vpdma_data *vpdma;
int r;
dev_dbg(&pdev->dev, "vpdma_create\n");
vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL);
if (!vpdma) {
dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n");
return ERR_PTR(-ENOMEM);
}
vpdma->pdev = pdev;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
if (res == NULL) {
dev_err(&pdev->dev, "missing platform resources data\n");
return ERR_PTR(-ENODEV);
}
vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!vpdma->base) {
dev_err(&pdev->dev, "failed to ioremap\n");
return ERR_PTR(-ENOMEM);
}
r = vpdma_load_firmware(vpdma);
if (r) {
pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
return ERR_PTR(r);
}
return vpdma;
}
MODULE_FIRMWARE(VPDMA_FIRMWARE);

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef __TI_VPDMA_H_
#define __TI_VPDMA_H_
/*
* A vpdma_buf tracks the size, DMA address and mapping status of each
* driver DMA area.
*/
struct vpdma_buf {
void *addr;
dma_addr_t dma_addr;
size_t size;
bool mapped;
};
struct vpdma_desc_list {
struct vpdma_buf buf;
void *next;
int type;
};
struct vpdma_data {
void __iomem *base;
struct platform_device *pdev;
/* tells whether vpdma firmware is loaded or not */
bool ready;
};
struct vpdma_data_format {
int data_type;
u8 depth;
};
#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
#define VPDMA_LIST_TYPE_NORMAL 0
#define VPDMA_LIST_TYPE_SELF_MODIFYING 1
#define VPDMA_LIST_TYPE_DOORBELL 2
enum vpdma_yuv_formats {
VPDMA_DATA_FMT_Y444 = 0,
VPDMA_DATA_FMT_Y422,
VPDMA_DATA_FMT_Y420,
VPDMA_DATA_FMT_C444,
VPDMA_DATA_FMT_C422,
VPDMA_DATA_FMT_C420,
VPDMA_DATA_FMT_YC422,
VPDMA_DATA_FMT_YC444,
VPDMA_DATA_FMT_CY422,
};
enum vpdma_rgb_formats {
VPDMA_DATA_FMT_RGB565 = 0,
VPDMA_DATA_FMT_ARGB16_1555,
VPDMA_DATA_FMT_ARGB16,
VPDMA_DATA_FMT_RGBA16_5551,
VPDMA_DATA_FMT_RGBA16,
VPDMA_DATA_FMT_ARGB24,
VPDMA_DATA_FMT_RGB24,
VPDMA_DATA_FMT_ARGB32,
VPDMA_DATA_FMT_RGBA24,
VPDMA_DATA_FMT_RGBA32,
VPDMA_DATA_FMT_BGR565,
VPDMA_DATA_FMT_ABGR16_1555,
VPDMA_DATA_FMT_ABGR16,
VPDMA_DATA_FMT_BGRA16_5551,
VPDMA_DATA_FMT_BGRA16,
VPDMA_DATA_FMT_ABGR24,
VPDMA_DATA_FMT_BGR24,
VPDMA_DATA_FMT_ABGR32,
VPDMA_DATA_FMT_BGRA24,
VPDMA_DATA_FMT_BGRA32,
};
enum vpdma_misc_formats {
VPDMA_DATA_FMT_MV = 0,
};
extern const struct vpdma_data_format vpdma_yuv_fmts[];
extern const struct vpdma_data_format vpdma_rgb_fmts[];
extern const struct vpdma_data_format vpdma_misc_fmts[];
enum vpdma_frame_start_event {
VPDMA_FSEVENT_HDMI_FID = 0,
VPDMA_FSEVENT_DVO2_FID,
VPDMA_FSEVENT_HDCOMP_FID,
VPDMA_FSEVENT_SD_FID,
VPDMA_FSEVENT_LM_FID0,
VPDMA_FSEVENT_LM_FID1,
VPDMA_FSEVENT_LM_FID2,
VPDMA_FSEVENT_CHANNEL_ACTIVE,
};
/*
* VPDMA channel numbers
*/
enum vpdma_channel {
VPE_CHAN_LUMA1_IN,
VPE_CHAN_CHROMA1_IN,
VPE_CHAN_LUMA2_IN,
VPE_CHAN_CHROMA2_IN,
VPE_CHAN_LUMA3_IN,
VPE_CHAN_CHROMA3_IN,
VPE_CHAN_MV_IN,
VPE_CHAN_MV_OUT,
VPE_CHAN_LUMA_OUT,
VPE_CHAN_CHROMA_OUT,
VPE_CHAN_RGB_OUT,
};
/* flags for VPDMA data descriptors */
#define VPDMA_DATA_ODD_LINE_SKIP (1 << 0)
#define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1)
#define VPDMA_DATA_FRAME_1D (1 << 2)
#define VPDMA_DATA_MODE_TILED (1 << 3)
/*
* client identifiers used for configuration descriptors
*/
#define CFD_MMR_CLIENT 0
#define CFD_SC_CLIENT 4
/* Address data block header format */
struct vpdma_adb_hdr {
u32 offset;
u32 nwords;
u32 reserved0;
u32 reserved1;
};
/* helpers for creating ADB headers for config descriptors MMRs as client */
#define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld))
#define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld)
#define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \
do { \
struct vpdma_adb_hdr *h; \
struct str *adb = NULL; \
h = MMR_ADB_ADDR(buf, str, hdr); \
h->offset = (offset_a); \
h->nwords = sizeof(adb->regs) >> 2; \
} while (0)
/* vpdma descriptor buffer allocation and management */
int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size);
void vpdma_free_desc_buf(struct vpdma_buf *buf);
int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
/* vpdma descriptor list funcs */
int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type);
void vpdma_reset_desc_list(struct vpdma_desc_list *list);
void vpdma_free_desc_list(struct vpdma_desc_list *list);
int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list);
/* helpers for creating vpdma descriptors */
void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
struct vpdma_buf *blk, u32 dest_offset);
void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
struct vpdma_buf *adb);
void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
enum vpdma_channel chan);
void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, u32 flags);
void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
int frame_height, struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, int field, u32 flags);
/* vpdma list interrupt management */
void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
bool enable);
void vpdma_clear_list_stat(struct vpdma_data *vpdma);
/* vpdma client configuration */
void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
enum vpdma_channel chan);
void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
void vpdma_dump_regs(struct vpdma_data *vpdma);
/* initialize vpdma, passed with VPE's platform device pointer */
struct vpdma_data *vpdma_create(struct platform_device *pdev);
#endif

View File

@ -0,0 +1,641 @@
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _TI_VPDMA_PRIV_H_
#define _TI_VPDMA_PRIV_H_
/*
* VPDMA Register offsets
*/
/* Top level */
#define VPDMA_PID 0x00
#define VPDMA_LIST_ADDR 0x04
#define VPDMA_LIST_ATTR 0x08
#define VPDMA_LIST_STAT_SYNC 0x0c
#define VPDMA_BG_RGB 0x18
#define VPDMA_BG_YUV 0x1c
#define VPDMA_SETUP 0x30
#define VPDMA_MAX_SIZE1 0x34
#define VPDMA_MAX_SIZE2 0x38
#define VPDMA_MAX_SIZE3 0x3c
/* Interrupts */
#define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8)
#define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4)
#define VPDMA_INT_CLIENT0_STAT 0x78
#define VPDMA_INT_CLIENT0_MASK 0x7c
#define VPDMA_INT_CLIENT1_STAT 0x80
#define VPDMA_INT_CLIENT1_MASK 0x84
#define VPDMA_INT_LIST0_STAT 0x88
#define VPDMA_INT_LIST0_MASK 0x8c
#define VPDMA_PERFMON(i) (0x200 + i * 4)
/* VPE specific client registers */
#define VPDMA_DEI_CHROMA1_CSTAT 0x0300
#define VPDMA_DEI_LUMA1_CSTAT 0x0304
#define VPDMA_DEI_LUMA2_CSTAT 0x0308
#define VPDMA_DEI_CHROMA2_CSTAT 0x030c
#define VPDMA_DEI_LUMA3_CSTAT 0x0310
#define VPDMA_DEI_CHROMA3_CSTAT 0x0314
#define VPDMA_DEI_MV_IN_CSTAT 0x0330
#define VPDMA_DEI_MV_OUT_CSTAT 0x033c
#define VPDMA_VIP_UP_Y_CSTAT 0x0390
#define VPDMA_VIP_UP_UV_CSTAT 0x0394
#define VPDMA_VPI_CTL_CSTAT 0x03d0
/* Reg field info for VPDMA_CLIENT_CSTAT registers */
#define VPDMA_CSTAT_LINE_MODE_MASK 0x03
#define VPDMA_CSTAT_LINE_MODE_SHIFT 8
#define VPDMA_CSTAT_FRAME_START_MASK 0xf
#define VPDMA_CSTAT_FRAME_START_SHIFT 10
#define VPDMA_LIST_NUM_MASK 0x07
#define VPDMA_LIST_NUM_SHFT 24
#define VPDMA_LIST_STOP_SHFT 20
#define VPDMA_LIST_RDY_MASK 0x01
#define VPDMA_LIST_RDY_SHFT 19
#define VPDMA_LIST_TYPE_MASK 0x03
#define VPDMA_LIST_TYPE_SHFT 16
#define VPDMA_LIST_SIZE_MASK 0xffff
/* VPDMA data type values for data formats */
#define DATA_TYPE_Y444 0x0
#define DATA_TYPE_Y422 0x1
#define DATA_TYPE_Y420 0x2
#define DATA_TYPE_C444 0x4
#define DATA_TYPE_C422 0x5
#define DATA_TYPE_C420 0x6
#define DATA_TYPE_YC422 0x7
#define DATA_TYPE_YC444 0x8
#define DATA_TYPE_CY422 0x23
#define DATA_TYPE_RGB16_565 0x0
#define DATA_TYPE_ARGB_1555 0x1
#define DATA_TYPE_ARGB_4444 0x2
#define DATA_TYPE_RGBA_5551 0x3
#define DATA_TYPE_RGBA_4444 0x4
#define DATA_TYPE_ARGB24_6666 0x5
#define DATA_TYPE_RGB24_888 0x6
#define DATA_TYPE_ARGB32_8888 0x7
#define DATA_TYPE_RGBA24_6666 0x8
#define DATA_TYPE_RGBA32_8888 0x9
#define DATA_TYPE_BGR16_565 0x10
#define DATA_TYPE_ABGR_1555 0x11
#define DATA_TYPE_ABGR_4444 0x12
#define DATA_TYPE_BGRA_5551 0x13
#define DATA_TYPE_BGRA_4444 0x14
#define DATA_TYPE_ABGR24_6666 0x15
#define DATA_TYPE_BGR24_888 0x16
#define DATA_TYPE_ABGR32_8888 0x17
#define DATA_TYPE_BGRA24_6666 0x18
#define DATA_TYPE_BGRA32_8888 0x19
#define DATA_TYPE_MV 0x3
/* VPDMA channel numbers(only VPE channels for now) */
#define VPE_CHAN_NUM_LUMA1_IN 0
#define VPE_CHAN_NUM_CHROMA1_IN 1
#define VPE_CHAN_NUM_LUMA2_IN 2
#define VPE_CHAN_NUM_CHROMA2_IN 3
#define VPE_CHAN_NUM_LUMA3_IN 4
#define VPE_CHAN_NUM_CHROMA3_IN 5
#define VPE_CHAN_NUM_MV_IN 12
#define VPE_CHAN_NUM_MV_OUT 15
#define VPE_CHAN_NUM_LUMA_OUT 102
#define VPE_CHAN_NUM_CHROMA_OUT 103
#define VPE_CHAN_NUM_RGB_OUT 106
/*
* a VPDMA address data block payload for a configuration descriptor needs to
* have each sub block length as a multiple of 16 bytes. Therefore, the overall
* size of the payload also needs to be a multiple of 16 bytes. The sub block
* lengths should be ensured to be aligned by the VPDMA user.
*/
#define VPDMA_ADB_SIZE_ALIGN 0x0f
/*
* data transfer descriptor
*/
struct vpdma_dtd {
u32 type_ctl_stride;
union {
u32 xfer_length_height;
u32 w1;
};
dma_addr_t start_addr;
u32 pkt_ctl;
union {
u32 frame_width_height; /* inbound */
dma_addr_t desc_write_addr; /* outbound */
};
union {
u32 start_h_v; /* inbound */
u32 max_width_height; /* outbound */
};
u32 client_attr0;
u32 client_attr1;
};
/* Data Transfer Descriptor specifics */
#define DTD_NO_NOTIFY 0
#define DTD_NOTIFY 1
#define DTD_PKT_TYPE 0xa
#define DTD_DIR_IN 0
#define DTD_DIR_OUT 1
/* type_ctl_stride */
#define DTD_DATA_TYPE_MASK 0x3f
#define DTD_DATA_TYPE_SHFT 26
#define DTD_NOTIFY_MASK 0x01
#define DTD_NOTIFY_SHFT 25
#define DTD_FIELD_MASK 0x01
#define DTD_FIELD_SHFT 24
#define DTD_1D_MASK 0x01
#define DTD_1D_SHFT 23
#define DTD_EVEN_LINE_SKIP_MASK 0x01
#define DTD_EVEN_LINE_SKIP_SHFT 20
#define DTD_ODD_LINE_SKIP_MASK 0x01
#define DTD_ODD_LINE_SKIP_SHFT 16
#define DTD_LINE_STRIDE_MASK 0xffff
#define DTD_LINE_STRIDE_SHFT 0
/* xfer_length_height */
#define DTD_LINE_LENGTH_MASK 0xffff
#define DTD_LINE_LENGTH_SHFT 16
#define DTD_XFER_HEIGHT_MASK 0xffff
#define DTD_XFER_HEIGHT_SHFT 0
/* pkt_ctl */
#define DTD_PKT_TYPE_MASK 0x1f
#define DTD_PKT_TYPE_SHFT 27
#define DTD_MODE_MASK 0x01
#define DTD_MODE_SHFT 26
#define DTD_DIR_MASK 0x01
#define DTD_DIR_SHFT 25
#define DTD_CHAN_MASK 0x01ff
#define DTD_CHAN_SHFT 16
#define DTD_PRI_MASK 0x0f
#define DTD_PRI_SHFT 9
#define DTD_NEXT_CHAN_MASK 0x01ff
#define DTD_NEXT_CHAN_SHFT 0
/* frame_width_height */
#define DTD_FRAME_WIDTH_MASK 0xffff
#define DTD_FRAME_WIDTH_SHFT 16
#define DTD_FRAME_HEIGHT_MASK 0xffff
#define DTD_FRAME_HEIGHT_SHFT 0
/* start_h_v */
#define DTD_H_START_MASK 0xffff
#define DTD_H_START_SHFT 16
#define DTD_V_START_MASK 0xffff
#define DTD_V_START_SHFT 0
#define DTD_DESC_START_SHIFT 5
#define DTD_WRITE_DESC_MASK 0x01
#define DTD_WRITE_DESC_SHIFT 2
#define DTD_DROP_DATA_MASK 0x01
#define DTD_DROP_DATA_SHIFT 1
#define DTD_USE_DESC_MASK 0x01
#define DTD_USE_DESC_SHIFT 0
/* max_width_height */
#define DTD_MAX_WIDTH_MASK 0x07
#define DTD_MAX_WIDTH_SHFT 4
#define DTD_MAX_HEIGHT_MASK 0x07
#define DTD_MAX_HEIGHT_SHFT 0
/* max width configurations */
/* unlimited width */
#define MAX_OUT_WIDTH_UNLIMITED 0
/* as specified in max_size1 reg */
#define MAX_OUT_WIDTH_REG1 1
/* as specified in max_size2 reg */
#define MAX_OUT_WIDTH_REG2 2
/* as specified in max_size3 reg */
#define MAX_OUT_WIDTH_REG3 3
/* maximum of 352 pixels as width */
#define MAX_OUT_WIDTH_352 4
/* maximum of 768 pixels as width */
#define MAX_OUT_WIDTH_768 5
/* maximum of 1280 pixels width */
#define MAX_OUT_WIDTH_1280 6
/* maximum of 1920 pixels as width */
#define MAX_OUT_WIDTH_1920 7
/* max height configurations */
/* unlimited height */
#define MAX_OUT_HEIGHT_UNLIMITED 0
/* as specified in max_size1 reg */
#define MAX_OUT_HEIGHT_REG1 1
/* as specified in max_size2 reg */
#define MAX_OUT_HEIGHT_REG2 2
/* as specified in max_size3 reg */
#define MAX_OUT_HEIGHT_REG3 3
/* maximum of 288 lines as height */
#define MAX_OUT_HEIGHT_288 4
/* maximum of 576 lines as height */
#define MAX_OUT_HEIGHT_576 5
/* maximum of 720 lines as height */
#define MAX_OUT_HEIGHT_720 6
/* maximum of 1080 lines as height */
#define MAX_OUT_HEIGHT_1080 7
static inline u32 dtd_type_ctl_stride(int type, bool notify, int field,
bool one_d, bool even_line_skip, bool odd_line_skip,
int line_stride)
{
return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) |
(field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) |
(even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) |
(odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) |
line_stride;
}
static inline u32 dtd_xfer_length_height(int line_length, int xfer_height)
{
return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height;
}
static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri,
int next_chan)
{
return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) |
(dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) |
(pri << DTD_PRI_SHFT) | next_chan;
}
static inline u32 dtd_frame_width_height(int width, int height)
{
return (width << DTD_FRAME_WIDTH_SHFT) | height;
}
static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc,
bool drop_data, bool use_desc)
{
return (addr << DTD_DESC_START_SHIFT) |
(write_desc << DTD_WRITE_DESC_SHIFT) |
(drop_data << DTD_DROP_DATA_SHIFT) |
use_desc;
}
static inline u32 dtd_start_h_v(int h_start, int v_start)
{
return (h_start << DTD_H_START_SHFT) | v_start;
}
static inline u32 dtd_max_width_height(int max_width, int max_height)
{
return (max_width << DTD_MAX_WIDTH_SHFT) | max_height;
}
static inline int dtd_get_data_type(struct vpdma_dtd *dtd)
{
return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT;
}
static inline bool dtd_get_notify(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK;
}
static inline int dtd_get_field(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK;
}
static inline bool dtd_get_1d(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK;
}
static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT)
& DTD_EVEN_LINE_SKIP_MASK;
}
static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT)
& DTD_ODD_LINE_SKIP_MASK;
}
static inline int dtd_get_line_stride(struct vpdma_dtd *dtd)
{
return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK;
}
static inline int dtd_get_line_length(struct vpdma_dtd *dtd)
{
return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT;
}
static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd)
{
return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK;
}
static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd)
{
return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT;
}
static inline bool dtd_get_mode(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK;
}
static inline bool dtd_get_dir(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK;
}
static inline int dtd_get_chan(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK;
}
static inline int dtd_get_priority(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK;
}
static inline int dtd_get_next_chan(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK;
}
static inline int dtd_get_frame_width(struct vpdma_dtd *dtd)
{
return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT;
}
static inline int dtd_get_frame_height(struct vpdma_dtd *dtd)
{
return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK;
}
static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd)
{
return dtd->desc_write_addr >> DTD_DESC_START_SHIFT;
}
static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd)
{
return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) &
DTD_WRITE_DESC_MASK;
}
static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd)
{
return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) &
DTD_DROP_DATA_MASK;
}
static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd)
{
return dtd->desc_write_addr & DTD_USE_DESC_MASK;
}
static inline int dtd_get_h_start(struct vpdma_dtd *dtd)
{
return dtd->start_h_v >> DTD_H_START_SHFT;
}
static inline int dtd_get_v_start(struct vpdma_dtd *dtd)
{
return dtd->start_h_v & DTD_V_START_MASK;
}
static inline int dtd_get_max_width(struct vpdma_dtd *dtd)
{
return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) &
DTD_MAX_WIDTH_MASK;
}
static inline int dtd_get_max_height(struct vpdma_dtd *dtd)
{
return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) &
DTD_MAX_HEIGHT_MASK;
}
/*
* configuration descriptor
*/
struct vpdma_cfd {
union {
u32 dest_addr_offset;
u32 w0;
};
union {
u32 block_len; /* in words */
u32 w1;
};
u32 payload_addr;
u32 ctl_payload_len; /* in words */
};
/* Configuration descriptor specifics */
#define CFD_PKT_TYPE 0xb
#define CFD_DIRECT 1
#define CFD_INDIRECT 0
#define CFD_CLS_ADB 0
#define CFD_CLS_BLOCK 1
/* block_len */
#define CFD__BLOCK_LEN_MASK 0xffff
#define CFD__BLOCK_LEN_SHFT 0
/* ctl_payload_len */
#define CFD_PKT_TYPE_MASK 0x1f
#define CFD_PKT_TYPE_SHFT 27
#define CFD_DIRECT_MASK 0x01
#define CFD_DIRECT_SHFT 26
#define CFD_CLASS_MASK 0x03
#define CFD_CLASS_SHFT 24
#define CFD_DEST_MASK 0xff
#define CFD_DEST_SHFT 16
#define CFD_PAYLOAD_LEN_MASK 0xffff
#define CFD_PAYLOAD_LEN_SHFT 0
static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest,
int payload_len)
{
return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) |
(direct << CFD_DIRECT_SHFT) |
(cls << CFD_CLASS_SHFT) |
(dest << CFD_DEST_SHFT) |
payload_len;
}
static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd)
{
return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT;
}
static inline bool cfd_get_direct(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK;
}
static inline bool cfd_get_class(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK;
}
static inline int cfd_get_dest(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK;
}
static inline int cfd_get_payload_len(struct vpdma_cfd *cfd)
{
return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK;
}
/*
* control descriptor
*/
struct vpdma_ctd {
union {
u32 timer_value;
u32 list_addr;
u32 w0;
};
union {
u32 pixel_line_count;
u32 list_size;
u32 w1;
};
union {
u32 event;
u32 fid_ctl;
u32 w2;
};
u32 type_source_ctl;
};
/* control descriptor types */
#define CTD_TYPE_SYNC_ON_CLIENT 0
#define CTD_TYPE_SYNC_ON_LIST 1
#define CTD_TYPE_SYNC_ON_EXT 2
#define CTD_TYPE_SYNC_ON_LM_TIMER 3
#define CTD_TYPE_SYNC_ON_CHANNEL 4
#define CTD_TYPE_CHNG_CLIENT_IRQ 5
#define CTD_TYPE_SEND_IRQ 6
#define CTD_TYPE_RELOAD_LIST 7
#define CTD_TYPE_ABORT_CHANNEL 8
#define CTD_PKT_TYPE 0xc
/* timer_value */
#define CTD_TIMER_VALUE_MASK 0xffff
#define CTD_TIMER_VALUE_SHFT 0
/* pixel_line_count */
#define CTD_PIXEL_COUNT_MASK 0xffff
#define CTD_PIXEL_COUNT_SHFT 16
#define CTD_LINE_COUNT_MASK 0xffff
#define CTD_LINE_COUNT_SHFT 0
/* list_size */
#define CTD_LIST_SIZE_MASK 0xffff
#define CTD_LIST_SIZE_SHFT 0
/* event */
#define CTD_EVENT_MASK 0x0f
#define CTD_EVENT_SHFT 0
/* fid_ctl */
#define CTD_FID2_MASK 0x03
#define CTD_FID2_SHFT 4
#define CTD_FID1_MASK 0x03
#define CTD_FID1_SHFT 2
#define CTD_FID0_MASK 0x03
#define CTD_FID0_SHFT 0
/* type_source_ctl */
#define CTD_PKT_TYPE_MASK 0x1f
#define CTD_PKT_TYPE_SHFT 27
#define CTD_SOURCE_MASK 0xff
#define CTD_SOURCE_SHFT 16
#define CTD_CONTROL_MASK 0x0f
#define CTD_CONTROL_SHFT 0
static inline u32 ctd_pixel_line_count(int pixel_count, int line_count)
{
return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count;
}
static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2)
{
return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0;
}
static inline u32 ctd_type_source_ctl(int source, int control)
{
return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) |
(source << CTD_SOURCE_SHFT) | control;
}
static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd)
{
return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT;
}
static inline int ctd_get_line_count(struct vpdma_ctd *ctd)
{
return ctd->pixel_line_count & CTD_LINE_COUNT_MASK;
}
static inline int ctd_get_event(struct vpdma_ctd *ctd)
{
return ctd->event & CTD_EVENT_MASK;
}
static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd)
{
return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK;
}
static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd)
{
return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK;
}
static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd)
{
return ctd->fid_ctl & CTD_FID2_MASK;
}
static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd)
{
return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT;
}
static inline int ctd_get_source(struct vpdma_ctd *ctd)
{
return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK;
}
static inline int ctd_get_ctl(struct vpdma_ctd *ctd)
{
return ctd->type_source_ctl & CTD_CONTROL_MASK;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,496 @@
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef __TI_VPE_REGS_H
#define __TI_VPE_REGS_H
/* VPE register offsets and field selectors */
/* VPE top level regs */
#define VPE_PID 0x0000
#define VPE_PID_MINOR_MASK 0x3f
#define VPE_PID_MINOR_SHIFT 0
#define VPE_PID_CUSTOM_MASK 0x03
#define VPE_PID_CUSTOM_SHIFT 6
#define VPE_PID_MAJOR_MASK 0x07
#define VPE_PID_MAJOR_SHIFT 8
#define VPE_PID_RTL_MASK 0x1f
#define VPE_PID_RTL_SHIFT 11
#define VPE_PID_FUNC_MASK 0xfff
#define VPE_PID_FUNC_SHIFT 16
#define VPE_PID_SCHEME_MASK 0x03
#define VPE_PID_SCHEME_SHIFT 30
#define VPE_SYSCONFIG 0x0010
#define VPE_SYSCONFIG_IDLE_MASK 0x03
#define VPE_SYSCONFIG_IDLE_SHIFT 2
#define VPE_SYSCONFIG_STANDBY_MASK 0x03
#define VPE_SYSCONFIG_STANDBY_SHIFT 4
#define VPE_FORCE_IDLE_MODE 0
#define VPE_NO_IDLE_MODE 1
#define VPE_SMART_IDLE_MODE 2
#define VPE_SMART_IDLE_WAKEUP_MODE 3
#define VPE_FORCE_STANDBY_MODE 0
#define VPE_NO_STANDBY_MODE 1
#define VPE_SMART_STANDBY_MODE 2
#define VPE_SMART_STANDBY_WAKEUP_MODE 3
#define VPE_INT0_STATUS0_RAW_SET 0x0020
#define VPE_INT0_STATUS0_RAW VPE_INT0_STATUS0_RAW_SET
#define VPE_INT0_STATUS0_CLR 0x0028
#define VPE_INT0_STATUS0 VPE_INT0_STATUS0_CLR
#define VPE_INT0_ENABLE0_SET 0x0030
#define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET
#define VPE_INT0_ENABLE0_CLR 0x0038
#define VPE_INT0_LIST0_COMPLETE (1 << 0)
#define VPE_INT0_LIST0_NOTIFY (1 << 1)
#define VPE_INT0_LIST1_COMPLETE (1 << 2)
#define VPE_INT0_LIST1_NOTIFY (1 << 3)
#define VPE_INT0_LIST2_COMPLETE (1 << 4)
#define VPE_INT0_LIST2_NOTIFY (1 << 5)
#define VPE_INT0_LIST3_COMPLETE (1 << 6)
#define VPE_INT0_LIST3_NOTIFY (1 << 7)
#define VPE_INT0_LIST4_COMPLETE (1 << 8)
#define VPE_INT0_LIST4_NOTIFY (1 << 9)
#define VPE_INT0_LIST5_COMPLETE (1 << 10)
#define VPE_INT0_LIST5_NOTIFY (1 << 11)
#define VPE_INT0_LIST6_COMPLETE (1 << 12)
#define VPE_INT0_LIST6_NOTIFY (1 << 13)
#define VPE_INT0_LIST7_COMPLETE (1 << 14)
#define VPE_INT0_LIST7_NOTIFY (1 << 15)
#define VPE_INT0_DESCRIPTOR (1 << 16)
#define VPE_DEI_FMD_INT (1 << 18)
#define VPE_INT0_STATUS1_RAW_SET 0x0024
#define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET
#define VPE_INT0_STATUS1_CLR 0x002c
#define VPE_INT0_STATUS1 VPE_INT0_STATUS1_CLR
#define VPE_INT0_ENABLE1_SET 0x0034
#define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET
#define VPE_INT0_ENABLE1_CLR 0x003c
#define VPE_INT0_CHANNEL_GROUP0 (1 << 0)
#define VPE_INT0_CHANNEL_GROUP1 (1 << 1)
#define VPE_INT0_CHANNEL_GROUP2 (1 << 2)
#define VPE_INT0_CHANNEL_GROUP3 (1 << 3)
#define VPE_INT0_CHANNEL_GROUP4 (1 << 4)
#define VPE_INT0_CHANNEL_GROUP5 (1 << 5)
#define VPE_INT0_CLIENT (1 << 7)
#define VPE_DEI_ERROR_INT (1 << 16)
#define VPE_DS1_UV_ERROR_INT (1 << 22)
#define VPE_INTC_EOI 0x00a0
#define VPE_CLK_ENABLE 0x0100
#define VPE_VPEDMA_CLK_ENABLE (1 << 0)
#define VPE_DATA_PATH_CLK_ENABLE (1 << 1)
#define VPE_CLK_RESET 0x0104
#define VPE_VPDMA_CLK_RESET_MASK 0x1
#define VPE_VPDMA_CLK_RESET_SHIFT 0
#define VPE_DATA_PATH_CLK_RESET_MASK 0x1
#define VPE_DATA_PATH_CLK_RESET_SHIFT 1
#define VPE_MAIN_RESET_MASK 0x1
#define VPE_MAIN_RESET_SHIFT 31
#define VPE_CLK_FORMAT_SELECT 0x010c
#define VPE_CSC_SRC_SELECT_MASK 0x03
#define VPE_CSC_SRC_SELECT_SHIFT 0
#define VPE_RGB_OUT_SELECT (1 << 8)
#define VPE_DS_SRC_SELECT_MASK 0x07
#define VPE_DS_SRC_SELECT_SHIFT 9
#define VPE_DS_BYPASS (1 << 16)
#define VPE_COLOR_SEPARATE_422 (1 << 18)
#define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT)
#define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT)
#define VPE_CLK_RANGE_MAP 0x011c
#define VPE_RANGE_RANGE_MAP_Y_MASK 0x07
#define VPE_RANGE_RANGE_MAP_Y_SHIFT 0
#define VPE_RANGE_RANGE_MAP_UV_MASK 0x07
#define VPE_RANGE_RANGE_MAP_UV_SHIFT 3
#define VPE_RANGE_MAP_ON (1 << 6)
#define VPE_RANGE_REDUCTION_ON (1 << 28)
/* VPE chrominance upsampler regs */
#define VPE_US1_R0 0x0304
#define VPE_US2_R0 0x0404
#define VPE_US3_R0 0x0504
#define VPE_US_C1_MASK 0x3fff
#define VPE_US_C1_SHIFT 2
#define VPE_US_C0_MASK 0x3fff
#define VPE_US_C0_SHIFT 18
#define VPE_US_MODE_MASK 0x03
#define VPE_US_MODE_SHIFT 16
#define VPE_ANCHOR_FID0_C1_MASK 0x3fff
#define VPE_ANCHOR_FID0_C1_SHIFT 2
#define VPE_ANCHOR_FID0_C0_MASK 0x3fff
#define VPE_ANCHOR_FID0_C0_SHIFT 18
#define VPE_US1_R1 0x0308
#define VPE_US2_R1 0x0408
#define VPE_US3_R1 0x0508
#define VPE_ANCHOR_FID0_C3_MASK 0x3fff
#define VPE_ANCHOR_FID0_C3_SHIFT 2
#define VPE_ANCHOR_FID0_C2_MASK 0x3fff
#define VPE_ANCHOR_FID0_C2_SHIFT 18
#define VPE_US1_R2 0x030c
#define VPE_US2_R2 0x040c
#define VPE_US3_R2 0x050c
#define VPE_INTERP_FID0_C1_MASK 0x3fff
#define VPE_INTERP_FID0_C1_SHIFT 2
#define VPE_INTERP_FID0_C0_MASK 0x3fff
#define VPE_INTERP_FID0_C0_SHIFT 18
#define VPE_US1_R3 0x0310
#define VPE_US2_R3 0x0410
#define VPE_US3_R3 0x0510
#define VPE_INTERP_FID0_C3_MASK 0x3fff
#define VPE_INTERP_FID0_C3_SHIFT 2
#define VPE_INTERP_FID0_C2_MASK 0x3fff
#define VPE_INTERP_FID0_C2_SHIFT 18
#define VPE_US1_R4 0x0314
#define VPE_US2_R4 0x0414
#define VPE_US3_R4 0x0514
#define VPE_ANCHOR_FID1_C1_MASK 0x3fff
#define VPE_ANCHOR_FID1_C1_SHIFT 2
#define VPE_ANCHOR_FID1_C0_MASK 0x3fff
#define VPE_ANCHOR_FID1_C0_SHIFT 18
#define VPE_US1_R5 0x0318
#define VPE_US2_R5 0x0418
#define VPE_US3_R5 0x0518
#define VPE_ANCHOR_FID1_C3_MASK 0x3fff
#define VPE_ANCHOR_FID1_C3_SHIFT 2
#define VPE_ANCHOR_FID1_C2_MASK 0x3fff
#define VPE_ANCHOR_FID1_C2_SHIFT 18
#define VPE_US1_R6 0x031c
#define VPE_US2_R6 0x041c
#define VPE_US3_R6 0x051c
#define VPE_INTERP_FID1_C1_MASK 0x3fff
#define VPE_INTERP_FID1_C1_SHIFT 2
#define VPE_INTERP_FID1_C0_MASK 0x3fff
#define VPE_INTERP_FID1_C0_SHIFT 18
#define VPE_US1_R7 0x0320
#define VPE_US2_R7 0x0420
#define VPE_US3_R7 0x0520
#define VPE_INTERP_FID0_C3_MASK 0x3fff
#define VPE_INTERP_FID0_C3_SHIFT 2
#define VPE_INTERP_FID0_C2_MASK 0x3fff
#define VPE_INTERP_FID0_C2_SHIFT 18
/* VPE de-interlacer regs */
#define VPE_DEI_FRAME_SIZE 0x0600
#define VPE_DEI_WIDTH_MASK 0x07ff
#define VPE_DEI_WIDTH_SHIFT 0
#define VPE_DEI_HEIGHT_MASK 0x07ff
#define VPE_DEI_HEIGHT_SHIFT 16
#define VPE_DEI_INTERLACE_BYPASS (1 << 29)
#define VPE_DEI_FIELD_FLUSH (1 << 30)
#define VPE_DEI_PROGRESSIVE (1 << 31)
#define VPE_MDT_BYPASS 0x0604
#define VPE_MDT_TEMPMAX_BYPASS (1 << 0)
#define VPE_MDT_SPATMAX_BYPASS (1 << 1)
#define VPE_MDT_SF_THRESHOLD 0x0608
#define VPE_MDT_SF_SC_THR1_MASK 0xff
#define VPE_MDT_SF_SC_THR1_SHIFT 0
#define VPE_MDT_SF_SC_THR2_MASK 0xff
#define VPE_MDT_SF_SC_THR2_SHIFT 0
#define VPE_MDT_SF_SC_THR3_MASK 0xff
#define VPE_MDT_SF_SC_THR3_SHIFT 0
#define VPE_EDI_CONFIG 0x060c
#define VPE_EDI_INP_MODE_MASK 0x03
#define VPE_EDI_INP_MODE_SHIFT 0
#define VPE_EDI_ENABLE_3D (1 << 2)
#define VPE_EDI_ENABLE_CHROMA_3D (1 << 3)
#define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff
#define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8
#define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff
#define VPE_EDI_DIR_COR_LOWER_THR_SHIFT 16
#define VPE_EDI_COR_SCALE_FACTOR_MASK 0xff
#define VPE_EDI_COR_SCALE_FACTOR_SHIFT 23
#define VPE_DEI_EDI_LUT_R0 0x0610
#define VPE_EDI_LUT0_MASK 0x1f
#define VPE_EDI_LUT0_SHIFT 0
#define VPE_EDI_LUT1_MASK 0x1f
#define VPE_EDI_LUT1_SHIFT 8
#define VPE_EDI_LUT2_MASK 0x1f
#define VPE_EDI_LUT2_SHIFT 16
#define VPE_EDI_LUT3_MASK 0x1f
#define VPE_EDI_LUT3_SHIFT 24
#define VPE_DEI_EDI_LUT_R1 0x0614
#define VPE_EDI_LUT0_MASK 0x1f
#define VPE_EDI_LUT0_SHIFT 0
#define VPE_EDI_LUT1_MASK 0x1f
#define VPE_EDI_LUT1_SHIFT 8
#define VPE_EDI_LUT2_MASK 0x1f
#define VPE_EDI_LUT2_SHIFT 16
#define VPE_EDI_LUT3_MASK 0x1f
#define VPE_EDI_LUT3_SHIFT 24
#define VPE_DEI_EDI_LUT_R2 0x0618
#define VPE_EDI_LUT4_MASK 0x1f
#define VPE_EDI_LUT4_SHIFT 0
#define VPE_EDI_LUT5_MASK 0x1f
#define VPE_EDI_LUT5_SHIFT 8
#define VPE_EDI_LUT6_MASK 0x1f
#define VPE_EDI_LUT6_SHIFT 16
#define VPE_EDI_LUT7_MASK 0x1f
#define VPE_EDI_LUT7_SHIFT 24
#define VPE_DEI_EDI_LUT_R3 0x061c
#define VPE_EDI_LUT8_MASK 0x1f
#define VPE_EDI_LUT8_SHIFT 0
#define VPE_EDI_LUT9_MASK 0x1f
#define VPE_EDI_LUT9_SHIFT 8
#define VPE_EDI_LUT10_MASK 0x1f
#define VPE_EDI_LUT10_SHIFT 16
#define VPE_EDI_LUT11_MASK 0x1f
#define VPE_EDI_LUT11_SHIFT 24
#define VPE_DEI_FMD_WINDOW_R0 0x0620
#define VPE_FMD_WINDOW_MINX_MASK 0x07ff
#define VPE_FMD_WINDOW_MINX_SHIFT 0
#define VPE_FMD_WINDOW_MAXX_MASK 0x07ff
#define VPE_FMD_WINDOW_MAXX_SHIFT 16
#define VPE_FMD_WINDOW_ENABLE (1 << 31)
#define VPE_DEI_FMD_WINDOW_R1 0x0624
#define VPE_FMD_WINDOW_MINY_MASK 0x07ff
#define VPE_FMD_WINDOW_MINY_SHIFT 0
#define VPE_FMD_WINDOW_MAXY_MASK 0x07ff
#define VPE_FMD_WINDOW_MAXY_SHIFT 16
#define VPE_DEI_FMD_CONTROL_R0 0x0628
#define VPE_FMD_ENABLE (1 << 0)
#define VPE_FMD_LOCK (1 << 1)
#define VPE_FMD_JAM_DIR (1 << 2)
#define VPE_FMD_BED_ENABLE (1 << 3)
#define VPE_FMD_CAF_FIELD_THR_MASK 0xff
#define VPE_FMD_CAF_FIELD_THR_SHIFT 16
#define VPE_FMD_CAF_LINE_THR_MASK 0xff
#define VPE_FMD_CAF_LINE_THR_SHIFT 24
#define VPE_DEI_FMD_CONTROL_R1 0x062c
#define VPE_FMD_CAF_THR_MASK 0x000fffff
#define VPE_FMD_CAF_THR_SHIFT 0
#define VPE_DEI_FMD_STATUS_R0 0x0630
#define VPE_FMD_CAF_MASK 0x000fffff
#define VPE_FMD_CAF_SHIFT 0
#define VPE_FMD_RESET (1 << 24)
#define VPE_DEI_FMD_STATUS_R1 0x0634
#define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff
#define VPE_FMD_FIELD_DIFF_SHIFT 0
#define VPE_DEI_FMD_STATUS_R2 0x0638
#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff
#define VPE_FMD_FRAME_DIFF_SHIFT 0
/* VPE scaler regs */
#define VPE_SC_MP_SC0 0x0700
#define VPE_INTERLACE_O (1 << 0)
#define VPE_LINEAR (1 << 1)
#define VPE_SC_BYPASS (1 << 2)
#define VPE_INVT_FID (1 << 3)
#define VPE_USE_RAV (1 << 4)
#define VPE_ENABLE_EV (1 << 5)
#define VPE_AUTO_HS (1 << 6)
#define VPE_DCM_2X (1 << 7)
#define VPE_DCM_4X (1 << 8)
#define VPE_HP_BYPASS (1 << 9)
#define VPE_INTERLACE_I (1 << 10)
#define VPE_ENABLE_SIN2_VER_INTP (1 << 11)
#define VPE_Y_PK_EN (1 << 14)
#define VPE_TRIM (1 << 15)
#define VPE_SELFGEN_FID (1 << 16)
#define VPE_SC_MP_SC1 0x0704
#define VPE_ROW_ACC_INC_MASK 0x07ffffff
#define VPE_ROW_ACC_INC_SHIFT 0
#define VPE_SC_MP_SC2 0x0708
#define VPE_ROW_ACC_OFFSET_MASK 0x0fffffff
#define VPE_ROW_ACC_OFFSET_SHIFT 0
#define VPE_SC_MP_SC3 0x070c
#define VPE_ROW_ACC_OFFSET_B_MASK 0x0fffffff
#define VPE_ROW_ACC_OFFSET_B_SHIFT 0
#define VPE_SC_MP_SC4 0x0710
#define VPE_TAR_H_MASK 0x07ff
#define VPE_TAR_H_SHIFT 0
#define VPE_TAR_W_MASK 0x07ff
#define VPE_TAR_W_SHIFT 12
#define VPE_LIN_ACC_INC_U_MASK 0x07
#define VPE_LIN_ACC_INC_U_SHIFT 24
#define VPE_NLIN_ACC_INIT_U_MASK 0x07
#define VPE_NLIN_ACC_INIT_U_SHIFT 28
#define VPE_SC_MP_SC5 0x0714
#define VPE_SRC_H_MASK 0x07ff
#define VPE_SRC_H_SHIFT 0
#define VPE_SRC_W_MASK 0x07ff
#define VPE_SRC_W_SHIFT 12
#define VPE_NLIN_ACC_INC_U_MASK 0x07
#define VPE_NLIN_ACC_INC_U_SHIFT 24
#define VPE_SC_MP_SC6 0x0718
#define VPE_ROW_ACC_INIT_RAV_MASK 0x03ff
#define VPE_ROW_ACC_INIT_RAV_SHIFT 0
#define VPE_ROW_ACC_INIT_RAV_B_MASK 0x03ff
#define VPE_ROW_ACC_INIT_RAV_B_SHIFT 10
#define VPE_SC_MP_SC8 0x0720
#define VPE_NLIN_LEFT_MASK 0x07ff
#define VPE_NLIN_LEFT_SHIFT 0
#define VPE_NLIN_RIGHT_MASK 0x07ff
#define VPE_NLIN_RIGHT_SHIFT 12
#define VPE_SC_MP_SC9 0x0724
#define VPE_LIN_ACC_INC VPE_SC_MP_SC9
#define VPE_SC_MP_SC10 0x0728
#define VPE_NLIN_ACC_INIT VPE_SC_MP_SC10
#define VPE_SC_MP_SC11 0x072c
#define VPE_NLIN_ACC_INC VPE_SC_MP_SC11
#define VPE_SC_MP_SC12 0x0730
#define VPE_COL_ACC_OFFSET_MASK 0x01ffffff
#define VPE_COL_ACC_OFFSET_SHIFT 0
#define VPE_SC_MP_SC13 0x0734
#define VPE_SC_FACTOR_RAV_MASK 0x03ff
#define VPE_SC_FACTOR_RAV_SHIFT 0
#define VPE_CHROMA_INTP_THR_MASK 0x03ff
#define VPE_CHROMA_INTP_THR_SHIFT 12
#define VPE_DELTA_CHROMA_THR_MASK 0x0f
#define VPE_DELTA_CHROMA_THR_SHIFT 24
#define VPE_SC_MP_SC17 0x0744
#define VPE_EV_THR_MASK 0x03ff
#define VPE_EV_THR_SHIFT 12
#define VPE_DELTA_LUMA_THR_MASK 0x0f
#define VPE_DELTA_LUMA_THR_SHIFT 24
#define VPE_DELTA_EV_THR_MASK 0x0f
#define VPE_DELTA_EV_THR_SHIFT 28
#define VPE_SC_MP_SC18 0x0748
#define VPE_HS_FACTOR_MASK 0x03ff
#define VPE_HS_FACTOR_SHIFT 0
#define VPE_CONF_DEFAULT_MASK 0x01ff
#define VPE_CONF_DEFAULT_SHIFT 16
#define VPE_SC_MP_SC19 0x074c
#define VPE_HPF_COEFF0_MASK 0xff
#define VPE_HPF_COEFF0_SHIFT 0
#define VPE_HPF_COEFF1_MASK 0xff
#define VPE_HPF_COEFF1_SHIFT 8
#define VPE_HPF_COEFF2_MASK 0xff
#define VPE_HPF_COEFF2_SHIFT 16
#define VPE_HPF_COEFF3_MASK 0xff
#define VPE_HPF_COEFF3_SHIFT 23
#define VPE_SC_MP_SC20 0x0750
#define VPE_HPF_COEFF4_MASK 0xff
#define VPE_HPF_COEFF4_SHIFT 0
#define VPE_HPF_COEFF5_MASK 0xff
#define VPE_HPF_COEFF5_SHIFT 8
#define VPE_HPF_NORM_SHIFT_MASK 0x07
#define VPE_HPF_NORM_SHIFT_SHIFT 16
#define VPE_NL_LIMIT_MASK 0x1ff
#define VPE_NL_LIMIT_SHIFT 20
#define VPE_SC_MP_SC21 0x0754
#define VPE_NL_LO_THR_MASK 0x01ff
#define VPE_NL_LO_THR_SHIFT 0
#define VPE_NL_LO_SLOPE_MASK 0xff
#define VPE_NL_LO_SLOPE_SHIFT 16
#define VPE_SC_MP_SC22 0x0758
#define VPE_NL_HI_THR_MASK 0x01ff
#define VPE_NL_HI_THR_SHIFT 0
#define VPE_NL_HI_SLOPE_SH_MASK 0x07
#define VPE_NL_HI_SLOPE_SH_SHIFT 16
#define VPE_SC_MP_SC23 0x075c
#define VPE_GRADIENT_THR_MASK 0x07ff
#define VPE_GRADIENT_THR_SHIFT 0
#define VPE_GRADIENT_THR_RANGE_MASK 0x0f
#define VPE_GRADIENT_THR_RANGE_SHIFT 12
#define VPE_MIN_GY_THR_MASK 0xff
#define VPE_MIN_GY_THR_SHIFT 16
#define VPE_MIN_GY_THR_RANGE_MASK 0x0f
#define VPE_MIN_GY_THR_RANGE_SHIFT 28
#define VPE_SC_MP_SC24 0x0760
#define VPE_ORG_H_MASK 0x07ff
#define VPE_ORG_H_SHIFT 0
#define VPE_ORG_W_MASK 0x07ff
#define VPE_ORG_W_SHIFT 16
#define VPE_SC_MP_SC25 0x0764
#define VPE_OFF_H_MASK 0x07ff
#define VPE_OFF_H_SHIFT 0
#define VPE_OFF_W_MASK 0x07ff
#define VPE_OFF_W_SHIFT 16
/* VPE color space converter regs */
#define VPE_CSC_CSC00 0x5700
#define VPE_CSC_A0_MASK 0x1fff
#define VPE_CSC_A0_SHIFT 0
#define VPE_CSC_B0_MASK 0x1fff
#define VPE_CSC_B0_SHIFT 16
#define VPE_CSC_CSC01 0x5704
#define VPE_CSC_C0_MASK 0x1fff
#define VPE_CSC_C0_SHIFT 0
#define VPE_CSC_A1_MASK 0x1fff
#define VPE_CSC_A1_SHIFT 16
#define VPE_CSC_CSC02 0x5708
#define VPE_CSC_B1_MASK 0x1fff
#define VPE_CSC_B1_SHIFT 0
#define VPE_CSC_C1_MASK 0x1fff
#define VPE_CSC_C1_SHIFT 16
#define VPE_CSC_CSC03 0x570c
#define VPE_CSC_A2_MASK 0x1fff
#define VPE_CSC_A2_SHIFT 0
#define VPE_CSC_B2_MASK 0x1fff
#define VPE_CSC_B2_SHIFT 16
#define VPE_CSC_CSC04 0x5710
#define VPE_CSC_C2_MASK 0x1fff
#define VPE_CSC_C2_SHIFT 0
#define VPE_CSC_D0_MASK 0x0fff
#define VPE_CSC_D0_SHIFT 16
#define VPE_CSC_CSC05 0x5714
#define VPE_CSC_D1_MASK 0x0fff
#define VPE_CSC_D1_SHIFT 0
#define VPE_CSC_D2_MASK 0x0fff
#define VPE_CSC_D2_SHIFT 16
#define VPE_CSC_BYPASS (1 << 28)
#endif

View File

@ -403,7 +403,7 @@ static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
return 0; return 0;
} }
static int timblogiw_streamon(struct file *file, void *priv, unsigned int type) static int timblogiw_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
{ {
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct timblogiw_fh *fh = priv; struct timblogiw_fh *fh = priv;
@ -420,7 +420,7 @@ static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
} }
static int timblogiw_streamoff(struct file *file, void *priv, static int timblogiw_streamoff(struct file *file, void *priv,
unsigned int type) enum v4l2_buf_type type)
{ {
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct timblogiw_fh *fh = priv; struct timblogiw_fh *fh = priv;

View File

@ -123,7 +123,7 @@ static int keene_cmd_set(struct keene_device *radio)
/* If bit 0 is set, then transmit mono, otherwise stereo. /* If bit 0 is set, then transmit mono, otherwise stereo.
If bit 2 is set, then enable 75 us preemphasis, otherwise If bit 2 is set, then enable 75 us preemphasis, otherwise
it is 50 us. */ it is 50 us. */
radio->buffer[3] = (!radio->stereo) | (radio->preemph_75_us ? 4 : 0); radio->buffer[3] = (radio->stereo ? 0 : 1) | (radio->preemph_75_us ? 4 : 0);
radio->buffer[4] = 0x00; radio->buffer[4] = 0x00;
radio->buffer[5] = 0x00; radio->buffer[5] = 0x00;
radio->buffer[6] = 0x00; radio->buffer[6] = 0x00;

View File

@ -74,8 +74,8 @@ static u8 fmr2_tea575x_get_pins(struct snd_tea575x *tea)
struct fmr2 *fmr2 = tea->private_data; struct fmr2 *fmr2 = tea->private_data;
u8 bits = inb(fmr2->io); u8 bits = inb(fmr2->io);
return (bits & STR_DATA) ? TEA575X_DATA : 0 | return ((bits & STR_DATA) ? TEA575X_DATA : 0) |
(bits & STR_MOST) ? TEA575X_MOST : 0; ((bits & STR_MOST) ? TEA575X_MOST : 0);
} }
static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output) static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output)
@ -295,7 +295,6 @@ static void fmr2_remove(struct fmr2 *fmr2)
static int fmr2_isa_remove(struct device *pdev, unsigned int ndev) static int fmr2_isa_remove(struct device *pdev, unsigned int ndev)
{ {
fmr2_remove(dev_get_drvdata(pdev)); fmr2_remove(dev_get_drvdata(pdev));
dev_set_drvdata(pdev, NULL);
return 0; return 0;
} }

View File

@ -254,7 +254,7 @@ static unsigned int si470x_get_step(struct si470x_device *radio)
/* 2: 50 kHz */ /* 2: 50 kHz */
default: default:
return 50 * 16; return 50 * 16;
}; }
} }

View File

@ -1456,7 +1456,7 @@ static int si4713_probe(struct i2c_client *client,
if (client->irq) { if (client->irq) {
rval = request_irq(client->irq, rval = request_irq(client->irq,
si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, si4713_handler, IRQF_TRIGGER_FALLING,
client->name, sdev); client->name, sdev);
if (rval < 0) { if (rval < 0) {
v4l2_err(&sdev->sd, "Could not request IRQ\n"); v4l2_err(&sdev->sd, "Could not request IRQ\n");

View File

@ -175,7 +175,7 @@ static int_handler_prototype int_handler_table[] = {
fm_irq_handle_intmsk_cmd_resp fm_irq_handle_intmsk_cmd_resp
}; };
long (*g_st_write) (struct sk_buff *skb); static long (*g_st_write) (struct sk_buff *skb);
static struct completion wait_for_fmdrv_reg_comp; static struct completion wait_for_fmdrv_reg_comp;
static inline void fm_irq_call(struct fmdev *fmdev) static inline void fm_irq_call(struct fmdev *fmdev)

View File

@ -322,4 +322,14 @@ config IR_GPIO_CIR
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called gpio-ir-recv. be called gpio-ir-recv.
config RC_ST
tristate "ST remote control receiver"
depends on ARCH_STI && RC_CORE
help
Say Y here if you want support for ST remote control driver
which allows both IR and UHF RX.
The driver passes raw pulse and space information to the LIRC decoder.
If you're not sure, select N here.
endif #RC_DEVICES endif #RC_DEVICES

View File

@ -30,3 +30,4 @@ obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
obj-$(CONFIG_IR_IGUANA) += iguanair.o obj-$(CONFIG_IR_IGUANA) += iguanair.o
obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
obj-$(CONFIG_RC_ST) += st_rc.o

View File

@ -16,6 +16,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/irq.h> #include <linux/irq.h>

View File

@ -201,8 +201,7 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer); lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer);
retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler, retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler,
IRQF_DISABLED | IRQF_SHARED, IRQF_SHARED, "lirc_pulse_timer", lirc_rx51);
"lirc_pulse_timer", lirc_rx51);
if (retval) { if (retval) {
dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n"); dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n");
goto err2; goto err2;

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