Example #1
0
// allocate and init i2c dev descriptor
// update i2c client params
// 
static int smsi2c_probe(void)
{
	int ret;

	struct smsi2c_device *smsdev;
	struct smsdevice_params_t params;
	struct SmsMsgHdr_S smsmsg;
	struct SmsMsgData2Args_S setIntMsg = {{MSG_SMS_SPI_INT_LINE_SET_REQ, 
				0, 
				11,
				sizeof(struct SmsMsgData2Args_S),
				0},
				{0xff,
				20}};

	    struct i2c_board_info smsi2c_info = {
		I2C_BOARD_INFO("smsi2c", sms_i2c_addr),
	    };
	
	smsdev = kzalloc(sizeof(struct smsi2c_device), GFP_KERNEL);
	if (!smsdev)
	{
		sms_err("Cannot allocate memory for I2C device driver.\n");
		return -ENOMEM;
	}
		
	g_smsi2c_device = smsdev;
	sms_debug ("Memory allocated");
	smsdev->adap = i2c_get_adapter(host_i2c_ctrl);
	if (!smsdev->adap) {
		sms_err("Cannot get adapter #%d.\n", host_i2c_ctrl);
		ret = -ENODEV;
		goto failed_allocate_adapter;
	}
	sms_debug ("Got the adapter");

	smsi2c_info.platform_data = smsdev;

	smsdev->client = i2c_new_device(smsdev->adap, &smsi2c_info);

	if (!smsdev->client) {
		sms_err("Cannot register I2C device with addr 0x%x.\n", sms_i2c_addr);
		 ret = -ENODEV;
		 goto failed_allocate_device;
	}
	sms_debug ("Got the device");


	ret = gpio_request(host_i2c_intr_pin, "sms_gpio");
	if (ret) {
		sms_err("failed to get sms_gpio\n");
		 goto failed_allocate_gpio;
	}	
	gpio_direction_input(host_i2c_intr_pin);
	gpio_export(host_i2c_intr_pin, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
	irq_set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#else
	set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#endif
	/*register irq*/
	ret = request_irq( gpio_to_irq(host_i2c_intr_pin), (irq_handler_t)smsi2c_interrupt,
		 IRQF_TRIGGER_RISING, "SMSI2C", smsdev);
	if (ret < 0) {
		sms_err("failed to allocate interrupt for SMS\n");
		ret = -ENODEV;
		goto failed_allocate_interrupt;
	}	

	if (device_int_line != 0xFFFFFFFF)
	{ /* Device is not using the default interrupt pin*/

		sms_debug("Device is not using the default int pin, need to set the interrupt pin to %d", device_int_line);
		setIntMsg.msgData[1] = device_int_line;
		ret = smsi2c_sendrequest(smsdev, &setIntMsg, sizeof(setIntMsg));
		msleep(50);
	}

	init_completion(&smsdev->version_ex_done);
	smsdev->wait_for_version_resp = 1;
	SMS_INIT_MSG(&smsmsg, MSG_SMS_GET_VERSION_EX_REQ,
		     sizeof(struct SmsMsgHdr_S));
	smsi2c_sendrequest(smsdev, &smsmsg, sizeof(smsmsg));
	/*Wait for response*/
	ret = wait_for_completion_timeout(&smsdev->version_ex_done, msecs_to_jiffies(500));
	if (ret > 0)
	{ /*Got version. device is in*/
		sms_debug("Found and identified the I2C device");
	}
	else
	{ /* No response recieved*/
		sms_err("No response to get version command");
		ret = -ETIME;
		goto failed_registering_coredev;
	}


	memset(&params, 0, sizeof(struct smsdevice_params_t));

	params.device = (struct device *)&smsdev->client->adapter->dev;
#ifdef SMS_RK_TS
	params.buffer_size = MAX_I2C_BUF_SIZE;
	params.num_buffers = MAX_I2C_BUF_NUMBER;
	params.require_node_buffer = 1;
#else
	params.buffer_size = 0x400;
	params.num_buffers = 20;
#endif
	params.context = smsdev;

	snprintf(params.devpath, sizeof(params.devpath),
		 "i2c\\%s", "smsi2c");

	params.sendrequest_handler  = smsi2c_sendrequest;
	params.loadfirmware_handler = smsi2c_loadfirmware_handler;
	switch(smsdev->chip_model)
	{
		case 0: params.device_type = 0; break;
		case 0x1002:
		case 0x1102:
		case 0x1004: params.device_type = SMS_NOVA_B0; break;
		case 0x1182: params.device_type = SMS_VENICE; break;
		case 0x1530: params.device_type = SMS_DENVER_1530; break;
		case 0x2130: params.device_type = SMS_PELE; break;
		case 0x2160: params.device_type = SMS_DENVER_2160; break;
		case 0x2180: params.device_type = SMS_MING; break;
		case 0x2230: params.device_type = SMS_RIO; break;
		case 0x3130: params.device_type = SMS_ZICO; break;
		case 0x3180: params.device_type = SMS_QING; break;
		case 0x3230: params.device_type = SMS_SANTOS; break;
		case 0x4470: 
			if (smsdev->chip_metal >= 2)
				params.device_type = SMS_SIENA_A2; 
			else
				params.device_type = SMS_SIENA; 
			break;

		default: params.device_type = 0; break;
	}

	/* Use SMS_DEVICE_FAMILY2 for firmware download over SMS MSGs
	   SMS_DEVICE_FAMILY1 for backdoor I2C firmware download */
	params.flags |= SMS_DEVICE_FAMILY2;
	
	/* Device protocol completion events */

	ret = smscore_register_device(&params, &smsdev->coredev);
	if (ret < 0)
        {
	        printk(KERN_INFO "smscore_register_device error\n");
		goto failed_registering_coredev;
        }

	ret = smscore_start_device(smsdev->coredev);
	if (ret < 0)
        {
		printk(KERN_INFO "smscore_start_device error\n");
		goto failed_device_start;
        }

	return 0;
failed_device_start:
	smscore_unregister_device(smsdev->coredev);
failed_registering_coredev:
	free_irq(gpio_to_irq(host_i2c_intr_pin), smsdev);
failed_allocate_interrupt:
	gpio_free(host_i2c_intr_pin);
failed_allocate_gpio:
	i2c_unregister_device(smsdev->client);
failed_allocate_device:
	i2c_put_adapter(smsdev->adap);
failed_allocate_adapter:
	g_smsi2c_device = NULL;
	kfree(smsdev);

	return ret;
}
Example #2
0
static int smssdio_probe(struct sdio_func *func,
                         const struct sdio_device_id *id)
{
    int ret;

    int board_id;
    struct smssdio_device *smsdev;
    struct smsdevice_params_t params;

    board_id = id->driver_data;

    smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
    if (!smsdev)
        return -ENOMEM;

    smsdev->func = func;

    memset(&params, 0, sizeof(struct smsdevice_params_t));

    params.device = &func->dev;
    params.buffer_size = 0x5000;	/* ?? */
    params.num_buffers = 22;	/* ?? */
    params.context = smsdev;

    snprintf(params.devpath, sizeof(params.devpath),
             "sdio\\%s", sdio_func_id(func));

    params.sendrequest_handler = smssdio_sendrequest;

    params.device_type = sms_get_board(board_id)->type;

    if (params.device_type != SMS_STELLAR)
        params.flags |= SMS_DEVICE_FAMILY2;
    else {
        /*
         * FIXME: Stellar needs special handling...
         */
        ret = -ENODEV;
        goto free;
    }

    ret = smscore_register_device(&params, &smsdev->coredev);
    if (ret < 0)
        goto free;

    smscore_set_board_id(smsdev->coredev, board_id);

    sdio_claim_host(func);

    ret = sdio_enable_func(func);
    if (ret)
        goto release;

    ret = sdio_set_block_size(func, 128);
    if (ret)
        goto disable;

    ret = sdio_claim_irq(func, smssdio_interrupt);
    if (ret)
        goto disable;

    sdio_set_drvdata(func, smsdev);

    sdio_release_host(func);

    ret = smscore_start_device(smsdev->coredev);
    if (ret < 0)
        goto reclaim;

    return 0;

reclaim:
    sdio_claim_host(func);
    sdio_release_irq(func);
disable:
    sdio_disable_func(func);
release:
    sdio_release_host(func);
    smscore_unregister_device(smsdev->coredev);
free:
    kfree(smsdev);

    return ret;
}
Example #3
0
int smsspi_register(void)
{
	struct smsdevice_params_t params;
	int ret;
	struct _spi_device_st *spi_device;
	struct _spi_dev_cb_st common_cb;

	PDEBUG("entering \n");

	spi_device =
	    kmalloc(sizeof(struct _spi_device_st), GFP_KERNEL);
	spi_dev = spi_device;

	INIT_LIST_HEAD(&spi_device->txqueue);

	ret = platform_device_register(&smsspi_device);
	if (ret < 0) {
		PERROR("platform_device_register failed\n");
		return ret;
	}

#if defined(MOT_FEAT_OMAP_DMA_USE)
	spi_device->txbuf =
	    dma_alloc_coherent(NULL, TX_BUFFER_SIZE,
			       &spi_device->txbuf_phy_addr,
			       GFP_KERNEL | GFP_DMA);
	if (!spi_device->txbuf) {
		printk(KERN_INFO "%s dma_alloc_coherent(...) failed\n",
		       __func__);
		ret = -ENOMEM;
		goto txbuf_error;
	}
#endif

	spi_device->phy_dev =
	    smsspiphy_init(NULL, smsspi_int_handler, spi_device);
	if (spi_device->phy_dev == 0) {
		printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
		goto phy_error;
	}

	common_cb.allocate_rx_buf = allocate_rx_buf;
	common_cb.free_rx_buf = free_rx_buf;
	common_cb.msg_found_cb = msg_found;
	common_cb.transfer_data_cb = smsspibus_xfer;

	ret =
	    smsspicommon_init(&spi_device->dev, spi_device, spi_device->phy_dev,
			      &common_cb);
	if (ret) {
		printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
		goto common_error;
	}

	/* register in smscore */
	memset(&params, 0, sizeof(params));
	params.context = spi_device;
	params.device = &smsspi_device.dev;
	params.buffer_size = RX_BUFFER_SIZE;
	params.num_buffers = NUM_RX_BUFFERS;
	params.flags = SMS_DEVICE_NOT_READY;
	params.sendrequest_handler = smsspi_write;
	strcpy(params.devpath, "spi");
	params.device_type = default_type;

	if (0) {
		/* device family */
		/* params.setmode_handler = smsspi_setmode; */
	} else {
		params.flags =
		    SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY;
		params.preload_handler = smsspi_preload;
		params.postload_handler = smsspi_postload;
	}

	ret = smscore_register_device(&params, &spi_device->coredev);
	if (ret < 0) {
		printk(KERN_INFO "%s smscore_register_device(...) failed\n",
		       __func__);
		goto reg_device_error;
	}

	ret = smscore_start_device(spi_device->coredev);
	if (ret < 0) {
		printk(KERN_INFO "%s smscore_start_device(...) failed\n",
		       __func__);
		goto start_device_error;
	}

	PDEBUG("exiting\n");
	return 0;

start_device_error:
	smscore_unregister_device(spi_device->coredev);

reg_device_error:

common_error:
	smsspiphy_deinit(spi_device->phy_dev);

phy_error:
	dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,
			  spi_device->txbuf_phy_addr);

txbuf_error:
	platform_device_unregister(&smsspi_device);

	PDEBUG("exiting error %d\n", ret);

	return ret;
}
Example #4
0
int smsspi_register(void)
{
	struct smsdevice_params_t params;
	int ret = 0;
	struct _spi_device_st *spi_device;
	struct _spi_dev_cb_st common_cb;

	PDEBUG("entering \n");
	printk(KERN_WARNING"enter smsspi_register\n");

	spi_device =
	    kmalloc(sizeof(struct _spi_device_st), GFP_KERNEL);
        if(!spi_device)
        {
          printk("spi_device is null smsspi_register\n") ;
	  return 0;
        }
	spi_dev = spi_device;

	INIT_LIST_HEAD(&spi_device->txqueue);


	spi_device->txbuf =
	    dma_alloc_coherent(NULL, MAX(TX_BUFFER_SIZE, PAGE_SIZE),
			       &spi_device->txbuf_phy_addr,
			       GFP_KERNEL | GFP_DMA);
	if (!spi_device->txbuf) {
		printk(KERN_INFO "%s dma_alloc_coherent(...) failed\n",
		       __func__);
		ret = -ENOMEM;
		goto txbuf_error;
	}

	printk(KERN_INFO "smsmdtv: spi_device->txbuf = 0x%x  spi_device->txbuf_phy_addr= 0x%x\n",
                        (unsigned int)spi_device->txbuf, spi_device->txbuf_phy_addr);

	

	spi_device->phy_dev =
	    smsspiphy_init(NULL, smsspi_int_handler, spi_device);
	
	if (spi_device->phy_dev == 0) {
		printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
		goto phy_error;
	}

	common_cb.allocate_rx_buf = allocate_rx_buf;
	common_cb.free_rx_buf = free_rx_buf;
	common_cb.msg_found_cb = msg_found;
	common_cb.transfer_data_cb = smsspibus_xfer;

	ret =
	    smsspicommon_init(&spi_device->dev, spi_device, spi_device->phy_dev,
			      &common_cb);
	if (ret) {
		printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
		goto common_error;
	}

	/* register in smscore */
	memset(&params, 0, sizeof(params));
	params.context = spi_device;
	params.device = &smsspi_device.dev;
	params.buffer_size = RX_BUFFER_SIZE;
	params.num_buffers = NUM_RX_BUFFERS;
	params.flags = SMS_DEVICE_NOT_READY;
	params.sendrequest_handler = smsspi_write;
	strcpy(params.devpath, "spi");
	params.device_type = default_type;

	if (0) {
		/* device family */
		/* params.setmode_handler = smsspi_setmode; */
	} else {
		params.flags =
		    SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY |
		    SMS_ROM_NO_RESPONSE;
		params.preload_handler = smsspi_preload;
		params.postload_handler = smsspi_postload;
	}

	ret = smscore_register_device(&params, &spi_device->coredev);
	if (ret < 0) {
		printk(KERN_INFO "%s smscore_register_device(...) failed\n",
		       __func__);
		goto reg_device_error;
	}

	ret = smscore_start_device(spi_device->coredev);
	if (ret < 0) {
		printk(KERN_INFO "%s smscore_start_device(...) failed\n",
		       __func__);
		goto start_device_error;
	}
        spi_resume_fail = 0 ;
        spi_suspended = 0 ;

#if 0 //ZTE:added by wangtao for cmmbtest 20110712
{
	smsspibus_ssp_resume(spi_dev->phy_dev) ;
       // smsspi_preload(spi_dev);
	printk(KERN_INFO "%s [test] smsspi_preload test end\n",__func__);
	}	
#endif
	
	printk(KERN_WARNING"helike exit smsspi_register\n");

	PDEBUG("exiting\n");
	return 0;

start_device_error:
	smscore_unregister_device(spi_device->coredev);

reg_device_error:

common_error:
	smsspiphy_deinit(spi_device->phy_dev);

phy_error:
	dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,
			  spi_device->txbuf_phy_addr);

txbuf_error:

	PDEBUG("exiting error %d\n", ret);

	return ret;
}
Example #5
0
// allocate and init i2c dev descriptor
// update i2c client params
// 
static int smsi2c_probe(void)
{
	int ret;

	struct smsi2c_device *smsdev;
	struct smsdevice_params_t params;

	    struct i2c_board_info smsi2c_info = {
		I2C_BOARD_INFO("smsi2c", sms_i2c_addr),
	    };
	
	smsdev = kzalloc(sizeof(struct smsi2c_device), GFP_KERNEL);
	if (!smsdev)
	{
		sms_err("Cannot allocate memory for I2C device driver.\n");
		return -ENOMEM;
	}
		
	g_smsi2c_device = smsdev;
	sms_debug ("Memory allocated");
	smsdev->adap = i2c_get_adapter(host_i2c_ctrl);
	if (!smsdev->adap) {
		sms_err("Cannot get adapter #%d.\n", host_i2c_ctrl);
		ret = -ENODEV;
		goto failed_allocate_adapter;
	}
	sms_debug ("Got the adapter");

	smsi2c_info.platform_data = smsdev;

	smsdev->client = i2c_new_device(smsdev->adap, &smsi2c_info);

	if (!smsdev->client) {
		sms_err("Cannot register I2C device with addr 0x%x.\n", sms_i2c_addr);
		 ret = -ENODEV;
		 goto failed_allocate_device;
	}
	sms_debug ("Got the device");


	ret = gpio_request(host_i2c_intr_pin, "sms_gpio");
	if (ret) {
		sms_err("failed to get sms_gpio\n");
		 goto failed_allocate_gpio;
	}	
	gpio_direction_input(host_i2c_intr_pin);
	gpio_export(host_i2c_intr_pin, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
	irq_set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#else
	set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#endif
	/*register irq*/
	ret = request_irq( gpio_to_irq(host_i2c_intr_pin), (irq_handler_t)smsi2c_interrupt,
		 IRQF_TRIGGER_RISING, "SMSI2C", smsdev);
	if (ret < 0) {
		sms_err("failed to allocate interrupt for SMS\n");
		 goto failed_allocate_interrupt;
	}	

	memset(&params, 0, sizeof(struct smsdevice_params_t));

	params.device = (struct device *)smsdev->client;
	params.buffer_size = 0x400;	
	params.num_buffers = 20;	
	params.context = smsdev;

	snprintf(params.devpath, sizeof(params.devpath),
		 "i2c\\%s", "smsi2c");

	params.sendrequest_handler  = smsi2c_sendrequest;
	params.loadfirmware_handler = smsi2c_loadfirmware_handler;
	params.device_type = i2c_default_type;

	/* Use SMS_DEVICE_FAMILY2 for firmware download over SMS MSGs
	   SMS_DEVICE_FAMILY1 for backdoor I2C firmware download */
	/* params.flags |= SMS_DEVICE_FAMILY2; */
	
	/* Device protocol completion events */
	init_completion(&smsdev->version_ex_done);

	ret = smscore_register_device(&params, &smsdev->coredev);
	if (ret < 0)
        {
	        printk(KERN_INFO "smscore_register_device error\n");
		goto failed_registering_coredev;
        }

	ret = smscore_start_device(smsdev->coredev);
	if (ret < 0)
        {
		printk(KERN_INFO "smscore_start_device error\n");
		goto failed_device_start;
        }

	return 0;
failed_device_start:
	smscore_unregister_device(smsdev->coredev);
failed_registering_coredev:
	free_irq(gpio_to_irq(host_i2c_intr_pin), smsdev);
failed_allocate_interrupt:
	gpio_free(host_i2c_intr_pin);
failed_allocate_gpio:
	i2c_unregister_device(smsdev->client);
failed_allocate_device:
	i2c_put_adapter(smsdev->adap);
failed_allocate_adapter:
	g_smsi2c_device = NULL;
	kfree(smsdev);

	return ret;
}