int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, const struct sram_channel *channel) { int tmp = 0; /* setup fifo + format */ cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma); /* reset counter */ cx_write(channel->gpcnt_ctl, 3); /* enable irq */ cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i)); cx_set(channel->int_msk, 0x11); /* start dma */ cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */ /* make sure upstream setting if any is reversed */ tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); return 0; }
static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) { struct cx25821_dev *dev = dev_id; u32 msk_stat, audio_status; int handled = 0; struct sram_channel *sram_ch; if (!dev) return -1; sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select]; msk_stat = cx_read(sram_ch->int_mstat); audio_status = cx_read(sram_ch->int_stat); // Only deal with our interrupt if (audio_status) { handled = cx25821_audio_upstream_irq(dev, dev-> _audio_upstream_channel_select, audio_status); } if (handled < 0) { cx25821_stop_upstream_audio(dev); } else { handled += handled; } return IRQ_RETVAL(handled); }
void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) { struct sram_channel *sram_ch = dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; u32 tmp = 0; if (!dev->_is_running) { pr_info("No video file is currently running so return!\n"); return; } /* Disable RISC interrupts */ tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp & ~_intr_msk); /* Turn OFF risc and fifo enable */ tmp = cx_read(sram_ch->dma_ctl); cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); /* Clear data buffer memory */ if (dev->_data_buf_virt_addr) memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); dev->_is_running = 0; dev->_is_first_frame = 0; dev->_frame_count = 0; dev->_file_status = END_OF_FILE; kfree(dev->_irq_queues); dev->_irq_queues = NULL; kfree(dev->_filename); tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); }
int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS. cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr); cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ /* reset counter */ cx_write(sram_ch->gpcnt_ctl, 3); //Set the line length (It looks like we do not need to set the line length) cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH); //Set the input mode to 16-bit tmp = cx_read(sram_ch->aud_cfg); tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE; cx_write(sram_ch->aud_cfg, tmp); // Read and write back the interrupt status register to clear it tmp = cx_read(sram_ch->int_stat); cx_write(sram_ch->int_stat, tmp); // Clear our bits from the interrupt status register. cx_write(sram_ch->int_stat, _intr_msk); //Set the interrupt mask register, enable irq. cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, IRQF_SHARED | IRQF_DISABLED, dev->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq); goto fail_irq; } // Start the DMA engine tmp = cx_read(sram_ch->dma_ctl); cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en); dev->_audio_is_running = 1; dev->_is_first_audio_frame = 1; // The fifo_en bit turns on by the first Risc program cx25821_wait_fifo_enable(dev, sram_ch); return 0; fail_irq: cx25821_dev_unregister(dev); return err; }
static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) { struct cx25821_dev *dev = dev_id; u32 msk_stat, vid_status; int handled = 0; int channel_num = 0; struct sram_channel *sram_ch; if (!dev) return -1; channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; sram_ch = dev->channels[channel_num].sram_channels; msk_stat = cx_read(sram_ch->int_mstat); vid_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ if (vid_status) handled = cx25821_video_upstream_irq_ch2(dev, channel_num, vid_status); if (handled < 0) cx25821_stop_upstream_video_ch2(dev); else handled += handled; return IRQ_RETVAL(handled); }
static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan, const struct sram_channel *sram_ch) { struct cx25821_video_out_data *out = chan->out; struct cx25821_dev *dev = chan->dev; u32 tmp = 0; int err = 0; /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for * channel A-C */ tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); /* Set the physical start address of the RISC program in the initial * program counter(IPC) member of the cmds. */ cx_write(sram_ch->cmds_start + 0, out->_dma_phys_addr); /* Risc IPC High 64 bits 63-32 */ cx_write(sram_ch->cmds_start + 4, 0); /* reset counter */ cx_write(sram_ch->gpcnt_ctl, 3); /* Clear our bits from the interrupt status register. */ cx_write(sram_ch->int_stat, _intr_msk); /* Set the interrupt mask register, enable irq. */ cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); err = request_irq(dev->pci->irq, cx25821_upstream_irq, IRQF_SHARED, dev->name, chan); if (err < 0) { pr_err("%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq); goto fail_irq; } /* Start the DMA engine */ tmp = cx_read(sram_ch->dma_ctl); cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); out->_is_running = 1; out->_is_first_frame = 1; return 0; fail_irq: cx25821_dev_unregister(dev); return err; }
s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) { s16 *samples; u32 N = 0; s32 ret = UNSET; /* If audio RDS fifo is disabled, we can't read the samples */ if (!(cx_read(MO_AUD_DMACNTRL) & 0x04)) return ret; if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS)) return ret; /* Wait at least 500 ms after an audio standard change */ if (time_before(jiffies, core->last_change + msecs_to_jiffies(500))) return ret; samples = read_rds_samples(core, &N); if (!samples) return ret; switch (core->tvaudio) { case WW_BG: case WW_DK: case WW_EIAJ: case WW_M: ret = detect_a2_a2m_eiaj(core, samples, N); break; case WW_BTSC: ret = detect_btsc(core, samples, N); break; case WW_NONE: case WW_I: case WW_L: case WW_I2SPT: case WW_FM: case WW_I2SADC: break; } kfree(samples); if (UNSET != ret) dprintk(1, "stereo/sap detection result:%s%s%s\n", (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : ""); return ret; }
void cx25821_stop_upstream_audio(struct cx25821_dev *dev) { struct sram_channel *sram_ch = dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; u32 tmp = 0; if (!dev->_audio_is_running) { printk(KERN_DEBUG pr_fmt("No audio file is currently running so return!\n")); return; } /* Disable RISC interrupts */ cx_write(sram_ch->int_msk, 0); /* Turn OFF risc and fifo enable in AUD_DMA_CNTRL */ tmp = cx_read(sram_ch->dma_ctl); cx_write(sram_ch->dma_ctl, tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en)); /* Clear data buffer memory */ if (dev->_audiodata_buf_virt_addr) memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size); dev->_audio_is_running = 0; dev->_is_first_audio_frame = 0; dev->_audioframe_count = 0; dev->_audiofile_status = END_OF_FILE; kfree(dev->_irq_audio_queues); dev->_irq_audio_queues = NULL; kfree(dev->_audiofilename); }
static int i2c_readbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int joined) { struct cx23885_i2c *bus = i2c_adap->algo_data; struct cx23885_dev *dev = bus->dev; u32 ctrl, cnt; int retval; if (i2c_debug && !joined) dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); /* Deal with i2c probe functions with zero payload */ if (msg->len == 0) { cx_write(bus->reg_addr, msg->addr << 25); cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); if (!i2c_wait_done(i2c_adap)) return -EIO; if (!i2c_slave_did_ack(i2c_adap)) return -ENXIO; dprintk(1, "%s() returns 0\n", __func__); return 0; } if (i2c_debug) { if (joined) dprintk(1, " R"); else dprintk(1, " <R %02x", (msg->addr << 1) + 1); } for (cnt = 0; cnt < msg->len; cnt++) { ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; if (cnt < msg->len - 1) ctrl |= I2C_NOSTOP | I2C_EXTEND; cx_write(bus->reg_addr, msg->addr << 25); cx_write(bus->reg_ctrl, ctrl); if (!i2c_wait_done(i2c_adap)) goto eio; msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; if (i2c_debug) { dprintk(1, " %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) dprintk(1, " >\n"); } } return msg->len; eio: retval = -EIO; if (i2c_debug) pr_err(" ERR: %d\n", retval); return retval; }
/********************* GPIO stuffs *********************/ void cx25821_set_gpiopin_direction(struct cx25821_dev *dev, int pin_number, int pin_logic_value) { int bit = pin_number; u32 gpio_oe_reg = GPIO_LO_OE; u32 gpio_register = 0; u32 value = 0; /* Check for valid pinNumber */ if (pin_number >= 47) return; if (pin_number > 31) { bit = pin_number - 31; gpio_oe_reg = GPIO_HI_OE; } /* Here we will make sure that the GPIOs 0 and 1 are output. keep the * rest as is */ gpio_register = cx_read(gpio_oe_reg); if (pin_logic_value == 1) value = gpio_register | Set_GPIO_Bit(bit); else value = gpio_register & Clear_GPIO_Bit(bit); cx_write(gpio_oe_reg, value); }
static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev, int pin_number, int pin_logic_value) { int bit = pin_number; u32 gpio_reg = GPIO_LO; u32 value = 0; /* Check for valid pinNumber */ if (pin_number >= 47) return; /* change to output direction */ cx25821_set_gpiopin_direction(dev, pin_number, 0); if (pin_number > 31) { bit = pin_number - 31; gpio_reg = GPIO_HI; } value = cx_read(gpio_reg); if (pin_logic_value == 0) value &= Clear_GPIO_Bit(bit); else value |= Set_GPIO_Bit(bit); cx_write(gpio_reg, value); }
static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) { struct cx25821_dev *dev = dev_id; u32 audio_status; int handled = 0; struct sram_channel *sram_ch; if (!dev) return -1; sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels; audio_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ if (audio_status) { handled = cx25821_audio_upstream_irq(dev, dev->_audio_upstream_channel, audio_status); } if (handled < 0) cx25821_stop_upstream_audio(dev); else handled += handled; return IRQ_RETVAL(handled); }
/* * BOARD Specific: Handles audio IRQ */ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask) { struct cx23885_audio_dev *chip = dev->audio_dev; if (0 == (status & mask)) return 0; cx_write(AUDIO_INT_INT_STAT, status); /* risc op code error */ if (status & AUD_INT_OPC_ERR) { printk(KERN_WARNING "%s/1: Audio risc op code error\n", dev->name); cx_clear(AUD_INT_DMA_CTL, 0x11); cx23885_sram_channel_dump(dev, &dev->sram_channels[AUDIO_SRAM_CHANNEL]); } if (status & AUD_INT_DN_SYNC) { dprintk(1, "Downstream sync error\n"); cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); return 1; } /* risc1 downstream */ if (status & AUD_INT_DN_RISCI1) { atomic_set(&chip->count, cx_read(AUD_INT_A_GPCNT)); snd_pcm_period_elapsed(chip->substream); } /* FIXME: Any other status should deserve a special handling? */ return 1; }
void cx88_sram_channel_dump(struct cx88_core *core, const struct sram_channel *ch) { static const char * const name[] = { "initial risc", "cdt base", "cdt size", "iq base", "iq size", "risc pc", "iq wr ptr", "iq rd ptr", "cdt current", "pci target", "line / byte", }; u32 risc; unsigned int i,j,n; printk("%s: %s - dma channel status dump\n", core->name,ch->name); for (i = 0; i < ARRAY_SIZE(name); i++) printk("%s: cmds: %-12s: 0x%08x\n", core->name,name[i], cx_read(ch->cmds_start + 4*i)); for (n = 1, i = 0; i < 4; i++) { risc = cx_read(ch->cmds_start + 4 * (i+11)); printk("%s: risc%d: ", core->name, i); if (--n) printk("0x%08x [ arg #%d ]\n", risc, n); else n = cx88_risc_decode(risc); } for (i = 0; i < 16; i += n) { risc = cx_read(ch->ctrl_start + 4 * i); printk("%s: iq %x: ", core->name, i); n = cx88_risc_decode(risc); for (j = 1; j < n; j++) { risc = cx_read(ch->ctrl_start + 4 * (i+j)); printk("%s: iq %x: 0x%08x [ arg #%d ]\n", core->name, i+j, risc, j); } } printk("%s: fifo: 0x%08x -> 0x%x\n", core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); printk("%s: ctrl: 0x%08x -> 0x%x\n", core->name, ch->ctrl_start, ch->ctrl_start+6*16); printk("%s: ptr1_reg: 0x%08x\n", core->name,cx_read(ch->ptr1_reg)); printk("%s: ptr2_reg: 0x%08x\n", core->name,cx_read(ch->ptr2_reg)); printk("%s: cnt1_reg: 0x%08x\n", core->name,cx_read(ch->cnt1_reg)); printk("%s: cnt2_reg: 0x%08x\n", core->name,cx_read(ch->cnt2_reg)); }
static int cx8800_bit_getsda(void *data) { struct cx88_core *core = data; u32 state; state = cx_read(MO_I2C); return state & 0x01; }
int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds. cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ /* reset counter */ cx_write(sram_ch->gpcnt_ctl, 3); // Clear our bits from the interrupt status register. cx_write(sram_ch->int_stat, _intr_msk); //Set the interrupt mask register, enable irq. cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, IRQF_SHARED | IRQF_DISABLED, dev->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq); goto fail_irq; } // Start the DMA engine tmp = cx_read(sram_ch->dma_ctl); cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); dev->_is_running_ch2 = 1; dev->_is_first_frame_ch2 = 1; return 0; fail_irq: cx25821_dev_unregister(dev); return err; }
static int vp3054_bit_getsda(void *data) { struct cx8802_dev *dev = data; struct cx88_core *core = dev->core; u32 state; state = cx_read(MO_GP0_IO); return (state & 0x02) ? 1 : 0; }
static int cx23885_g_host_register(struct cx23885_dev *dev, struct v4l2_dbg_register *reg) { if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) return -EINVAL; reg->size = 4; reg->val = cx_read(reg->reg); return 0; }
static int netup_altera_fpga_rw(void *device, int flag, int data, int read) { struct cx23885_dev *dev = (struct cx23885_dev *)device; unsigned long timeout = jiffies + msecs_to_jiffies(1); uint32_t mem = 0; mem = cx_read(MC417_RWD); if (read) cx_set(MC417_OEN, ALT_DATA); else { cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */ mem &= ~ALT_DATA; mem |= (data & ALT_DATA); } if (flag) mem |= ALT_AD_RG; else mem &= ~ALT_AD_RG; mem &= ~ALT_CS; if (read) mem = (mem & ~ALT_RD) | ALT_WR; else mem = (mem & ~ALT_WR) | ALT_RD; cx_write(MC417_RWD, mem); /* start RW cycle */ for (;;) { mem = cx_read(MC417_RWD); if ((mem & ALT_RDY) == 0) break; if (time_after(jiffies, timeout)) break; udelay(1); } cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS); if (read) return mem & ALT_DATA; return 0; };
static void cx8800_bit_setsda(void *data, int state) { struct cx88_core *core = data; if (state) core->i2c_state |= 0x01; else core->i2c_state &= ~0x01; cx_write(MO_I2C, core->i2c_state); cx_read(MO_I2C); }
void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) { struct sram_channel *sram_ch = &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J]; u32 tmp = 0; if (!dev->_is_running_ch2) { printk ("cx25821: No video file is currently running so return!\n"); return; } //Disable RISC interrupts tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp & ~_intr_msk); //Turn OFF risc and fifo tmp = cx_read(sram_ch->dma_ctl); cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); //Clear data buffer memory if (dev->_data_buf_virt_addr_ch2) memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); dev->_is_running_ch2 = 0; dev->_is_first_frame_ch2 = 0; dev->_frame_count_ch2 = 0; dev->_file_status_ch2 = END_OF_FILE; if (dev->_irq_queues_ch2) { kfree(dev->_irq_queues_ch2); dev->_irq_queues_ch2 = NULL; } if (dev->_filename_ch2 != NULL) kfree(dev->_filename_ch2); tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); }
static s16 *read_rds_samples(struct cx88_core *core, u32 *N) { const struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27]; s16 *samples; unsigned int i; unsigned int bpl = srch->fifo_size/AUD_RDS_LINES; unsigned int spl = bpl/4; unsigned int sample_count = spl*(AUD_RDS_LINES-1); u32 current_address = cx_read(srch->ptr1_reg); u32 offset = (current_address - srch->fifo_start + bpl); dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), " "sample_count=%d, aud_intstat=%08x\n", current_address, current_address - srch->fifo_start, sample_count, cx_read(MO_AUD_INTSTAT)); samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL); if (!samples) return NULL; *N = sample_count; for (i = 0; i < sample_count; i++) { offset = offset % (AUD_RDS_LINES*bpl); samples[i] = cx_read(srch->fifo_start + offset); offset += 4; } if (dsp_debug >= 2) { dprintk(2, "RDS samples dump: "); for (i = 0; i < sample_count; i++) printk("%hd ", samples[i]); printk(".\n"); } return samples; }
void cx25821_stop_upstream_video(struct cx25821_channel *chan) { struct cx25821_video_out_data *out = chan->out; struct cx25821_dev *dev = chan->dev; const struct sram_channel *sram_ch = chan->sram_channels; u32 tmp = 0; if (!out->_is_running) { pr_info("No video file is currently running so return!\n"); return; } /* Set the interrupt mask register, disable irq. */ cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) & ~(1 << sram_ch->irq_bit)); /* Disable RISC interrupts */ tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp & ~_intr_msk); /* Turn OFF risc and fifo enable */ tmp = cx_read(sram_ch->dma_ctl); cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); free_irq(dev->pci->irq, chan); /* Clear data buffer memory */ if (out->_data_buf_virt_addr) memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); out->_is_running = 0; out->_is_first_frame = 0; out->_frame_count = 0; out->_file_status = END_OF_FILE; tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); }
static void vp3054_bit_setscl(void *data, int state) { struct cx8802_dev *dev = data; struct cx88_core *core = dev->core; struct vp3054_i2c_state *vp3054_i2c = dev->vp3054; if (state) { vp3054_i2c->state |= 0x0001; /* SCL high */ vp3054_i2c->state &= ~0x0100; /* external pullup */ } else { vp3054_i2c->state &= ~0x0001; /* SCL low */ vp3054_i2c->state |= 0x0100; /* drive pin */ } cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state); cx_read(MO_GP0_IO); }
/* We're given the Video Interrupt status register. * The cx23885_video_irq() func has already validated * the potential error bits, we just need to * deal with vbi payload and return indication if * we actually processed any payload. */ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status) { u32 count; int handled = 0; if (status & VID_BC_MSK_VBI_RISCI1) { dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__); spin_lock(&dev->slock); count = cx_read(VID_A_GPCNT); cx23885_video_wakeup(dev, &dev->vbiq, count); spin_unlock(&dev->slock); handled++; } return handled; }
static void vp3054_bit_setsda(void *data, int state) { struct cx8802_dev *dev = data; struct cx88_core *core = dev->core; struct vp3054_i2c_state *vp3054_i2c = dev->vp3054; if (state) { vp3054_i2c->state |= 0x0002; /* SDA high */ vp3054_i2c->state &= ~0x0200; /* tristate pin */ } else { vp3054_i2c->state &= ~0x0002; /* SDA low */ vp3054_i2c->state |= 0x0200; /* drive pin */ } cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state); cx_read(MO_GP0_IO); }
int cx23885_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct cx23885_dev *dev = video_drvdata(file); if (reg->match.addr > 1) return -EINVAL; if (reg->match.addr) return cx23417_g_register(dev, reg); if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) return -EINVAL; reg->size = 4; reg->val = cx_read(reg->reg); return 0; }
static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) { struct cx25821_channel *chan = dev_id; struct cx25821_dev *dev = chan->dev; u32 vid_status; int handled = 0; const struct sram_channel *sram_ch; if (!dev) return -1; sram_ch = chan->sram_channels; vid_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ if (vid_status) handled = cx25821_video_upstream_irq(chan, vid_status); return IRQ_RETVAL(handled); }
int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) { int handled = 0; u32 mask; const struct sram_channel *channel = dev->channels[chan_num].sram_channels; mask = cx_read(channel->int_msk); if (0 == (status & mask)) return handled; cx_write(channel->int_stat, status); /* risc op code error */ if (status & (1 << 16)) { pr_warn("%s, %s: video risc op code error\n", dev->name, channel->name); cx_clear(channel->dma_ctl, 0x11); cx25821_sram_channel_dump(dev, channel); } /* risc1 y */ if (status & FLD_VID_DST_RISC1) { struct cx25821_dmaqueue *dmaq = &dev->channels[channel->i].dma_vidq; struct cx25821_buffer *buf; spin_lock(&dev->slock); if (!list_empty(&dmaq->active)) { buf = list_entry(dmaq->active.next, struct cx25821_buffer, queue); buf->vb.vb2_buf.timestamp = ktime_get_ns(); buf->vb.sequence = dmaq->count++; list_del(&buf->queue); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } spin_unlock(&dev->slock); handled++; }
static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, struct sram_channel *sram_ch) { int count = 0; u32 tmp; do { /* Wait 10 microsecond before checking to see if the FIFO is * turned ON. */ udelay(10); tmp = cx_read(sram_ch->dma_ctl); /* 10 millisecond timeout */ if (count++ > 1000) { pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n", __func__); return; } } while (!(tmp & sram_ch->fld_aud_fifo_en)); }