1866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman/* 2866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * Copyright (C) 2005-2006 Micronas USA Inc. 3866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * 4866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * This program is free software; you can redistribute it and/or modify 5866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * it under the terms of the GNU General Public License (Version 2) as 6866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * published by the Free Software Foundation. 7866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * 8866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * This program is distributed in the hope that it will be useful, 9866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * but WITHOUT ANY WARRANTY; without even the implied warranty of 10866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * GNU General Public License for more details. 12866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * 13866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * You should have received a copy of the GNU General Public License 14866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * along with this program; if not, write to the Free Software Foundation, 15866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 16866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman */ 17866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 18866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/module.h> 19866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/kernel.h> 20866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/init.h> 21866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/spinlock.h> 22866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/wait.h> 23866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/list.h> 24866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/slab.h> 25866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/time.h> 26866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/mm.h> 27866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/usb.h> 28866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <linux/i2c.h> 29866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include <asm/byteorder.h> 30d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein#include <media/v4l2-common.h> 31866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 32866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include "saa7134-reg.h" 33866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include "saa7134.h" 34866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#include "go7007-priv.h" 35866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 36866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#define GO7007_HPI_DEBUG 37866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 38866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanenum hpi_address { 39866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_VIDEO_BUFFER = 0xe4, 40866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INIT_BUFFER = 0xea, 41866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INTR_RET_VALUE = 0xee, 42866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INTR_RET_DATA = 0xec, 43866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INTR_STATUS = 0xf4, 44866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INTR_WR_PARAM = 0xf6, 45866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman HPI_ADDR_INTR_WR_INDEX = 0xf8, 46866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 47866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 48866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanenum gpio_command { 49866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_RESET = 0x00, /* 000b */ 50866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_REQ1 = 0x04, /* 001b */ 51866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_WRITE = 0x20, /* 010b */ 52866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_REQ2 = 0x24, /* 011b */ 53866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_READ = 0x80, /* 100b */ 54866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_VIDEO = 0x84, /* 101b */ 55866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_IDLE = 0xA0, /* 110b */ 56866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GPIO_COMMAND_ADDR = 0xA4, /* 111b */ 57866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 58866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 59866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstruct saa7134_go7007 { 60866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev; 61866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u8 *top; 62866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u8 *bottom; 63866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dma_addr_t top_dma; 64866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dma_addr_t bottom_dma; 65866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 66866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 67866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic struct go7007_board_info board_voyager = { 68866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .firmware = "go7007tv.bin", 69866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .flags = 0, 70866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .sensor_flags = GO7007_SENSOR_656 | 71866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GO7007_SENSOR_VALID_ENABLE | 72866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GO7007_SENSOR_TV | 73866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GO7007_SENSOR_VBI, 74866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .audio_flags = GO7007_AUDIO_I2S_MODE_1 | 75866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GO7007_AUDIO_WORD_16, 76866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .audio_rate = 48000, 77866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .audio_bclk_div = 8, 78866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .audio_main_div = 2, 79866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .hpi_buffer_cap = 7, 80866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .num_inputs = 1, 81866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .inputs = { 82866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman { 83866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .name = "SAA7134", 84866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman }, 85866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman }, 86866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 875d929a71908968905331cda0d52c44570d402110Ben HutchingsMODULE_FIRMWARE("go7007tv.bin"); 88866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 89866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman/********************* Driver for GPIO HPI interface *********************/ 90866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 91866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data) 92866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 93866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0xff); 94866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 95866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Write HPI address */ 96866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, addr); 97866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR); 98866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 99866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 100866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Write low byte */ 101866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff); 102866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE); 103866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 104866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 105866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Write high byte */ 106866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8); 107866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE); 108866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 109866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 110866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 111866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 112866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 113866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data) 114866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 115866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0xff); 116866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 117866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Write HPI address */ 118866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, addr); 119866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR); 120866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 121866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 122866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0x00); 123866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 124866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Read low byte */ 125866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ); 126866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 127866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 128866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman *data = saa_readb(SAA7134_GPIO_GPSTATUS0); 129866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 130866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 131866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Read high byte */ 132866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ); 133866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 134866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 135866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8; 136866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 137866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 138866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 139866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 140866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 141866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_interface_reset(struct go7007 *go) 142866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 143866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 144866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev = saa->dev; 145866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u32 status; 146866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u16 intr_val, intr_data; 147866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman int count = 20; 148866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 149866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */ 150866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4); 151866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0xff); 152866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 153866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1); 154866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET); 155866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman msleep(1); 156866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1); 157866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2); 158866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman msleep(10); 159866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 160866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 161866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 162866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 163866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman status = saa_readb(SAA7134_GPIO_GPSTATUS2); 164866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */ 165866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 166866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* enter command mode...(?) */ 167866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1); 168866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2); 169866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 170866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman do { 171866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 172866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 173866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman status = saa_readb(SAA7134_GPIO_GPSTATUS2); 174866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */ 175866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } while (--count > 0); 176866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 177866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Wait for an interrupt to indicate successful hardware reset */ 178866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || 179866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman (intr_val & ~0x1) != 0x55aa) { 180866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_ERR 181866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman "saa7134-go7007: unable to reset the GO7007\n"); 182866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -1; 183866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 184866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 185866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 186866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 187866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data) 188866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 189866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 190866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev = saa->dev; 191866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman int i; 192866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u16 status_reg; 193866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 194866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#ifdef GO7007_HPI_DEBUG 195866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_DEBUG 196866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data); 197866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#endif 198866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 199866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman for (i = 0; i < 100; ++i) { 200866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg); 201866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!(status_reg & 0x0010)) 202866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman break; 203866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman msleep(10); 204866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 205866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (i == 100) { 206866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_ERR 207866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman "saa7134-go7007: device is hung, status reg = 0x%04x\n", 208866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman status_reg); 209866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -1; 210866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 211866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data); 212866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr); 213866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 214866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 215866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 216866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 217866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_read_interrupt(struct go7007 *go) 218866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 219866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 220866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev = saa->dev; 221866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 222866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* XXX we need to wait if there is no interrupt available */ 223866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->interrupt_available = 1; 224866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value); 225866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data); 226866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#ifdef GO7007_HPI_DEBUG 227866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n", 228866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->interrupt_value, go->interrupt_data); 229866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#endif 230866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 231866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 232866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 233866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev, 234866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman unsigned long status) 235866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 236866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct go7007 *go = video_get_drvdata(dev->empress_dev); 237866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 238866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 239866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!go->streaming) 240866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return; 241866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (0 != (status & 0x000f0000)) 242866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n", 243866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman (status >> 16) & 0x0f); 244866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (status & 0x100000) { 2456d256fa8868b4509310ea201c2d2c04fabea96abFUJITA Tomonori dma_sync_single_for_cpu(&dev->pci->dev, 2466d256fa8868b4509310ea201c2d2c04fabea96abFUJITA Tomonori saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE); 247866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE); 248866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma)); 249866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } else { 2506d256fa8868b4509310ea201c2d2c04fabea96abFUJITA Tomonori dma_sync_single_for_cpu(&dev->pci->dev, 2516d256fa8868b4509310ea201c2d2c04fabea96abFUJITA Tomonori saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE); 252866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go7007_parse_video_stream(go, saa->top, PAGE_SIZE); 253866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma)); 254866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 255866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 256866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 257866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_stream_start(struct go7007 *go) 258866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 259866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 260866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev = saa->dev; 261866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 262866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top), 263866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 0, PAGE_SIZE, DMA_FROM_DEVICE); 264866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!saa->top_dma) 265866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -ENOMEM; 266866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa->bottom_dma = dma_map_page(&dev->pci->dev, 267866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman virt_to_page(saa->bottom), 268866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 0, PAGE_SIZE, DMA_FROM_DEVICE); 269866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!saa->bottom_dma) { 270866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE, 271866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman DMA_FROM_DEVICE); 272866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -ENOMEM; 273866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 274866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 275866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000); 276866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200); 277866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 278866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Set HPI interface for video */ 279866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0xff); 280866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER); 281866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR); 282866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0x00); 283866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 284866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Enable TS interface */ 285866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_TS_PARALLEL, 0xe6); 286866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 287866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Reset TS interface */ 288866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setb(SAA7134_TS_SERIAL1, 0x01); 289866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_TS_SERIAL1, 0x01); 290866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 291866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Set up transfer block size */ 292866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1); 293866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1); 294866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_TS_DMA1, 0); 295866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_TS_DMA2, 0); 296866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 297866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Enable video streaming mode */ 298866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO); 299866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 300866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma)); 301866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma)); 302866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_PITCH(5), 128); 303866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX); 304866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 305866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Enable TS FIFO */ 306866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5); 307866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 308866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Enable DMA IRQ */ 309866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_setl(SAA7134_IRQ1, 310866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0); 311866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 312866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 313866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 314866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 315866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_stream_stop(struct go7007 *go) 316866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 317866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 318d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct saa7134_dev *dev; 319d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein 320d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein if (!saa) 321d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return -EINVAL; 322d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein dev = saa->dev; 323d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein if (!dev) 324d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return -EINVAL; 325866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 326866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Shut down TS FIFO */ 327866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5); 328866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 329866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Disable DMA IRQ */ 330866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearl(SAA7134_IRQ1, 331866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0); 332866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 333866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Disable TS interface */ 334866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_clearb(SAA7134_TS_PARALLEL, 0x80); 335866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 336866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE, 337866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman DMA_FROM_DEVICE); 338866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE, 339866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman DMA_FROM_DEVICE); 340866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 341866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 342866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 343866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 344866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len) 345866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 346866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa = go->hpi_context; 347866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_dev *dev = saa->dev; 348866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman u16 status_reg; 349866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman int i; 350866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 351866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#ifdef GO7007_HPI_DEBUG 352866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer " 353866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman "sending %d bytes\n", len); 354866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman#endif 355866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 356866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman while (len > 0) { 357866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman i = len > 64 ? 64 : len; 358866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPMODE0, 0xff); 359866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER); 360866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR); 361866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 362866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman while (i-- > 0) { 363866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS0, *data); 364866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE); 365866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE); 366866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman ++data; 367866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman --len; 368866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 369866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman for (i = 0; i < 100; ++i) { 370866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg); 371866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!(status_reg & 0x0002)) 372866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman break; 373866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 374866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (i == 100) { 375866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_ERR "saa7134-go7007: device is hung, " 376866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman "status reg = 0x%04x\n", status_reg); 377866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -1; 378866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 379866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman } 380866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 381866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 382866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 383d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberleinstatic int saa7134_go7007_send_command(struct go7007 *go, unsigned int cmd, 384d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein void *arg) 385d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein{ 386d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct saa7134_go7007 *saa = go->hpi_context; 387d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct saa7134_dev *dev = saa->dev; 388d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein 389d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein switch (cmd) { 390d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein case VIDIOC_S_STD: 391d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein { 392d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein v4l2_std_id *std = arg; 393d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return saa7134_s_std_internal(dev, NULL, std); 394d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 395d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein case VIDIOC_G_STD: 396d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein { 397d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein v4l2_std_id *std = arg; 398d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein *std = dev->tvnorm->id; 399d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return 0; 400d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 401d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein case VIDIOC_QUERYCTRL: 402d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein { 403d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct v4l2_queryctrl *ctrl = arg; 404d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) 405d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return saa7134_queryctrl(NULL, NULL, ctrl); 406d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 407d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein case VIDIOC_G_CTRL: 408d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein { 409d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct v4l2_control *ctrl = arg; 410d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) 411d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return saa7134_g_ctrl_internal(dev, NULL, ctrl); 412d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 413d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein case VIDIOC_S_CTRL: 414d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein { 415d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein struct v4l2_control *ctrl = arg; 416d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) 417d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return saa7134_s_ctrl_internal(dev, NULL, ctrl); 418d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 419d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein } 420d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein return -EINVAL; 421d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein 422d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein} 423d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein 424866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic struct go7007_hpi_ops saa7134_go7007_hpi_ops = { 425866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .interface_reset = saa7134_go7007_interface_reset, 426866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .write_interrupt = saa7134_go7007_write_interrupt, 427866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .read_interrupt = saa7134_go7007_read_interrupt, 428866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .stream_start = saa7134_go7007_stream_start, 429866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .stream_stop = saa7134_go7007_stream_stop, 430866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .send_firmware = saa7134_go7007_send_firmware, 431d73f822ce775e004836ffc01ce9feae27d0d65cfPete Eberlein .send_command = saa7134_go7007_send_command, 432866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 433866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 434866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman/********************* Add/remove functions *********************/ 435866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 436866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_init(struct saa7134_dev *dev) 437866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 438866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct go7007 *go; 439866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa; 440866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 441866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n"); 442866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 4437a6cb0d5497418599d2125b670926b75e673861cJulia Lawall saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL); 444866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (saa == NULL) 445866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -ENOMEM; 446866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 447866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Allocate a couple pages for receiving the compressed stream */ 448866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa->top = (u8 *)get_zeroed_page(GFP_KERNEL); 449866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!saa->top) 450866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman goto allocfail; 451866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL); 452866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (!saa->bottom) 453866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman goto allocfail; 454866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 455866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go = go7007_alloc(&board_voyager, &dev->pci->dev); 456866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (go == NULL) 457866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman goto allocfail; 458866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->board_id = GO7007_BOARDID_PCI_VOYAGER; 459866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name)); 460866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->hpi_ops = &saa7134_go7007_hpi_ops; 461866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->hpi_context = saa; 462866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa->dev = dev; 463866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 464866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Boot the GO7007 */ 465866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (go7007_boot_encoder(go, go->board_info->flags & 466866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman GO7007_BOARD_USE_ONBOARD_I2C) < 0) 467866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman goto initfail; 468866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 469866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman /* Do any final GO7007 initialization, then register the 470866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman * V4L2 and ALSA interfaces */ 471866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (go7007_register_encoder(go) < 0) 472866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman goto initfail; 473866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dev->empress_dev = go->video_dev; 474866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman video_set_drvdata(dev->empress_dev, go); 475866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 476866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->status = STATUS_ONLINE; 477866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 478866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 479866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmaninitfail: 480866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->status = STATUS_SHUTDOWN; 481866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 482866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 483866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanallocfail: 484866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (saa->top) 485866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman free_page((unsigned long)saa->top); 486866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (saa->bottom) 487866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman free_page((unsigned long)saa->bottom); 488866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman kfree(saa); 489866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return -ENOMEM; 490866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 491866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 492866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int saa7134_go7007_fini(struct saa7134_dev *dev) 493866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 494866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct go7007 *go; 495866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman struct saa7134_go7007 *saa; 496866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 497866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman if (NULL == dev->empress_dev) 498866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 499866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 500866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go = video_get_drvdata(dev->empress_dev); 501866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa = go->hpi_context; 502866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go->status = STATUS_SHUTDOWN; 503866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman free_page((unsigned long)saa->top); 504866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman free_page((unsigned long)saa->bottom); 505866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman kfree(saa); 506866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman go7007_remove(go); 507866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman dev->empress_dev = NULL; 508866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 509866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return 0; 510866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 511866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 512866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic struct saa7134_mpeg_ops saa7134_go7007_ops = { 513866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .type = SAA7134_MPEG_GO7007, 514866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .init = saa7134_go7007_init, 515866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .fini = saa7134_go7007_fini, 516866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman .irq_ts_done = saa7134_go7007_irq_ts_done, 517866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman}; 518866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 519866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic int __init saa7134_go7007_mod_init(void) 520866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 521866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman return saa7134_ts_register(&saa7134_go7007_ops); 522866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 523866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 524866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanstatic void __exit saa7134_go7007_mod_cleanup(void) 525866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman{ 526866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman saa7134_ts_unregister(&saa7134_go7007_ops); 527866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman} 528866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 529866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanmodule_init(saa7134_go7007_mod_init); 530866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartmanmodule_exit(saa7134_go7007_mod_cleanup); 531866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-Hartman 532866b8695d67e83f47194731d3a7ba55826a7ec70Greg Kroah-HartmanMODULE_LICENSE("GPL v2"); 533