本文整理汇总了C++中CX18_ERR函数的典型用法代码示例。如果您正苦于以下问题:C++ CX18_ERR函数的具体用法?C++ CX18_ERR怎么用?C++ CX18_ERR使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CX18_ERR函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: load_cpu_fw_direct
static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
{
const struct firmware *fw = NULL;
int i, j;
unsigned size;
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
}
src = (const u32 *)fw->data;
for (i = 0; i < fw->size; i += 4096) {
cx18_setup_page(cx, i);
for (j = i; j < fw->size && j < i + 4096; j += 4) {
/* no need for endianness conversion on the ppc */
cx18_raw_writel(cx, *src, dst);
if (cx18_raw_readl(cx, dst) != *src) {
CX18_ERR("Mismatch at offset %x\n", i);
release_firmware(fw);
cx18_setup_page(cx, 0);
return -EIO;
}
dst++;
src++;
}
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
size = fw->size;
release_firmware(fw);
cx18_setup_page(cx, SCB_OFFSET);
return size;
}
示例2: cx18_i2c_hw
/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
If hw == CX18_HW_GPIO then call the gpio handler. */
int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
{
int addr;
if (hw == CX18_HW_GPIO || hw == 0)
return 0;
if (hw == CX18_HW_CX23418)
return cx18_av_cmd(cx, cmd, arg);
addr = cx18_i2c_hw_addr(cx, hw);
if (addr < 0) {
CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
hw, cx18_i2c_hw_name(hw), cmd);
return addr;
}
return cx18_call_i2c_client(cx, addr, cmd, arg);
}
示例3: cx18_v4l2_open
int cx18_v4l2_open(struct file *filp)
{
int res;
struct video_device *video_dev = video_devdata(filp);
struct cx18_stream *s = video_get_drvdata(video_dev);
struct cx18 *cx = s->cx;
mutex_lock(&cx->serialize_lock);
if (cx18_init_on_first_open(cx)) {
CX18_ERR("Failed to initialize on minor %d\n",
video_dev->minor);
mutex_unlock(&cx->serialize_lock);
return -ENXIO;
}
res = cx18_serialized_open(s, filp);
mutex_unlock(&cx->serialize_lock);
return res;
}
示例4: cx18_firmware_init
int cx18_firmware_init(struct cx18 *cx)
{
/* Allow chip to control CLKRUN */
write_reg(0x5, CX18_DSP0_INTERRUPT_MASK);
write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
cx18_msleep_timeout(1, 0);
sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
/* Only if the processor is not running */
if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
cx->enc_mem, cx, CX18_FW_APU_SIZE);
sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
cx->enc_mem, cx, CX18_FW_CPU_SIZE);
if (sz > 0) {
int retries = 0;
/* start the CPU */
write_reg(0x00080000, CX18_PROC_SOFT_RESET);
while (retries++ < 50) { /* Loop for max 500mS */
if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0)
break;
cx18_msleep_timeout(10, 0);
}
cx18_msleep_timeout(200, 0);
if (retries == 51) {
CX18_ERR("Could not start the CPU\n");
return -EIO;
}
}
if (sz <= 0)
return -EIO;
}
/* initialize GPIO */
write_reg(0x14001400, 0xC78110);
return 0;
}
示例5: cx18_call_i2c_client
int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
{
struct i2c_client *client;
int retval;
int i;
CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
for (i = 0; i < I2C_CLIENTS_MAX; i++) {
client = cx->i2c_clients[i];
if (client == NULL || client->driver == NULL ||
client->driver->command == NULL)
continue;
if (addr == client->addr) {
retval = client->driver->command(client, cmd, arg);
return retval;
}
}
if (cmd != VIDIOC_G_CHIP_IDENT)
CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
addr, cmd);
return -ENODEV;
}
示例6: dvb_register
/* All the DVB attach calls go here, this function get's modified
* for each new card. No other function in this file needs
* to change.
*/
static int dvb_register(struct cx18_stream *stream)
{
struct cx18_dvb *dvb = &stream->dvb;
struct cx18 *cx = stream->cx;
int ret = 0;
switch (cx->card->type) {
case CX18_CARD_HVR_1600_ESMT:
case CX18_CARD_HVR_1600_SAMSUNG:
dvb->fe = dvb_attach(s5h1409_attach,
&hauppauge_hvr1600_config,
&cx->i2c_adap[0]);
if (dvb->fe != NULL) {
dvb_attach(mxl5005s_attach, dvb->fe,
&cx->i2c_adap[0],
&hauppauge_hvr1600_tuner);
ret = 0;
}
break;
default:
/* No Digital Tv Support */
break;
}
if (dvb->fe == NULL) {
CX18_ERR("frontend initialization failed\n");
return -1;
}
ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
if (ret < 0) {
if (dvb->fe->ops.release)
dvb->fe->ops.release(dvb->fe);
return ret;
}
return ret;
}
示例7: cx18_process_options
//.........这里部分代码省略.........
if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
cx->stream_buf_size[i] =
CX18_UNIT_ENC_IDX_BUFSIZE;
}
/*
* YUV and IDX are special cases where the stream_buf_size is
* now in bytes.
* VBI is a special case where the stream_buf_size is fixed
* and already in bytes
*/
if (i == CX18_ENC_STREAM_TYPE_VBI ||
i == CX18_ENC_STREAM_TYPE_YUV ||
i == CX18_ENC_STREAM_TYPE_IDX) {
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] =
cx->options.megabytes[i] * 1024 * 1024
/ cx->stream_buf_size[i];
} else {
/* N.B. This might round down to 0 */
cx->options.megabytes[i] =
cx->stream_buffers[i]
* cx->stream_buf_size[i]/(1024 * 1024);
}
} else {
/* All other streams have stream_buf_size in kB here */
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] =
cx->options.megabytes[i] * 1024
/ cx->stream_buf_size[i];
} else {
/* N.B. This might round down to 0 */
cx->options.megabytes[i] =
cx->stream_buffers[i]
* cx->stream_buf_size[i] / 1024;
}
/* convert from kB to bytes */
cx->stream_buf_size[i] *= 1024;
}
CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
"%d bytes\n", i, cx->options.megabytes[i],
cx->stream_buffers[i], cx->stream_buf_size[i]);
}
cx->options.cardtype = cardtype[cx->instance];
cx->options.tuner = tuner[cx->instance];
cx->options.radio = radio[cx->instance];
cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) {
CX18_INFO("Ignore card\n");
return;
}
cx->card = cx18_get_card(cx->options.cardtype - 1);
if (cx->card)
CX18_INFO("User specified %s card\n", cx->card->name);
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
if (cx->card == NULL) {
if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
}
if (cx->card == NULL) {
for (i = 0; (cx->card = cx18_get_card(i)); i++) {
if (cx->card->pci_list == NULL)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
if (cx->pci_dev->device !=
cx->card->pci_list[j].device)
continue;
if (cx->pci_dev->subsystem_vendor !=
cx->card->pci_list[j].subsystem_vendor)
continue;
if (cx->pci_dev->subsystem_device !=
cx->card->pci_list[j].subsystem_device)
continue;
CX18_INFO("Autodetected %s card\n", cx->card->name);
goto done;
}
}
}
done:
if (cx->card == NULL) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
cx->pci_dev->vendor, cx->pci_dev->device);
CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
cx->pci_dev->subsystem_vendor,
cx->pci_dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
}
cx->v4l2_cap = cx->card->v4l2_capabilities;
cx->card_name = cx->card->name;
cx->card_i2c = cx->card->i2c;
}
示例8: cx18_process_eeprom
static void cx18_process_eeprom(struct cx18 *cx)
{
struct tveeprom tv;
cx18_read_eeprom(cx, &tv);
/* Many thanks to Steven Toth from Hauppauge for providing the
model numbers */
/* Note: the Samsung memory models cannot be reliably determined
from the model number. Use the cardtype module option if you
have one of these preproduction models. */
switch (tv.model) {
case 74301: /* Retail models */
case 74321:
case 74351: /* OEM models */
case 74361:
/* Digital side is s5h1411/tda18271 */
cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411);
break;
case 74021: /* Retail models */
case 74031:
case 74041:
case 74141:
case 74541: /* OEM models */
case 74551:
case 74591:
case 74651:
case 74691:
case 74751:
case 74891:
/* Digital side is s5h1409/mxl5005s */
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
break;
case 0x718:
return;
case 0xffffffff:
CX18_INFO("Unknown EEPROM encoding\n");
return;
case 0:
CX18_ERR("Invalid EEPROM\n");
return;
default:
CX18_ERR("Unknown model %d, defaulting to original HVR-1600 "
"(cardtype=1)\n", tv.model);
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
break;
}
cx->v4l2_cap = cx->card->v4l2_capabilities;
cx->card_name = cx->card->name;
cx->card_i2c = cx->card->i2c;
CX18_INFO("Autodetected %s\n", cx->card_name);
if (tv.tuner_type == TUNER_ABSENT)
CX18_ERR("tveeprom cannot autodetect tuner!\n");
if (cx->options.tuner == -1)
cx->options.tuner = tv.tuner_type;
if (cx->options.radio == -1)
cx->options.radio = (tv.has_radio != 0);
if (cx->std != 0)
/* user specified tuner standard */
return;
/* autodetect tuner standard */
#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
V4L2_STD_MN | \
V4L2_STD_PAL_I | \
V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
V4L2_STD_DK)
if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
== TVEEPROM_TUNER_FORMAT_ALL) {
CX18_DEBUG_INFO("Worldwide tuner detected\n");
cx->std = V4L2_STD_ALL;
} else if (tv.tuner_formats & V4L2_STD_PAL) {
CX18_DEBUG_INFO("PAL tuner detected\n");
cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
} else if (tv.tuner_formats & V4L2_STD_NTSC) {
CX18_DEBUG_INFO("NTSC tuner detected\n");
cx->std |= V4L2_STD_NTSC_M;
} else if (tv.tuner_formats & V4L2_STD_SECAM) {
CX18_DEBUG_INFO("SECAM tuner detected\n");
cx->std |= V4L2_STD_SECAM_L;
} else {
CX18_INFO("No tuner detected, default to NTSC-M\n");
cx->std |= V4L2_STD_NTSC_M;
}
}
示例9: cx18_api_call
static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
{
const struct cx18_api_info *info = find_api_info(cmd);
u32 state = 0, irq = 0, req, oldreq, err;
struct cx18_mailbox __iomem *mb;
wait_queue_head_t *waitq;
int timeout = 100;
int cnt = 0;
int sig = 0;
int i;
if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd);
return -EINVAL;
}
if (cmd == CX18_CPU_DE_SET_MDL)
CX18_DEBUG_HI_API("%s\n", info->name);
else
CX18_DEBUG_API("%s\n", info->name);
cx18_setup_page(cx, SCB_OFFSET);
mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
if (mb == NULL) {
CX18_ERR("mb %s busy\n", info->name);
return -EBUSY;
}
oldreq = req - 1;
cx18_writel(cx, cmd, &mb->cmd);
for (i = 0; i < args; i++)
cx18_writel(cx, data[i], &mb->args[i]);
cx18_writel(cx, 0, &mb->error);
cx18_writel(cx, req, &mb->request);
switch (info->rpu) {
case APU: waitq = &cx->mb_apu_waitq; break;
case CPU: waitq = &cx->mb_cpu_waitq; break;
case EPU: waitq = &cx->mb_epu_waitq; break;
case HPU: waitq = &cx->mb_hpu_waitq; break;
default: return -EINVAL;
}
if (info->flags & API_FAST)
timeout /= 2;
cx18_write_reg(cx, irq, SW1_INT_SET);
while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request)
&& cnt < 660) {
if (cnt > 200 && !in_atomic())
sig = cx18_msleep_timeout(10, 1);
cnt++;
}
if (sig)
return -EINTR;
if (cnt == 660) {
cx18_writel(cx, oldreq, &mb->request);
CX18_ERR("mb %s failed\n", info->name);
return -EINVAL;
}
for (i = 0; i < MAX_MB_ARGUMENTS; i++)
data[i] = cx18_readl(cx, &mb->args[i]);
err = cx18_readl(cx, &mb->error);
if (!in_atomic() && (info->flags & API_SLOW))
cx18_msleep_timeout(300, 0);
if (err)
CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
info->name);
return err ? -EIO : 0;
}
示例10: cx18_av_loadfw
int cx18_av_loadfw(struct cx18 *cx)
{
const struct firmware *fw = NULL;
u32 size;
u32 v;
u8 *ptr;
int i;
if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
CX18_ERR("unable to open firmware %s\n", FWFILE);
return -EINVAL;
}
cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */
/* Reset the Mako core (Register is undocumented.) */
cx18_av_write4(cx, 0x8100, 0x00010000);
/* Put the 8051 in reset and enable firmware upload */
cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
ptr = fw->data;
size = fw->size;
for (i = 0; i < size; i++) {
u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16);
u32 value = 0;
int retries;
for (retries = 0; retries < 5; retries++) {
cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
value = cx18_av_read4(cx, CXADEC_DL_CTL);
if ((value & 0x3F00) == (dl_control & 0x3F00))
break;
}
if (retries >= 5) {
CX18_ERR("unable to load firmware %s\n", FWFILE);
release_firmware(fw);
return -EIO;
}
}
cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
/* Output to the 416 */
cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
/* Audio input control 1 set to Sony mode */
/* Audio output input 2 is 0 for slave operation input */
/* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
/* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
after WS transition for first bit of audio word. */
cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
/* Audio output control 1 is set to Sony mode */
/* Audio output control 2 is set to 1 for master mode */
/* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
/* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
after WS transition for first bit of audio word. */
/* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
are generated) */
cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
/* set alt I2s master clock to /16 and enable alt divider i2s
passthrough */
cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6);
/* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
/* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
/* Register 0x09CC is defined by the Merlin firmware, and doesn't
have a name in the spec. */
cx18_av_write4(cx, 0x09CC, 1);
#define CX18_AUDIO_ENABLE 0xc72014
v = read_reg(CX18_AUDIO_ENABLE);
/* If bit 11 is 1 */
if (v & 0x800)
write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */
/* Enable WW auto audio standard detection */
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
v |= 0xFF; /* Auto by default */
v |= 0x400; /* Stereo by default */
v |= 0x14000000;
cx18_av_write4(cx, CXADEC_STD_DET_CTL, v);
release_firmware(fw);
CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
return 0;
}
示例11: cx18_process_options
static void cx18_process_options(struct cx18 *cx)
{
int i, j;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
cx->options.cardtype = cardtype[cx->num];
cx->options.tuner = tuner[cx->num];
cx->options.radio = radio[cx->num];
cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) {
CX18_INFO("Ignore card\n");
return;
}
cx->card = cx18_get_card(cx->options.cardtype - 1);
if (cx->card)
CX18_INFO("User specified %s card\n", cx->card->name);
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
if (cx->card == NULL) {
if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
}
if (cx->card == NULL) {
for (i = 0; (cx->card = cx18_get_card(i)); i++) {
if (cx->card->pci_list == NULL)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
if (cx->dev->device !=
cx->card->pci_list[j].device)
continue;
if (cx->dev->subsystem_vendor !=
cx->card->pci_list[j].subsystem_vendor)
continue;
if (cx->dev->subsystem_device !=
cx->card->pci_list[j].subsystem_device)
continue;
CX18_INFO("Autodetected %s card\n", cx->card->name);
goto done;
}
}
}
done:
if (cx->card == NULL) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: %04x/%04x\n",
cx->dev->vendor, cx->dev->device);
CX18_ERR(" subsystem vendor/device: %04x/%04x\n",
cx->dev->subsystem_vendor, cx->dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
}
cx->v4l2_cap = cx->card->v4l2_capabilities;
cx->card_name = cx->card->name;
cx->card_i2c = cx->card->i2c;
}
示例12: cx18_prep_dev
static int cx18_prep_dev(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
u32 cap = cx->v4l2_cap;
int num_offset = cx18_stream_info[type].num_offset;
int num = cx->instance + cx18_first_minor + num_offset;
s->video_dev = NULL;
s->dvb = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
return 0;
if (type == CX18_ENC_STREAM_TYPE_VBI &&
!(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
return 0;
if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
cx->stream_buffers[type] == 0) {
CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
return 0;
}
cx18_stream_init(cx, type);
if (type == CX18_ENC_STREAM_TYPE_TS) {
if (cx->card->hw_all & CX18_HW_DVB) {
s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
if (s->dvb == NULL) {
CX18_ERR("Couldn't allocate cx18_dvb structure"
" for %s\n", s->name);
return -ENOMEM;
}
} else {
s->buffers = 0;
}
}
if (num_offset == -1)
return 0;
s->video_dev = video_device_alloc();
if (s->video_dev == NULL) {
CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
s->name);
return -ENOMEM;
}
snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
cx->v4l2_dev.name, s->name);
s->video_dev->num = num;
s->video_dev->v4l2_dev = &cx->v4l2_dev;
s->video_dev->fops = &cx18_v4l2_enc_fops;
s->video_dev->release = video_device_release;
s->video_dev->tvnorms = V4L2_STD_ALL;
set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
cx18_set_funcs(s->video_dev);
return 0;
}
示例13: load_apu_fw_direct
static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size)
{
const struct firmware *fw = NULL;
int retries = 3;
int i, j;
const u32 *src;
struct cx18_apu_rom_seghdr seghdr;
const u8 *vers;
u32 offset = 0;
u32 apu_version = 0;
int sz;
retry:
if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
CX18_ERR("unable to open firmware %s (must be %ld bytes)\n",
fn, size);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
}
src = (const u32 *)fw->data;
vers = fw->data + sizeof(seghdr);
sz = fw->size;
if (fw->size != size) {
/* Due to race conditions in firmware loading (esp. with
udev <0.95) the wrong file was sometimes loaded. So we check
filesizes to see if at least the right-sized file was
loaded. If not, then we retry. */
CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
fn, size, fw->size);
release_firmware(fw);
retries--;
goto retry;
}
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
while (offset + sizeof(seghdr) < size) {
/* TODO: byteswapping */
memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
offset += sizeof(seghdr);
if (seghdr.sync1 != APU_ROM_SYNC1 ||
seghdr.sync2 != APU_ROM_SYNC2) {
offset += seghdr.size;
continue;
}
CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
seghdr.addr + seghdr.size - 1);
if (offset + seghdr.size > sz)
break;
for (i = 0; i < seghdr.size; i += 4096) {
setup_page(offset + i);
for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
/* no need for endianness conversion on the ppc */
__raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j);
if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) {
CX18_ERR("Mismatch at offset %x\n", offset + j);
release_firmware(fw);
return -EIO;
}
}
}
offset += seghdr.size;
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
fn, apu_version, fw->size);
release_firmware(fw);
/* Clear bit0 for APU to start from 0 */
write_reg(read_reg(0xc72030) & ~1, 0xc72030);
return size;
}
示例14: cx18_firmware_init
int cx18_firmware_init(struct cx18 *cx)
{
u32 fw_entry_addr;
int sz, retries;
u32 api_args[MAX_MB_ARGUMENTS];
/* Allow chip to control CLKRUN */
cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
/* Stop the firmware */
cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
0x0000000F, 0x000F000F);
cx18_msleep_timeout(1, 0);
/* If the CPU is still running */
if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
return -EIO;
}
cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
if (sz <= 0)
return sz;
/* The SCB & IPC area *must* be correct before starting the firmwares */
cx18_init_scb(cx);
fw_entry_addr = 0;
sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
&fw_entry_addr);
if (sz <= 0)
return sz;
/* Start the CPU. The CPU will take care of the APU for us. */
cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
0x00000000, 0x00080008);
/* Wait up to 500 ms for the APU to come out of reset */
for (retries = 0;
retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
retries++)
cx18_msleep_timeout(10, 0);
cx18_msleep_timeout(200, 0);
if (retries == 50 &&
(cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
CX18_ERR("Could not start the CPU\n");
return -EIO;
}
/*
* The CPU had once before set up to receive an interrupt for it's
* outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
* interrupt when it sends us an ack, but by the time we process it,
* that flag in the SW2 status register has been cleared by the CPU
* firmware. We'll prevent that not so useful condition from happening
* by clearing the CPU's interrupt enables for Ack IRQ's we want to
* process.
*/
cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
/* Try a benign command to see if the CPU is alive and well */
sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
if (sz < 0)
return sz;
/* initialize GPIO */
cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
return 0;
}
示例15: load_apu_fw_direct
static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 *entry_addr)
{
const struct firmware *fw = NULL;
int i, j;
unsigned size;
const u32 *src;
struct cx18_apu_rom_seghdr seghdr;
const u8 *vers;
u32 offset = 0;
u32 apu_version = 0;
int sz;
if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
cx18_setup_page(cx, 0);
return -ENOMEM;
}
*entry_addr = 0;
src = (const u32 *)fw->data;
vers = fw->data + sizeof(seghdr);
sz = fw->size;
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
while (offset + sizeof(seghdr) < fw->size) {
/* TODO: byteswapping */
memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
offset += sizeof(seghdr);
if (seghdr.sync1 != APU_ROM_SYNC1 ||
seghdr.sync2 != APU_ROM_SYNC2) {
offset += seghdr.size;
continue;
}
CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
seghdr.addr + seghdr.size - 1);
if (*entry_addr == 0)
*entry_addr = seghdr.addr;
if (offset + seghdr.size > sz)
break;
for (i = 0; i < seghdr.size; i += 4096) {
cx18_setup_page(cx, seghdr.addr + i);
for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
/* no need for endianness conversion on the ppc */
cx18_raw_writel(cx, src[(offset + j) / 4],
dst + seghdr.addr + j);
if (cx18_raw_readl(cx, dst + seghdr.addr + j)
!= src[(offset + j) / 4]) {
CX18_ERR("Mismatch at offset %x\n",
offset + j);
release_firmware(fw);
cx18_setup_page(cx, 0);
return -EIO;
}
}
}
offset += seghdr.size;
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
fn, apu_version, fw->size);
size = fw->size;
release_firmware(fw);
cx18_setup_page(cx, 0);
return size;
}