blob: 3e410cdf5973a2986b6f4278e86054bf6d19f3b4 [file] [log] [blame]
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/string.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <mach/mt_gpio.h>
#include <cust_gpio_usage.h>
#include <cust_eint.h>
#include <mach/eint.h>
#include <cust_cwmcu.h>
#include <mach/mt_pm_ldo.h>
#include <linux/spi/spi.h>
#include <mtk_spi.h>
#include <mach/mt_sleep.h>
#include "CwMcuSensor.h"
//extern struct CWMCU_data *sensor;
static DEFINE_MUTEX(cwmcu_bus_lock);
#ifdef CWMCU_I2C_INTERFACE
static u8 *CWI2CDMABuf_va = NULL;
static dma_addr_t CWI2CDMABuf_pa = 0;
static struct i2c_board_info __initdata i2c_cw_boardinfo =
{ I2C_BOARD_INFO("CwMcuSensor", (0x3a)) };
static s32 i2c_dma_read(struct i2c_client *client, u8 addr, u8 * rxbuf,
s32 len)
{
int ret;
s32 retry = 0;
u8 buffer[2];
struct i2c_msg msg[2] = {
{
.addr = (client->addr & I2C_MASK_FLAG),
.flags = 0, //(client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
.buf = buffer,
.len = 1,
.timing = 400},
{
.addr = (client->addr & I2C_MASK_FLAG),
.ext_flag =
(client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
.flags = I2C_M_RD,
.buf = (u8 *) CWI2CDMABuf_pa,
.len = len,
.timing = 400},
};
buffer[0] = addr;
if (rxbuf == NULL)
return -1;
//GTP_DEBUG("dma i2c read: 0x%04X, %d bytes(s)", addr, len);
for (retry = 0; retry < 10; ++retry) {
ret = i2c_transfer(client->adapter, &msg[0], 2);
if (ret < 0) {
CW_ERROR("I2C DMA read error retry=%d", retry);
continue;
}
memcpy(rxbuf, CWI2CDMABuf_va, len);
return 0;
}
CW_ERROR("Dma I2C Read Error: 0x%04X, %d byte(s), err-code: %d",
addr, len, ret);
return ret;
}
static s32 i2c_dma_write(struct i2c_client *client, u8 addr, u8 * txbuf,
s32 len)
{
int ret;
s32 retry = 0;
u8 *wr_buf = CWI2CDMABuf_va;
//CW_DEBUG("fwq3,.....%x",txbuf[0]);
struct i2c_msg msg = {
.addr = (client->addr & I2C_MASK_FLAG),
.ext_flag =
(client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
.flags = 0,
.buf = (u8 *) CWI2CDMABuf_pa,
.len = 1 + len,
.timing = 400
};
wr_buf[0] = addr;
if (txbuf == NULL)
return -1;
//GTP_DEBUG("dma i2c write: 0x%04X, %d bytes(s)", addr, len);
memcpy(wr_buf + 1, txbuf, len + 1);
//for(retry=0;retry<len+1;retry++)
//{
// CW_DEBUG("fwq4,.....wr_buf[%d]=%x",retry,wr_buf[retry]);
//}
for (retry = 0; retry < 5; ++retry) {
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret < 0) {
CW_ERROR("I2C DMA write error retry=%d", retry);
continue;
}
return 0;
}
CW_ERROR("Dma I2C Write Error: 0x%04X, %d byte(s), err-code: %d",
addr, len, ret);
return ret;
}
static s32 i2c_dma_read_serial(struct i2c_client *client, u8 * rxbuf,
s32 len)
{
int ret;
s32 retry = 0;
struct i2c_msg msg[2] = {
{
.addr = (client->addr & I2C_MASK_FLAG),
.ext_flag =
(client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
.flags = I2C_M_RD,
.buf = (u8 *) CWI2CDMABuf_pa,
.len = len,
.timing = 400},
};
if (rxbuf == NULL)
return -1;
//GTP_DEBUG("dma i2c read: 0x%04X, %d bytes(s)", addr, len);
for (retry = 0; retry < 5; ++retry) {
ret = i2c_transfer(client->adapter, &msg[0], 1);
if (ret < 0) {
CW_ERROR("I2C DMA read error retry=%d", retry);
continue;
}
memcpy(rxbuf, CWI2CDMABuf_va, len);
return 0;
}
CW_ERROR("Dma I2C Read Error: %d byte(s), err-code: %d", len, ret);
return ret;
}
static s32 i2c_dma_write_serial(struct i2c_client *client, u8 * txbuf,
s32 len)
{
int ret;
s32 retry = 0;
u8 *wr_buf = CWI2CDMABuf_va;
struct i2c_msg msg = {
.addr = (client->addr & I2C_MASK_FLAG),
.ext_flag =
(client->ext_flag | I2C_ENEXT_FLAG | I2C_DMA_FLAG),
.flags = 0,
.buf = (u8 *) CWI2CDMABuf_pa,
.len = len,
.timing = 400
};
if (txbuf == NULL)
return -1;
//GTP_DEBUG("dma i2c write: 0x%04X, %d bytes(s)", addr, len);
memcpy(wr_buf, txbuf, len);
for (retry = 0; retry < 10; ++retry) {
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret < 0) {
CW_ERROR("I2C DMA write error retry=%d", retry);
continue;
}
return 0;
}
CW_ERROR("Dma I2C Write Error: %d byte(s), err-code: %d", len,
ret);
return ret;
}
static s32 i2c_read_bytes_dma(struct i2c_client *client, u8 addr,
u8 * rxbuf, s32 len)
{
s32 left = len;
s32 read_len = 0;
u8 *rd_buf = rxbuf;
s32 ret = 0;
//GTP_DEBUG("Read bytes dma: 0x%04X, %d byte(s)", addr, len);
while (left > 0) {
if (left > GTP_DMA_MAX_TRANSACTION_LENGTH) {
read_len = GTP_DMA_MAX_TRANSACTION_LENGTH;
} else {
read_len = left;
}
ret = i2c_dma_read(client, addr, rd_buf, read_len);
if (ret < 0) {
CW_ERROR("dma read failed");
return -1;
}
left -= read_len;
addr += read_len;
rd_buf += read_len;
}
return 0;
}
static s32 i2c_write_bytes_dma(struct i2c_client *client, u8 addr,
u8 * txbuf, s32 len)
{
s32 ret = 0;
s32 write_len = 0;
s32 left = len;
u8 *wr_buf = txbuf;
//CW_DEBUG("fwq2...%x",txbuf[0]);
//GTP_DEBUG("Write bytes dma: 0x%04X, %d byte(s)", addr, len);
while (left > 0) {
if (left > GTP_DMA_MAX_I2C_TRANSFER_SIZE) {
write_len = GTP_DMA_MAX_I2C_TRANSFER_SIZE;
} else {
write_len = left;
}
ret = i2c_dma_write(client, addr, wr_buf, write_len);
if (ret < 0) {
CW_ERROR("dma i2c write failed!");
return -1;
}
left -= write_len;
addr += write_len;
wr_buf += write_len;
}
return 0;
}
static s32 i2c_write_bytes_dma_serial(struct i2c_client *client,
u8 * txbuf, s32 len)
{
s32 ret = 0;
s32 write_len = 0;
s32 left = len;
u8 *wr_buf = txbuf;
//GTP_DEBUG("Write bytes dma: 0x%04X, %d byte(s)", addr, len);
while (left > 0) {
if (left > GTP_DMA_MAX_I2C_TRANSFER_SIZE) {
write_len = GTP_DMA_MAX_I2C_TRANSFER_SIZE;
} else {
write_len = left;
}
ret = i2c_dma_write_serial(client, wr_buf, write_len);
if (ret < 0) {
CW_ERROR("dma i2c write failed!");
return -1;
}
left -= write_len;
wr_buf += write_len;
}
return 0;
}
static s32 i2c_read_bytes_dma_serial(struct i2c_client *client, u8 * rxbuf,
s32 len)
{
s32 left = len;
s32 read_len = 0;
u8 *rd_buf = rxbuf;
s32 ret = 0;
//GTP_DEBUG("Read bytes dma: 0x%04X, %d byte(s)", addr, len);
while (left > 0) {
if (left > GTP_DMA_MAX_TRANSACTION_LENGTH) {
read_len = GTP_DMA_MAX_TRANSACTION_LENGTH;
} else {
read_len = left;
}
ret = i2c_dma_read_serial(client, rd_buf, read_len);
if (ret < 0) {
CW_ERROR("dma read serial failed");
return -1;
}
left -= read_len;
rd_buf += read_len;
}
return 0;
}
void i2c_init(void *client)
{
CWI2CDMABuf_va =
(u8 *) dma_alloc_coherent(NULL, GTP_DMA_MAX_TRANSACTION_LENGTH,
&CWI2CDMABuf_pa, GFP_KERNEL);
if (!CWI2CDMABuf_va) {
CW_INFO("[sensorHUB] dma_alloc_coherent error");
}
}
static int CWMCU_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
CWMCU_probe(client);
return 0;
}
static void CWMCU_i2c_shutdown(struct i2c_client *client)
{
struct CWMCU_T *sensor = i2c_get_clientdata(client);
CWMCU_shutdown(sensor);
}
static int CWMCU_i2c_remove(struct i2c_client *client)
{
struct CWMCU_T *sensor = i2c_get_clientdata(client);
kfree(sensor);
return 0;
}
static int CWMCU_i2c_suspend(struct device *dev)
{
return CWMCU_system_suspend();
}
static int CWMCU_i2c_resume(struct device *dev)
{
CWMCU_system_resume();
return 0;
}
static const struct dev_pm_ops CWMCU_pm_ops = {
.suspend = CWMCU_i2c_suspend,
.resume = CWMCU_i2c_resume
};
static const struct i2c_device_id CWMCU_id[] = {
{CWMCU_I2C_NAME, 0},
{}
};
MODULE_DEVICE_TABLE(i2c, CWMCU_id);
static struct i2c_driver CWMCU_i2c_driver = {
.driver = {
.name = CWMCU_I2C_NAME,
.owner = THIS_MODULE,
.pm = &CWMCU_pm_ops,
},
.probe = CWMCU_i2c_probe,
.remove = CWMCU_i2c_remove,
.shutdown = CWMCU_i2c_shutdown,
.id_table = CWMCU_id,
};
#elif defined(CWMCU_SPI_INTERFACE)
extern struct CWMCU_data *sensor;
unsigned char *cwmcu_spi_src_buffer_all = NULL;
static struct mt_chip_conf spi_conf;
void spi_io_enable(int enable)
{
if (enable) {
mt_set_gpio_mode(GPIO_SPI_CS_PIN,
GPIO_SPI_CS_PIN_M_SPI_CS);
mt_set_gpio_mode(GPIO_SPI_SCK_PIN,
GPIO_SPI_SCK_PIN_M_SPI_SCK);
mt_set_gpio_mode(GPIO_SPI_MISO_PIN,
GPIO_SPI_MISO_PIN_M_SPI_MISO);
mt_set_gpio_mode(GPIO_SPI_MOSI_PIN,
GPIO_SPI_MOSI_PIN_M_SPI_MOSI);
} else {
//set dir pull to save power
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);
}
}
static int spi_xfer(unsigned char *txbuf, unsigned char *rxbuf, int len)
{
int ret;
struct spi_transfer transfer_1[2];
int const pkt_count =
len / CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES;
int const remainder =
len % CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES;
struct spi_message msg;
spi_message_init(&msg);
spi_io_enable(1);
//CW_INFO(" len=%d, txbuf=0x%x, rxbuf=0x%x", len, txbuf, rxbuf);
if (len > CWMCU_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 =
CWMCU_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 +
(CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES *
pkt_count);
transfer_1[1].rx_buf =
(rxbuf ==
NULL) ? NULL : rxbuf +
(CWMCU_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 (spi_sync(sensor->spi, &msg))
ret = -1;
else
ret = 0;
spi_io_enable(0);
return ret;
}
static int spi_write_bytes_serial(unsigned char *buffer, int len)
{
int ret = 0;
unsigned char *tx_buf = NULL, *rx_buf = NULL;
if (len > CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES) {
tx_buf = buffer;
rx_buf = NULL;
} else {
if (cwmcu_spi_src_buffer_all == NULL)
return -1;
if (buffer != cwmcu_spi_src_buffer_all)
memcpy(cwmcu_spi_src_buffer_all, buffer, len);
tx_buf = cwmcu_spi_src_buffer_all;
rx_buf = NULL;
}
ret = spi_xfer(tx_buf, rx_buf, len);
return ret;
}
static int spi_read_bytes_serial(unsigned char *buffer, int len)
{
int ret = 0;
unsigned char *tx_buf = NULL, *rx_buf = NULL;
if (len > CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES) {
tx_buf = NULL;
rx_buf = buffer;
ret = spi_xfer(tx_buf, rx_buf, len);
} else {
if (cwmcu_spi_src_buffer_all == NULL)
return -1;
tx_buf = NULL;
rx_buf = cwmcu_spi_src_buffer_all;
ret = spi_xfer(tx_buf, rx_buf, len);
if (ret == 0)
memcpy(buffer, cwmcu_spi_src_buffer_all, len);
}
return ret;
}
static int spi_read_bytes_serial_chksum(unsigned char *buffer, int len)
{
int i;
static u8 checksum;
checksum = 0;
spi_read_bytes_serial(cwmcu_spi_src_buffer_all, len + 1);
for (i == 0; i < len; i++) {
checksum += cwmcu_spi_src_buffer_all[i];
//CW_DEBUG("[%d]:0x%x, checksum=0x%x", i, cwmcu_spi_src_buffer_all[i], checksum);
}
//CW_DEBUG("=>cal_chksum:0x%x, data_chksum:0x%x", checksum, cwmcu_spi_src_buffer_all[len]);
if (checksum != cwmcu_spi_src_buffer_all[len]) {
CW_ERROR("SPI read checksum failed:0x%x(0x%x)", checksum,
cwmcu_spi_src_buffer_all[len]);
return -1;
}
memcpy(buffer, cwmcu_spi_src_buffer_all, len);
return 0;
}
static int spi_read_bytes(u8 reg_addr, u8 * buffer, u8 len)
{
int ret = 0;
//CW_DEBUG("[SPI]R_Reg:0x%x, len=%d", reg_addr, len);
if (cwmcu_spi_src_buffer_all == NULL)
return -1;
cwmcu_spi_src_buffer_all[0] = reg_addr;
ret = spi_xfer(cwmcu_spi_src_buffer_all, NULL, 1);
if (ret < 0) {
CW_ERROR("spi_read_bytes: write failed");
return ret;
}
#if CWMCU_SPI_CHECKSUM_SUPPORT
ret = spi_read_bytes_serial_chksum(buffer, len);
#else
ret = spi_read_bytes_serial(buffer, len);
#endif
if (ret < 0) {
CW_ERROR("spi_read_bytes: read failed");
return ret;
}
return ret;
}
static int spi_write_bytes(u8 reg_addr, u8 * buffer, u8 len)
{
int ret = 0;
if (cwmcu_spi_src_buffer_all == NULL)
return -1;
//CW_DEBUG("[SPI]W_Reg:0x%x, len=%d", reg_addr, len);
cwmcu_spi_src_buffer_all[0] = reg_addr;
ret = spi_xfer(cwmcu_spi_src_buffer_all, NULL, 1);
if (ret < 0) {
CW_ERROR("spi_write_bytes 1st: write failed");
return ret;
}
memcpy(&cwmcu_spi_src_buffer_all[0], buffer, len);
ret = spi_write_bytes_serial(cwmcu_spi_src_buffer_all, len);
if (ret < 0) {
CW_ERROR("spi_write_bytes 2nd: write failed");
return ret;
}
return ret;
}
int spi_rw_bytes_serial(u8 * wbuf, u8 * rbuf, u8 len)
{
int ret;
unsigned char *tx_buf = NULL, *rx_buf = NULL;
tx_buf = wbuf;
rx_buf = cwmcu_spi_src_buffer_all;
ret = spi_xfer(tx_buf, rx_buf, len);
if (ret == 0)
memcpy(rbuf, cwmcu_spi_src_buffer_all, len);
else if (ret < 0) {
CW_ERROR("spi_rw_bytes: read failed");
}
return ret;
}
void spi_init(void *dev)
{
struct mt_chip_conf *spi_par;
sensor->spi = dev;
spi_io_enable(1);
cwmcu_spi_src_buffer_all =
kmalloc(CWMCU_SPI_INTERFACE_MAX_PKT_LENGTH_PER_TIMES,
GFP_KERNEL);
if (cwmcu_spi_src_buffer_all == NULL) {
CW_ERROR("error kmalloc fail cwmcu_spi_src_buffer_all");
}
sensor->spi->controller_data = (void *) &spi_conf;
spi_par = &spi_conf;
if (!spi_par) {
CW_ERROR("spi config fail");
}
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(sensor->spi)) {
CW_ERROR("spi_setup fail");
}
spi_io_enable(0);
//TODO
//SPI DMA SETTING
}
int CWMCU_spi_probe(struct spi_device *spi)
{
CW_INFO("CWMCU_spi_probe entry");
CWMCU_probe(spi);
pm_runtime_enable(&spi->dev);
return 0;
}
int CWMCU_spi_remove(struct spi_device *spi)
{
sensor->spi = NULL;
return 0;
}
int CWMCU_spi_suspend(struct spi_device *spi, pm_message_t mesg)
{
CWMCU_suspend(&spi->dev);
return 0;
}
int CWMCU_spi_resume(struct spi_device *spi)
{
CWMCU_resume(&spi->dev);
}
static struct spi_board_info spi_cw_boardinfo __initdata = {
.modalias = CWMCU_NAME,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_3,
};
static struct spi_driver CWMCU_spi_driver = {
.driver = {
.name = CWMCU_SPI_NAME,
.owner = THIS_MODULE,
},
.probe = CWMCU_spi_probe,
.remove = CWMCU_spi_remove,
.suspend = CWMCU_spi_suspend,
.resume = CWMCU_spi_resume,
};
#endif //bus type
/*======================================================== */
void CWMCU_bus_init(void *bus_dev)
{
#if defined(CWMCU_I2C_INTERFACE)
i2c_init(bus_dev);
#elif defined(CWMCU_SPI_INTERFACE)
spi_init(bus_dev);
#endif
}
int CWMCU_bus_register(void)
{
#if defined(CWMCU_I2C_INTERFACE)
i2c_register_board_info(CWMCU_I2C_NUMBER, &i2c_cw_boardinfo, 1);
return i2c_add_driver(&CWMCU_i2c_driver);
#elif defined(CWMCU_SPI_INTERFACE)
spi_register_board_info(&spi_cw_boardinfo, 1);
return spi_register_driver(&CWMCU_spi_driver);
#endif
}
void CWMCU_bus_unregister(void)
{
#if defined(CWMCU_I2C_INTERFACE)
i2c_del_driver(&CWMCU_i2c_driver);
#elif defined(CWMCU_SPI_INTERFACE)
#endif
}
int CWMCU_bus_write(struct CWMCU_T *sensor, u8 reg_addr, u8 * data, u8 len)
{
int ret;
mutex_lock(&cwmcu_bus_lock);
#if defined(CWMCU_I2C_INTERFACE)
ret = i2c_write_bytes_dma(sensor->client, reg_addr, data, len);
#elif defined(CWMCU_SPI_INTERFACE)
ret = spi_write_bytes(reg_addr, data, len);
#endif
mutex_unlock(&cwmcu_bus_lock);
return ret;
}
/* Returns the number of read bytes on success */
int CWMCU_bus_read(struct CWMCU_T *sensor, u8 reg_addr, u8 * data, u8 len)
{
int ret = 0;
mutex_lock(&cwmcu_bus_lock);
#if defined(CWMCU_I2C_INTERFACE)
ret = i2c_read_bytes_dma(sensor->client, reg_addr, data, len);
#elif defined(CWMCU_SPI_INTERFACE)
ret = spi_read_bytes(reg_addr, data, len);
#endif
mutex_unlock(&cwmcu_bus_lock);
return ret;
}
int CWMCU_bus_write_serial(struct CWMCU_T *sensor, u8 * data, int len)
{
int ret = 0;
mutex_lock(&cwmcu_bus_lock);
#if defined(CWMCU_I2C_INTERFACE)
ret = i2c_write_bytes_dma_serial(sensor->client, data, len);
if (ret < 0) {
CW_ERROR("i2c write error =%d", ret);
goto BUS_WS_EXIT;
}
#elif defined(CWMCU_SPI_INTERFACE)
ret = spi_write_bytes_serial(data, len);
if (ret < 0) {
CW_ERROR("spi write error =%d", ret);
goto BUS_WS_EXIT;
}
#endif
mutex_unlock(&cwmcu_bus_lock);
BUS_WS_EXIT:
return ret;
}
int CWMCU_bus_read_serial(struct CWMCU_T *sensor, u8 * data, int len)
{
int ret = 0;
mutex_lock(&cwmcu_bus_lock);
#if defined(CWMCU_I2C_INTERFACE)
ret = i2c_read_bytes_dma_serial(sensor->client, data, len);
if (ret < 0) {
CW_ERROR("i2c read error =%d", ret);
goto BUS_RS_EXIT;
}
#elif defined(CWMCU_SPI_INTERFACE)
ret = spi_read_bytes_serial(data, len);
if (ret < 0) {
CW_ERROR("spi read error =%d", ret);
goto BUS_RS_EXIT;
}
#endif
mutex_unlock(&cwmcu_bus_lock);
BUS_RS_EXIT:
return ret;
}