Ejemplo n.º 1
0
static int inno_request_firmware(char *fw_name)
{
	int ret;
	/* uses the default method to get the firmware */
	const struct firmware *fw_entry;

	if(fw_name==NULL) {
		inno_msg(KERN_ERR "innodev: error, firmware name is NULL");
		return -EINVAL;
	}

	inno_msg(KERN_INFO "innodev: if2xx requesting firmware (%s)", fw_name);

	if(request_firmware(&fw_entry, fw_name, g_innodev_platform_dev)!=0)
	{
		inno_msg(KERN_ERR "innodev: firmware (%s) not available!", fw_name);
		return -EINVAL;
	}

	inno_msg(KERN_INFO "innodev: if2xx loaded firmware %d bytes", fw_entry->size);
	ret = inno_download_firmware((char*)fw_entry->data, fw_entry->size);

	release_firmware(fw_entry);

	/* finish setting up the device */
	return ret;
}
Ejemplo n.º 2
0
ssize_t INNODev_sync(struct INNODev_data *INNODevS, struct spi_message *message)
{
	int ret;
	if(!flag_spi_ok){
		inno_msg("Warning:spi_sync timeout,should not to use spi");
		return -1;
	}	
	//	spin_lock_irq(&INNODevS->spi_lock);
	mutex_lock(&inno_mtkspi_mutex);
	//inno_msg("**s"); 
	if (INNODevS->spi == NULL){
		inno_err("spi ==NULL");
		ret = -ESHUTDOWN;
	}
	else
		ret = spi_sync(INNODevS->spi, message);

	// inno_msg("**e");
	mutex_unlock(&inno_mtkspi_mutex);
	//	spin_unlock_irq(&INNODevS->spi_lock);
	/*
	   if (ret == 0) {                                                
	   ret = message->status;
	   if (ret == 0)
	   ret = message->actual_length;
	   }
	 */
	if(ret){
		inno_err("spi_sync fail ret=%d,should check",ret);
		if(ret == -ETIME){
       		flag_spi_ok = 0;
		}
	}		 
	return ret;
}
Ejemplo n.º 3
0
/*
 * Init and Deinit SPI interface 
 *
 * Parameter:
 *		enable <in>		: enable or disable SPI interface
 *
 * Example:
 *		INNO_SPI_Init(1);	// Enable SPI interface
 *		INNO_SPI_Init(0);	// Enable SPI interface
 */
INNO_RET INNO_SPI_Init(int enable)
{
	mutex_lock(&inno_spi_mutex);
	if(enable){
		struct mt6575_chip_conf* spi_par;
		cmmb_spi_src_buffer_all = kmalloc(CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES,GFP_KERNEL);
		if(cmmb_spi_src_buffer_all== NULL){
			inno_err("error kmalloc fail cmmb_spi_src_buffer_all");
			mutex_unlock(&inno_spi_mutex);
			return INNO_GENERAL_ERROR;
		}
                INNODev->spi->controller_data =(void*)&spi_conf; 
                spi_par =&spi_conf;
		if(!spi_par){
			inno_err("spi config fail");
			mutex_unlock(&inno_spi_mutex);
			return INNO_GENERAL_ERROR;
		}
		spi_par->setuptime = 15;
		spi_par->holdtime = 15;
		spi_par->high_time = 10;       //10--6m   15--4m   20--3m  30--2m  [ 60--1m 120--0.5m  300--0.2m]
		spi_par->low_time = 10;
		spi_par->cs_idletime = 20;

		spi_par->rx_mlsb = 1; 
		spi_par->tx_mlsb = 1;		 
		spi_par->tx_endian = 0;
		spi_par->rx_endian = 0;

		spi_par->cpol = 0;
		spi_par->cpha = 0;
		spi_par->com_mod = DMA_TRANSFER;

		spi_par->pause = 0;
		spi_par->finish_intr = 1;
		spi_par->deassert = 0;

		if(spi_setup(INNODev->spi)){
			inno_err("spi_setup fail");
			mutex_unlock(&inno_spi_mutex);
			return INNO_GENERAL_ERROR;
		}

#if 0           //check spi register
		spi_cfg0 = (int*)ioremap(0x700B2000,4);
		spi_cfg1 = (int*)ioremap(0x700B2000+0x4,4);
		spi_cmd = (int*)ioremap(0x700B2000+0x18,4);  
		inno_msg("SPI CFG0:%08x, SPI_CFG1:%08x, SPI_CMD:%08x\n",*spi_cfg0,*spi_cfg1,*spi_cmd);
		iounmap(spi_cfg0);
		iounmap(spi_cfg1);
		iounmap(spi_cmd);
#endif
	}
	else{
		kfree(cmmb_spi_src_buffer_all);
		cmmb_spi_src_buffer_all =NULL; 
	}
	mutex_unlock(&inno_spi_mutex);
	return INNO_NO_ERROR;
}
INNO_RET  INNODev_xfer(unsigned char *txbuf,unsigned char *rxbuf, int len)
{
	int const pkt_count = len / CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES;
	int const remainder = len % CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES;
	struct spi_message msg;
	spi_message_init(&msg);

	inno_msg(" len=%d, txbuf=0x%p,rxbuf=0x%p",len,txbuf,rxbuf);
	if(len>CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES){	
		transfer_1[0].tx_buf =(txbuf==NULL)?NULL: txbuf;
		transfer_1[0].rx_buf =(rxbuf==NULL)?NULL: rxbuf;
		transfer_1[0].len = CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES*pkt_count;
		spi_message_add_tail(&transfer_1[0], &msg);

		if(0 != remainder)	 { 
			transfer_1[1].tx_buf =(txbuf==NULL)?NULL:txbuf+ (CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES * pkt_count);
			transfer_1[1].rx_buf =(rxbuf==NULL)?NULL:rxbuf+ (CMMB_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES * pkt_count);
			transfer_1[1].len = remainder;
			spi_message_add_tail(&transfer_1[1], &msg);
		}
	}
	else{
		transfer_1[0].tx_buf =(txbuf==NULL)?NULL: txbuf;
		transfer_1[0].rx_buf =(rxbuf==NULL)?NULL: rxbuf;
		transfer_1[0].len = len;
		spi_message_add_tail(&transfer_1[0], &msg);
	}
	if(INNODev_sync(INNODev,&msg))
		return INNO_GENERAL_ERROR;	
	else
		return INNO_NO_ERROR;
}
Ejemplo n.º 5
0
void inno_irq_release(void)
{
	mt_eint_mask(CUST_EINT_CMMB_NUM);   
	mt_set_gpio_pull_enable(GPIO_CMMB_EINT_PIN, 1);
	mt_set_gpio_pull_select(GPIO_CMMB_EINT_PIN,  0);
	mt_set_gpio_mode(GPIO_CMMB_EINT_PIN, GPIO_CMMB_EINT_PIN_M_GPIO);                 //set to eint MODE for enable eint function
	inno_msg("CMMB GPIO EINT PIN mode:num:%d, %d, dir:%d,pullen:%d,pullup%d",GPIO_CMMB_EINT_PIN,mt_get_gpio_mode(GPIO_CMMB_EINT_PIN),
			mt_get_gpio_dir(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_enable(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_select(GPIO_CMMB_EINT_PIN));    
//	mt_set_gpio_dir(GPIO_CMMB_EINT_PIN, GPIO_DIR_OUT);               // set to input avoid of leak power
}
Ejemplo n.º 6
0
static void check_block_thread(void *arg)
{
	inno_msg("runing for check block status\n");
	int oldcount=intCount;
	msleep(1000*60);                        //wait 60s for to get mfs
	int version=0;
	INNO_GetFirmwareVersion(&version);
	inno_msg("version =%d",version);
	while(1){
		if (intCount ==oldcount) {
			inno_msg("error over 20 second no interrup,then gerversion");
#if 1
			//xingyu debug get firmware the first 8 bytes
			inno_msg("INNO_GetFirmwareBytes for get the first 8 bytes");
			int ret =INNO_GetFirmwareBytes();
			if(ret != INNO_NO_ERROR)       {
				inno_err("INNO_GetFirmwareBytes fail");
			}	
#else	
			INNO_GetFirmwareVersion(&version);
			inno_msg("version =%d",version);
#endif				
			break;
		}
		else
			oldcount = intCount;
		msleep(1000*10);
	}
	msleep(1000*3);
	inno_msg("exit");

}
Ejemplo n.º 7
0
void inno_chip_reset(void)
{
	mt_set_gpio_mode(GPIO_CMMB_RST_PIN, GPIO_CMMB_RST_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CMMB_RST_PIN, GPIO_DIR_OUT);

//	mdelay(1);
	mt_set_gpio_out(GPIO_CMMB_RST_PIN, GPIO_OUT_ZERO); 			 
	mdelay(30);                                                                                  //delay for power to reset  typical:10ms max:50ms
	mt_set_gpio_out(GPIO_CMMB_RST_PIN, GPIO_OUT_ONE); 
//	mt_set_gpio_pull_enable(GPIO_CMMB_RST_PIN, 1);
//	mt_set_gpio_pull_select(GPIO_CMMB_RST_PIN,  1);
	inno_msg("CMMB GPIO RST PIN mode:num:%d, %d,out:%d, dir:%d,pullen:%d,pullup%d",GPIO_CMMB_RST_PIN,mt_get_gpio_mode(GPIO_CMMB_RST_PIN),mt_get_gpio_out(GPIO_CMMB_RST_PIN),mt_get_gpio_dir(GPIO_CMMB_RST_PIN),mt_get_gpio_pull_enable(GPIO_CMMB_RST_PIN),mt_get_gpio_pull_select(GPIO_CMMB_RST_PIN));    	 
	mdelay(30);                                                                                  //delay for waiting system ready typical:10ms max:50ms
}
Ejemplo n.º 8
0
/*
 * register irq handler
 * parmaters pass by inno_core
 * @handler		-	if101 irq handler function pointer
 * @irq_type	-	if101 irq type (falling edge detect or rising)
 */
int inno_irq_setup(void (*interrupthandler)(void ))
{
	mt_set_gpio_mode(GPIO_CMMB_EINT_PIN, GPIO_CMMB_EINT_PIN_M_EINT);                 //set to eint MODE for enable eint function
	mt_set_gpio_dir(GPIO_CMMB_EINT_PIN, GPIO_DIR_IN); 
#if 1
	mt_set_gpio_pull_enable(GPIO_CMMB_EINT_PIN, 1);
	mt_set_gpio_pull_select(GPIO_CMMB_EINT_PIN,  1);
#endif
	inno_msg("CMMB GPIO EINT PIN mode:num:%d, %d, dir:%d,pullen:%d,pullup%d",GPIO_CMMB_EINT_PIN,mt_get_gpio_mode(GPIO_CMMB_EINT_PIN),
			mt_get_gpio_dir(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_enable(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_select(GPIO_CMMB_EINT_PIN));    
	// rename the functions mt65xx_eint_xx by mt_eint_xx   rui
	mt_eint_registration(CUST_EINT_CMMB_NUM, EINTF_TRIGGER_FALLING, interrupthandler, 0);         // 0:auto mask is no
	mt_eint_unmask(CUST_EINT_CMMB_NUM);   
	//    mt_eint_mask(CUST_EINT_CMMB_NUM);   
	return 0;
}
Ejemplo n.º 9
0
static unsigned int lgx_poll(struct file* filp, poll_table *wait)
{
	unsigned int ret = 0;
	struct inno_lgx* lgx = (struct inno_lgx*)filp->private_data;
	struct inno_buffer* inno_buf = &lgx->inno_buffer;
	poll_wait(filp, &lgx->read_wait, wait);

	if(inno_buf->valid && inno_buf->own_id==lgx->ids->id)
		ret = POLLIN | POLLRDNORM;

	if(cancle_wait){
		inno_msg("lgx->cancle_wait");
		ret = POLLNVAL;
	}
	return ret;
}
Ejemplo n.º 10
0
/*
 * register irq handler
 * parmaters pass by inno_core
 * @handler		-	if101 irq handler function pointer
 * @irq_type	-	if101 irq type (falling edge detect or rising)
 */
int inno_irq_setup(void (*interrupthandler)(void ))
{
	mt_set_gpio_mode(GPIO_CMMB_EINT_PIN, GPIO_CMMB_EINT_PIN_M_EINT);                 //set to eint MODE for enable eint function
	mt_set_gpio_dir(GPIO_CMMB_EINT_PIN, GPIO_DIR_IN); 
#if 1
	mt_set_gpio_pull_enable(GPIO_CMMB_EINT_PIN, 1);
	mt_set_gpio_pull_select(GPIO_CMMB_EINT_PIN,  1);
#endif
	inno_msg("CMMB GPIO EINT PIN mode:num:%d, %d, dir:%d,pullen:%d,pullup%d",GPIO_CMMB_EINT_PIN,mt_get_gpio_mode(GPIO_CMMB_EINT_PIN),
			mt_get_gpio_dir(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_enable(GPIO_CMMB_EINT_PIN),mt_get_gpio_pull_select(GPIO_CMMB_EINT_PIN));    

	mt65xx_eint_set_sens(CUST_EINT_CMMB_NUM, CUST_EINT_EDGE_SENSITIVE);
	mt65xx_eint_registration(CUST_EINT_CMMB_NUM, CUST_EINT_DEBOUNCE_DISABLE, CUST_EINT_POLARITY_LOW, interrupthandler, 0);         // 0:auto mask is no
	mt65xx_eint_unmask(CUST_EINT_CMMB_NUM);   
	//    mt65xx_eint_mask(CUST_EINT_CMMB_NUM);   
	return 0;
}
Ejemplo n.º 11
0
/*
 * Set and Reset SPI GPIO pins 
 *
 * Parameter:
 *		enable <in>		: Set and Reset SPI GPIO pins 
 *
 * Example:
 *		INNO_SPI_Init(1);	// Set SPI GPIO pins 
 *		INNO_SPI_Init(0);	// Reset SPI GPIO pins 
 */
INNO_RET INNO_SPI_GPIO_Set(int enable)
{
	mutex_lock(&inno_spi_mutex);
	if(enable)
		{
			mt_set_gpio_mode(GPIO_SPI_CS_PIN, GPIO_SPI_CS_PIN_M_SPI_CS);
			mt_set_gpio_pull_enable(GPIO_SPI_CS_PIN, GPIO_PULL_ENABLE);
			mt_set_gpio_pull_select(GPIO_SPI_CS_PIN, GPIO_PULL_UP);
			
			mt_set_gpio_mode(GPIO_SPI_SCK_PIN, GPIO_SPI_SCK_PIN_M_SPI_CK);
			mt_set_gpio_pull_enable(GPIO_SPI_SCK_PIN, GPIO_PULL_ENABLE);
			mt_set_gpio_pull_select(GPIO_SPI_SCK_PIN, GPIO_PULL_DOWN);
			
			mt_set_gpio_mode(GPIO_SPI_MISO_PIN, GPIO_SPI_MISO_PIN_M_SPI_MI);
			mt_set_gpio_pull_enable(GPIO_SPI_MISO_PIN, GPIO_PULL_ENABLE);
			mt_set_gpio_pull_select(GPIO_SPI_MISO_PIN, GPIO_PULL_DOWN);
			
			mt_set_gpio_mode(GPIO_SPI_MOSI_PIN, GPIO_SPI_MOSI_PIN_M_SPI_MO);
			mt_set_gpio_pull_enable(GPIO_SPI_MOSI_PIN, GPIO_PULL_ENABLE);
			mt_set_gpio_pull_select(GPIO_SPI_MOSI_PIN, GPIO_PULL_DOWN);
			inno_msg("CMMB GPIO CS SPI PIN mode:num:%d, %d,out:%d, dir:%d,pullen:%d,pullup%d",GPIO_SPI_CS_PIN,mt_get_gpio_mode(GPIO_SPI_CS_PIN),mt_get_gpio_out(GPIO_SPI_CS_PIN),
			mt_get_gpio_dir(GPIO_SPI_CS_PIN),mt_get_gpio_pull_enable(GPIO_SPI_CS_PIN),mt_get_gpio_pull_select(GPIO_SPI_CS_PIN));    
		}
	else
		{
			mt_set_gpio_mode(GPIO_SPI_CS_PIN, GPIO_SPI_CS_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_SPI_CS_PIN, GPIO_DIR_IN);
			mt_set_gpio_pull_enable(GPIO_SPI_CS_PIN, GPIO_PULL_DISABLE);
			
			mt_set_gpio_mode(GPIO_SPI_SCK_PIN, GPIO_SPI_SCK_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_SPI_SCK_PIN, GPIO_DIR_IN);
			mt_set_gpio_pull_enable(GPIO_SPI_SCK_PIN, GPIO_PULL_DISABLE);
			
			mt_set_gpio_mode(GPIO_SPI_MISO_PIN, GPIO_SPI_MISO_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_SPI_MISO_PIN, GPIO_DIR_IN);
			mt_set_gpio_pull_enable(GPIO_SPI_MISO_PIN, GPIO_PULL_DISABLE);
			
			mt_set_gpio_mode(GPIO_SPI_MOSI_PIN, GPIO_SPI_MOSI_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_SPI_MOSI_PIN, GPIO_DIR_IN);
			mt_set_gpio_pull_enable(GPIO_SPI_MOSI_PIN, GPIO_PULL_DISABLE);
		}
	
	mutex_unlock(&inno_spi_mutex);
	return INNO_NO_ERROR;
	
}
Ejemplo n.º 12
0
//static int lgx_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg)
static long lgx_ioctl(struct file* filp, unsigned int cmd, unsigned long arg)
{
	long retval = 0;
	long val;
//	inno_device_t* inno_dev = &g_inno_dev;

	/* FIHTDC, ALXiao, add cmmb ftm test function, 20101008 { */
	if(_IOC_TYPE(cmd) != INNO_IOC_MAGIC)
		return -ENOTTY;
	/* FIHTDC, ALXiao, add cmmb ftm test function, 20101008 } */

	inno_msg("[CMMB]%s+",__FUNCTION__);

	// ASUS_BSP+++ JimmyLin "[CMMB] avoid UI hang"
	// msleep(100);
	// ASUS_BSP--- 
	switch(cmd){
		case INNO_STOP_POLL:                // stop polling,avoid poll block,then driver can't deinit
			{
				cancle_wait  =(u8)arg;
				inno_msg("[lgx_ioctl] INNO_STOP_POLL cancle_wait =%d",cancle_wait);
				if(cancle_wait){
					struct inno_lgx* lgx0 = g_inno_dev.lgxs[0];
					struct inno_lgx* lgx1 = g_inno_dev.lgxs[1];
					struct inno_lgx* lgx2 = g_inno_dev.lgxs[2];
					struct inno_lgx* lgx3 = g_inno_dev.lgxs[3];
					wake_up_interruptible(&lgx0->read_wait);
					wake_up_interruptible(&lgx1->read_wait);
					wake_up_interruptible(&lgx2->read_wait);
					wake_up_interruptible(&lgx3->read_wait);
				}
				break;
			}
		case INNO_MEMSET_MFS:                      // memset mfs buffer before fetch mfs data
			{
				flag_memset= (u8)arg; 
				inno_msg("[lgx_ioctl] INNO_MEMSET_MFS flag_memset =%d",flag_memset);
				break;
			}
#if 0
		case INNO_GET_INTR_TYPE:                              //no use
			inno_msg("[lgx_ioctl] INNO_GET_INTR_TYPE");
			val = inno_dev->cfg.intr_type;
			put_user(val, (long*)arg);
			break;
		case INNO_READ_REG:                                  //no use
			{
				struct inno_reg_data* reg_data;
				inno_msg("[lgx_ioctl] INNO_READ_REG");
				reg_data = kmalloc(sizeof(struct inno_reg_data), GFP_KERNEL);
				retval = copy_from_user(reg_data, (void*)arg, sizeof(struct inno_reg_data));
				if(retval == 0){
					/*
					   down(&inno_iic_mutex);
					   g_inno_dev.i2c_driver->read(reg_data->reg, (unsigned char*)&reg_data->data);	
					   up(&inno_iic_mutex);
					   retval = copy_to_user((void*)arg, reg_data, sizeof(struct inno_reg_data));
					 */
				}
				kfree(reg_data);
				break;
			}
		case INNO_WRITE_REG:                                 //no use
			{
				struct inno_reg_data* reg_data;
				inno_msg("[lgx_ioctl] INNO_WRITE_REG");
				reg_data = kmalloc(sizeof(struct inno_reg_data), GFP_KERNEL);
				retval = copy_from_user(reg_data, (void*)arg, sizeof(struct inno_reg_data));
				if(retval == 0){
					/*
					   down(&inno_iic_mutex);
					   g_inno_dev.i2c_driver->write(reg_data->reg, reg_data->data);
					   up(&inno_iic_mutex);
					   retval = copy_to_user((void*)arg, reg_data, sizeof(struct inno_reg_data));
					 */
				}
				kfree(reg_data);
				break;
			}
		case INNO_MMIS_READ:                     	//no use
			{
				u8 reg  = (u8)arg;
				u8 value;
				inno_msg("[lgx_ioctl] INNO_MMIS_READ");
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);
				g_inno_dev.spi_driver->write(&reg, 1);
				inno_spi_drive_cs(1);

				inno_spi_drive_cs(0);
				g_inno_dev.spi_driver->read(&value, 1);
				inno_spi_drive_cs(1);

				retval = value;
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_MMIS_CMD:	                       //no use
			{
				u8 value = (u8)arg;
				inno_msg("[lgx_ioctl] INNO_MMIS_CMD");
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&value,1);
				inno_spi_drive_cs(1);		
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_MMIS_WRITE:	          //pass value	mmis_cmd|value no use
			{
				u8 cmd, value;
				inno_msg("[lgx_ioctl] INNO_MMIS_WRITE");
				val = arg;
				cmd = (val & 0xFF00)>>8;
				value = (val & 0x00FF);
				mutex_lock(&inno_spi_mutex);
				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&cmd, 1);
				inno_spi_drive_cs(1);

				inno_spi_drive_cs(0);		
				g_inno_dev.spi_driver->write(&value, 1);
				inno_spi_drive_cs(1);
				mutex_unlock(&inno_spi_mutex);
				break;
			}
		case INNO_SCAN_FREQUENCY:                   // if228 not support scan function  no use
			{
				struct inno_freq_scan_area* 	scan_area;
				inno_msg("[lgx_ioctl] INNO_SCAN_FREQUENCY");
				scan_area = kmalloc(sizeof(struct inno_freq_scan_area), GFP_KERNEL);
				retval = copy_from_user(scan_area, (void*)arg, sizeof(struct inno_freq_scan_area));

				if(retval == 0)
					;//retval = inno_scan_frequency(scan_area->start, scan_area->end);
				kfree(scan_area);
				break;
			}
		case INNO_SCAN_FREQUENCY_DOT:              // if228 not support scan function no use
			{
				struct inno_freq_scan_area*		scan_area;
				inno_msg("[lgx_ioctl] INNO_SCAN_FREQUENCY_DOT");
				scan_area = kmalloc(sizeof(struct inno_freq_scan_area), GFP_KERNEL);
				retval = copy_from_user(scan_area, (void*)arg, sizeof(struct inno_freq_scan_area));
				if(retval == 0)
					;//retval = inno_scan_frequency_dot((u8)scan_area->start, (u8)scan_area->end);
				kfree(scan_area);
				break;
			}
#endif
#if 0
		case INNO_SET_FREQUENCY:	// unit:MHZ
			{
				inno_msg("[lgx_ioctl] INNO_SET_FREQUENCY");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				inno_msg("[inno-ioctl]: INNO_SET_FREQUENCY, val=%ld", val);

				if(retval == 0)
					retval = inno_set_frequency((u16)val);

				break;
			}
#endif		
		case INNO_SET_FREQUENCY_DOT:
			{
				inno_msg("[lgx_ioctl] INNO_SET_FREQUENCY_DOT");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				inno_msg("[inno-ioctl]: INNO_SET_FREQUENCY_DOT, val=%ld", val);
				if(retval == 0)
					retval = inno_set_frequency_dot((u8)val);
				if(retval)
					retval = -1;
				break;
			}
#if 0
		case INNO_SET_CP_TYPE:                    // no use   
			{
				inno_msg("[lgx_ioctl] INNO_SET_CP_TYPE");
				retval = copy_from_user(&val, (void*)arg, sizeof(unsigned long));
				if(retval == 0)
					retval = inno_set_cp_type((u8)val);
				break;
			}
#endif
		case INNO_GET_CHANNEL_CONFIG:                         
			{
				struct inno_channel_config* 	cfg;
				inno_msg("[lgx_ioctl] INNO_GET_CHANNEL_CONFIG");
				cfg = kmalloc(sizeof(struct inno_channel_config), GFP_KERNEL);
				if(!cfg ){
					inno_err("kmalloc cfg ==NULL");
					retval =-1;
					break;
				}

				retval = copy_from_user(cfg, (void*)arg, sizeof(struct inno_channel_config));

				if(retval == 0)
					retval =INNO_GetChannelConfig(cfg);            
				if(!retval){
					retval = copy_to_user((void*)arg, cfg, sizeof(struct inno_channel_config));
					inno_msg("[lgx_ioctl] INNO_Get_CHANNEL_CONFIG:cid(%d),close(%d),start(%d),count(%d),ldpc(%d),itlv(%d),rs(%d),mod(%d) "
							,cfg->ch_id,cfg->ch_close,cfg->ts_start,cfg->ts_count,cfg->ldpc,cfg->itlv,cfg->rs,cfg->modulate);			
				}
				else
					retval =-1;
				kfree(cfg);
				break;	
			}
		case INNO_SET_CHANNEL_CONFIG:                 
			{
				struct inno_channel_config* 	cfg;
				cfg = kmalloc(sizeof(struct inno_channel_config), GFP_KERNEL);
				if(!cfg ){
					inno_err("kmalloc cfg ==NULL");
					retval =-1;
					break;
				}
				inno_msg("[inno-ioctl]: INNO_SET_CHANNEL_CONFIG");
				retval = copy_from_user(cfg, (void*)arg, sizeof(struct inno_channel_config));
				inno_msg("[lgx_ioctl] INNO_SET_CHANNEL_CONFIG:cid(%d),close(%d),start(%d),count(%d),ldpc(%d),itlv(%d),rs(%d),mod(%d),subframeID(%d) "
						,cfg->ch_id,cfg->ch_close,cfg->ts_start,cfg->ts_count,cfg->ldpc,cfg->itlv,cfg->rs,cfg->modulate,cfg->subframe_ID);
				if(retval == 0)
					retval = inno_set_channel_config(cfg);
				kfree(cfg);
				break;	
			}
		case INNO_GET_SYS_STATE:
			{
				struct inno_sys_state*	sys_state;
				inno_msg("[lgx_ioctl] INNO_GET_SYS_STATE");
				sys_state = kmalloc(sizeof(struct inno_sys_state), GFP_KERNEL);
				if(!sys_state){
					inno_err("kmalloc fail sys_state = null");
					retval =1;
					break;
				}
				retval = copy_from_user(sys_state, (void*)arg, sizeof(struct inno_sys_state));

				if(retval == 0)
					retval = inno_get_system_state(sys_state);
				if(!retval)
					retval = copy_to_user((void*)arg, sys_state, sizeof(struct inno_sys_state));
				else
					retval = -1;
				kfree(sys_state);
				break;
			}
#if 0                             // no use
		case INNO_SET_PM:                                    // no use
			{
				struct inno_pm_control* pmctl;
				inno_msg("[lgx_ioctl] INNO_SET_PM");
				pmctl = kmalloc(sizeof(struct inno_pm_control), GFP_KERNEL);
				retval = copy_from_user(pmctl, (void*)arg, sizeof(struct inno_pm_control));

				if(retval == 0)
					retval = inno_set_pm(pmctl);
				kfree(pmctl);
				break;
			}
		case INNO_GET_FW_VER:                                 //no use
			{	
				struct inno_fw_ver ver = {0, 0};
				inno_msg("[lgx_ioctl] INNO_GET_FW_VER");
				inno_get_fireware_version(&ver);
				retval = copy_to_user((void*)arg, &ver, sizeof(struct inno_fw_ver));
				break;
			}
#endif
		case INNO_FW_DOWNLOAD:
			{
				int retry=0;
			//	struct INNOCHAR_FW_DATA *up = (struct INNOCHAR_FW_DATA *)arg;
				unsigned char* fwbuf =NULL;
				//inno_msg("check up->fw_size =%d",up->fw_size);                    
				//unsigned char* fwbuf = kmalloc(up->fw_size, GFP_KERNEL| GFP_DMA);
                                inno_msg("download using h file in kernel");
				if(FIRMWARE_BUF_DATA_SIZE < 40960)
					fwbuf =3*INNO_BUFFER_SIZE+g_inno_buffer;
				else{
					inno_err("fw_size >40k fail");
					retval = -1;
					break;
				}			 

				//int pass=0;
				//INNO_RET ret_tmp = INNO_NO_ERROR;

				inno_msg("[lgx_ioctl] INNO_FW_DOWNLOAD");
                                memset(fwbuf,0,FIRMWARE_BUF_DATA_SIZE);
			//	memset(fwbuf, 0, up->fw_size);
	         	//	retval = copy_from_user(fwbuf, (void*)up->fwbuf, up->fw_size);
                                memcpy(fwbuf,fw_buf,FIRMWARE_BUF_DATA_SIZE);
#if 0            				//check copy fw
				int i;
				inno_msg("check copy_from_user fw_bu");
				for(i=0;i<4;i++)
					inno_msg(" %02x",fwbuf[i]);
				inno_msg("end");
				for(i=0;i<4;i++)
					inno_msg(" %02x",fwbuf[up->fw_size-i-1]);
				inno_msg("end");	
				//mtk_spi_test();
				//break;
				//inno_msg("******** sleep 1s for download fw");
				//msleep(5000);
#endif
				if(retval == 0){
					for(retry=0;retry<1;retry++){                                
						retval = inno_download_fireware(fwbuf,FIRMWARE_BUF_DATA_SIZE);
						if(retval){
							inno_err("firmware download failed retval =%d!",(int)retval);
							retval =  -EIO;
							continue;
						}
#if 0
						//	mdelay(100);                                                       //no need delay,refer to innofidei code
						inno_msg("inno_download_fireware OK,then check FW");
						ret_tmp = INNO_CheckFWDownload(fw_buf,up->fw_size,&pass);
						if(ret_tmp){
							inno_err("INNO_CheckFWDownload fail ret =%d",ret_tmp);
							retval = -1;
							continue;
						}
						if(!pass){
							inno_err("FW Download Fail, checksum no pass =%d!",pass);
						}
						else{
							inno_msg("INNO_CheckFWDownload success");	
							break;
						}
#else
						else{
							inno_msg("inno_download_fireware ok");
							break;
						}
#endif
					}
					if(retry ==5){
						inno_err("inno_download_fireware timeout");
						retval = -1;
					}
				}
				//kfree(fwbuf);
				break;
			}
#if 0                               // no use
		case INNO_UPDATE_FW:                         // no use
			{
				inno_msg("[lgx_ioctl] INNO_UPDATE_FW");
				inno_update_fireware();
				break;
			}
#endif
		case INNO_GET_FW_BYTES:
			{
				int ret =INNO_Chip_errHandle();
				if(ret != INNO_NO_ERROR)       {
					inno_err("INNO_Chip_errHandle fail");
					retval =-1;   
				}	
				break;
			}
		case INNO_ENABLE_IRQ:
			inno_msg("[lgx_ioctl] INNO_ENABLE_IRQ");
			break;
		case INNO_DISABLE_IRQ:
			inno_msg("[lgx_ioctl] INNO_DISABLE_IRQ");
			break;
#if 0
		case INNO_SHUTDOWN_IRQ:                                    // no use
			{	//NOTE: cleanup all (i2c, spi, power down) mannually while, NOT the device itself
				inno_msg("[lgx_ioctl] INNO_SHUTDOWN_IRQ");
				if(!g_inno_dev.use_count)
				{
					inno_msg("shutdown innodev. %d", g_inno_dev.use_count);
					innodev_shutdown(&g_inno_dev);
					g_inno_dev.use_count = 0; //unrefer all reference counter
				}
				break;
			}
		case INNO_GET_BUFFERLEN:                                        //xingyu getbufferlen
			val = INNO_BUFFER_SIZE;
			put_user(val, (long*)arg);
			inno_msg("[lgx_ioctl] INNO_GET_BUFFERLEN:%ld",val);
			break;
#endif
			//////////////////////////// uam ///////////////////////////
		case INNO_UAM_TRANSFER:
			{
				struct inno_uam_parameter *uam_para_tmp;
				inno_msg("[lgx_ioctl] INNO_UAM_TRANSFER");
				uam_para_tmp = kmalloc(sizeof(struct inno_uam_parameter), GFP_KERNEL);
				if(!uam_para_tmp){
					inno_msg("uam_para_tmp kmalloc fail");
					retval = -1;
					break;
				}			 
				retval = copy_from_user(uam_para_tmp, (void*)arg, sizeof(struct inno_uam_parameter));

				if(retval == 0)
					retval = inno_uam_transfer(uam_para_tmp);
				if(!retval)
					retval = copy_to_user((void*)arg, uam_para_tmp, sizeof(struct inno_uam_parameter));     
				else
					retval = -1;
				kfree(uam_para_tmp);
				uam_para_tmp=NULL;
			}
			break;
		case INNO_UAM_INIT:
			inno_msg("[lgx_ioctl] INNO_UAM_INIT");
			retval = inno_init_uam();
			if(retval !=0){
				retval =-1;                   //tell user space fail
				inno_err("init uam fail");
			}
			break;		

		case INNO_SEND_UAM_CMD:
			{
				unsigned char* cmd_tmp0;
				struct uam_cmd_par* up0 = (struct uam_cmd_par*)arg;
				inno_msg("[lgx_ioctl] INNO_SEND_UAM_CMD");
				cmd_tmp0= kmalloc(up0->len, GFP_KERNEL);
				if(cmd_tmp0 == NULL){
					inno_msg("cmd_tmp0 kmalloc fail");
					retval = -1;
					break;
				}			 
				memset(cmd_tmp0, 0, up0->len);
				retval = copy_from_user(cmd_tmp0, (void*)up0->cmd, up0->len);

				if(retval ==0)
					retval = INNO_Send_UAM_Cmd(cmd_tmp0,up0->len);
				if(retval)
					retval = -1;
				kfree(cmd_tmp0);
				cmd_tmp0 =NULL;
			}
			break;		
		case INNO_SEND_CMD:
			{
				unsigned char *cmd_tmp;
				inno_msg("[lgx_ioctl] INNO_SEND_CMD");
				cmd_tmp = kmalloc(8,GFP_KERNEL);
				if(!cmd_tmp){
					inno_err("kmalloc fail,cmd_tmp==null");
					retval=-1;
					break;
				}
				retval = copy_from_user(cmd_tmp, (void*)arg, 8);
				if(retval ==0){
					mutex_lock(&inno_spi_mutex);                         //xingyu 2011-06-24
					retval = INNO_Send_Cmd(cmd_tmp);
					mutex_unlock(&inno_spi_mutex);
				}
				if(retval)
					retval =-1;
				kfree(cmd_tmp);
				cmd_tmp =NULL;
				break;		
			}	
#if 0                                        // no use
		case INNO_UAM_SET_CMD:                               //no use
			//inno_msg("we are in kernel ioctl^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
			inno_msg("[lgx_ioctl] INNO_UAM_SET_CMD");
			retval = copy_from_user(&uam_para.pBufIn, (void*)arg, uam_cmd_len);
			if(retval == 0){
				inno_dbg("IOCTL: INNO_UAM_TRANSFER");
			}
			uam_para.bufInLen = uam_cmd_len;
			inno_uam_transfer(&uam_para);
			break;

		case INNO_UAM_SET_CMDL:                               // no use
			inno_msg("[lgx_ioctl] INNO_UAM_SET_CMDL");
			retval = copy_from_user((void *)&uam_cmd_len, (void*)arg, sizeof(unsigned int));
			inno_dbg("INNO_UAM_SET_CMDL - uam_cmd_len: %d", uam_cmd_len);
			break;

		case INNO_UAM_READ_RES:                              // no use
			inno_msg("[lgx_ioctl] INNO_UAM_READ_RES");
			inno_dbg("INNO_UAM_READ_RES - return response len: %d", uam_para.pBufOutLen);
			return copy_to_user((void *)arg, uam_para.pBufOut, uam_para.pBufOutLen);

		case INNO_UAM_READ_STATUS:                                 // no sue
			inno_msg("[lgx_ioctl] INNO_UAM_READ_STATUS");
			inno_dbg("INNO_UAM_READ_STATUS - return status: 0x%x", uam_para.sw);
			return put_user(uam_para.sw, (unsigned long *)arg);

		case INNO_UAM_READ_STATUS_LEN:                              // no use
			inno_msg("[lgx_ioctl] INNO_UAM_READ_STATUS_LEN");
			inno_dbg("INNO_UAM_READ_STATUS_LEN - return response len: 0x%x", uam_para.pBufOutLen);
			return put_user(uam_para.pBufOutLen, (unsigned long *)arg);
#endif

		default:
			return -ENOTTY;
	}
Ejemplo n.º 13
0
/*====================================
 * character device file operations
 *===================================*/
static int lgx_open(struct inode* inode, struct file* filp)
{
	struct inno_lgx* lgx;
	unsigned int lg_num = iminor(inode);
	int i;                    
	inno_msg("+++++++++++++++++++++++++++++++++++++++++");
	inno_msg("CMMB IF208 open [%s]", lgx_ids_table[lg_num].name);
	inno_msg("+++++++++++++++++++++++++++++++++++++++++");

	if(lg_num >= LG_END){
		inno_err("minor error, should be [%d-%d]", LG0, UAM);
		return -1;
	}

	if(g_inno_dev.lgxs[lg_num]){ 	//already opened, just increase reference count
		down(&g_inno_dev.lgxs[lg_num]->sem);
		g_inno_dev.lgxs[lg_num]->use_count++;                           
		//g_inno_dev.lgxs[lg_num]->use_count = 1;
		inno_msg("reopen");
		up(&g_inno_dev.lgxs[lg_num]->sem);
		filp->private_data = g_inno_dev.lgxs[lg_num];
		return 0;
	}	

	/* OK, it's not open, Create it */
	lgx = (struct inno_lgx*)kmalloc(sizeof(struct inno_lgx), GFP_KERNEL);
	if(!lgx){
		inno_err("kmalloc lgx ==NULL");
		return -1;
	}
	else
		memset(lgx, 0, sizeof(struct inno_lgx));

	for(i=0; lgx_ids_table[i].name!=NULL; i++){
		if(lg_num == lgx_ids_table[i].id){
			lgx->ids = &lgx_ids_table[i];
			break;
		}
	}
	//allocat memory for get mfs file
	if (lgx_alloc_buffer(lgx)){
		kfree(lgx);
		lgx = NULL;
		return -1;
	}
	
//**********  global flag set ******************//
	cancle_wait = 0;                                   //xingyu 0328 add   solve poll wait
	flag_memset = 0;                                // memset the bitstream buffer
	once_closeirq=0;                                 // control close irq

	lgx->use_count = 1;
	sema_init(&lgx->sem,1);
	init_waitqueue_head(&lgx->read_wait);
#ifndef UAM_COMPLETE
	init_waitqueue_head(&lgx->uam_wait);
#else
//	if(lg_num==2){                // open uam
	if(strcmp(lgx->ids->name, "UAM") == 0){
	//if(lgx->ids->name =="UAM") {                          //xing 0922  use uamcomplete function
		inno_msg("uam_complete init");
		init_completion(&lgx->uam_complete);
	}
#endif
	g_inno_dev.lgxs[lg_num] = lgx;

	//inno_msg("open file for inno_num: %d\n", lg_num);
	if( innodev_startup(&g_inno_dev) ){
		inno_err("startup fail, free lgx");
		g_inno_dev.lgxs[lg_num] = NULL;
		lgx_free_buffer(lgx);
		kfree(lgx);
		return -1;
	}
	filp->private_data = lgx;
#ifdef _check_block_time            //printk rxbuf
	static int onetime =0;
	if (onetime ==0){                                     // when open file create better than module init for time
		onetime++;
		inno_msg("use thread to watch the block time");
		check_block_wq = create_singlethread_workqueue("siano work wq");
		INIT_WORK(&check_block_work,check_block_thread);
		queue_work(check_block_wq,&check_block_work);
	}
#endif
       inno_msg("use single thread for workqueue");
	return 0;
}
Ejemplo n.º 14
0
static int lgx_alloc_buffer(struct inno_lgx *lgx)
{
	//int i,j;
	//int page_num;
	//struct page *page = NULL;
	int i;
	struct inno_buffer *inno_buf = &lgx->inno_buffer;
	//int ret = 0;

	memset(inno_buf, 0, sizeof(struct inno_buffer));
	sema_init(&inno_buf->sem,1);
	down(&inno_buf->sem);

	// alloc buffer
#if 0                        //xingyu buffer issue
	page_num = PAGE_ALIGN(INNO_BUFFER_SIZE) / PAGE_SIZE;
	inno_buf->pages = (struct page **)kzalloc(page_num * sizeof(struct page *), GFP_KERNEL);         
	if (!inno_buf->pages) {
		inno_err("lgx_alloc_buffer:No enough memory");
		ret = -ENOMEM;
		goto alloc_node_error;
	}

	for (i = 0; i < page_num; i++) {
		page = alloc_page(GFP_KERNEL);

		if (!page) {
			inno_err("lgx_alloc_buffer:No enough page");
			ret = -ENOMEM;
			goto alloc_pages_error;
		}
		//SetPageReserved(page);
		inno_buf->pages[i] = page;
	}

	inno_buf->page_num = page_num;

	inno_buf->bufsize = page_num * PAGE_SIZE;
	inno_buf->vaddr = vmap(inno_buf->pages, page_num, VM_MAP, PAGE_KERNEL);

	/* check if the memory map is OK. */
	if (!inno_buf->vaddr) {
		inno_err("lgx_alloc_buffer:vmap() failure");
		ret = -EFAULT;
		goto vmap_error;
	}

	memset(inno_buf->vaddr, 0, inno_buf->bufsize);

	inno_buf->start = inno_buf->vaddr;
#else	
#ifndef _buffer_global                                                      // buffer alloc modify xingyu 0714
	inno_buf->vaddr = kmalloc(INNO_BUFFER_SIZE, GFP_KERNEL| GFP_DMA);         
	if(inno_buf->vaddr == NULL || (int)inno_buf->vaddr %4 !=0){
		inno_err("inno_buf->vaddr kmalloc fail");
		up(&inno_buf->sem);
		return -1;
	}			 
#else
	for(i=0; lgx_ids_table[i].name!=NULL; i++){
		if(lgx->ids  == &lgx_ids_table[i]){
			inno_buf->vaddr =i*INNO_BUFFER_SIZE+g_inno_buffer;
			inno_msg("use global mem");
			break;
		}
	}
#endif
	inno_buf->start = inno_buf->vaddr;
	inno_buf->bufsize = INNO_BUFFER_SIZE;
	
#endif
	up(&inno_buf->sem);

	return 0;

#if 0                          //xingyu buffer issue
	//vmap_error:
	//alloc_pages_error:
	for (j = 0; j < i; j++) {
		page = inno_buf->pages[j];
		//ClearPageReserved(page);
		__free_page(page);
	}
	kfree(inno_buf->pages);
	//alloc_node_error:
	return ret;
#endif
}