// 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(¶ms, 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(¶ms, &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; }
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(¶ms, 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(¶ms, &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; }
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(¶ms, 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(¶ms, &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; }
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(¶ms, 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(¶ms, &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; }
// 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(¶ms, 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(¶ms, &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; }