diff options
-rw-r--r-- | drivers/misc/i2s/Kconfig | 10 | ||||
-rw-r--r-- | drivers/misc/i2s/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/i2s/i2s.c | 52 | ||||
-rw-r--r-- | drivers/misc/i2s/i2s_test_protocol_driver.c | 305 | ||||
-rw-r--r-- | drivers/misc/i2s/msp_i2s.c | 26 | ||||
-rw-r--r-- | include/linux/i2s/i2s.h | 1 | ||||
-rw-r--r-- | include/linux/i2s/i2s_test_prot.h | 44 |
7 files changed, 57 insertions, 382 deletions
diff --git a/drivers/misc/i2s/Kconfig b/drivers/misc/i2s/Kconfig index a2652e9eab3..569818caa5d 100644 --- a/drivers/misc/i2s/Kconfig +++ b/drivers/misc/i2s/Kconfig @@ -17,13 +17,3 @@ config STM_MSP_I2S If you say Y here, you will enable the U8500 MSP_I2S hardware driver. If unsure, say N. - -config STM_I2S_TEST_PROTOCOL_DRIVER - tristate "U8500 I2S test protocol driver" - depends on STM_I2S && STE_DMA40 && STM_MSP_I2S - default n - ---help--- - If you say Y here, you will enable the test protocol driver used for testing I2S Rx and Tx controllers - - If unsure, say N. - diff --git a/drivers/misc/i2s/Makefile b/drivers/misc/i2s/Makefile index 22cfdc07551..06cb51d7b30 100644 --- a/drivers/misc/i2s/Makefile +++ b/drivers/misc/i2s/Makefile @@ -5,4 +5,3 @@ nmdk_i2s-objs := i2s.o obj-$(CONFIG_STM_I2S) += nmdk_i2s.o obj-$(CONFIG_STM_MSP_I2S) += msp_i2s.o -obj-$(CONFIG_STM_I2S_TEST_PROTOCOL_DRIVER) += i2s_test_protocol_driver.o diff --git a/drivers/misc/i2s/i2s.c b/drivers/misc/i2s/i2s.c index a77711e3dd4..8ee7492a4fa 100644 --- a/drivers/misc/i2s/i2s.c +++ b/drivers/misc/i2s/i2s.c @@ -8,9 +8,8 @@ /* */ /* This program is distributed in the hope that it will be useful, but */ /* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY */ -/* or FITNES */ -/* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more */ -/* details. */ +/* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License */ +/* for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -173,15 +172,47 @@ int i2s_register_driver(struct i2s_driver *sdrv) EXPORT_SYMBOL_GPL(i2s_register_driver); /******************************************************************************/ +struct board_i2s_combined_info { + struct i2s_board_info board_info; + struct i2s_device *i2s_dev_p; +}; struct boardinfo { struct list_head list; unsigned n_board_info; - struct i2s_board_info board_info[0]; + struct board_i2s_combined_info board_i2s_info[0]; }; static LIST_HEAD(board_list); static DEFINE_MUTEX(board_lock); +/* + * Get an i2s device. Used in MSP LTP tests. + */ +struct i2s_device *i2s_get_device_from_boardinfo(int chip_select) +{ + struct boardinfo *bi; + struct i2s_device *i2s_dev_p = NULL; + + mutex_lock(&board_lock); + list_for_each_entry(bi, &board_list, list) { + struct board_i2s_combined_info *chip = bi->board_i2s_info; + unsigned n; + + for (n = bi->n_board_info; n > 0; n--, chip++) + if (chip->board_info.chip_select == chip_select) { + i2s_dev_p = chip->i2s_dev_p; + break; + } + if (i2s_dev_p != NULL) + break; + } + mutex_unlock(&board_lock); + + return i2s_dev_p; +} + +EXPORT_SYMBOL_GPL(i2s_get_device_from_boardinfo); + /* I2S devices should normally not be created by I2S device drivers; that * would make them board-specific. Similarly with I2S master drivers. * Device registration normally goes into like arch/.../mach.../board-YYY.c @@ -315,13 +346,16 @@ EXPORT_SYMBOL_GPL(i2s_new_device); int __init i2s_register_board_info(struct i2s_board_info const *info, unsigned n) { + int i; struct boardinfo *bi; - bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL); + bi = kmalloc(sizeof(*bi) + (n * sizeof(struct board_i2s_combined_info)), GFP_KERNEL); if (!bi) return -ENOMEM; bi->n_board_info = n; - memcpy(bi->board_info, info, n * sizeof *info); + + for (i = 0; i < n; i++) + memcpy(&bi->board_i2s_info[i].board_info, &info[i], sizeof *info); mutex_lock(&board_lock); list_add_tail(&bi->list, &board_list); @@ -347,16 +381,16 @@ static void scan_boardinfo(struct i2s_controller *i2s_cont) mutex_lock(&board_lock); list_for_each_entry(bi, &board_list, list) { - struct i2s_board_info *chip = bi->board_info; + struct board_i2s_combined_info *chip = bi->board_i2s_info; unsigned n; for (n = bi->n_board_info; n > 0; n--, chip++) { - if (chip->id != i2s_cont->id) + if (chip->board_info.chip_select != i2s_cont->id) continue; /* NOTE: this relies on i2s_new_device to * issue diagnostics when given bogus inputs */ - (void)i2s_new_device(i2s_cont, chip); + chip->i2s_dev_p = i2s_new_device(i2s_cont, &chip->board_info); } } mutex_unlock(&board_lock); diff --git a/drivers/misc/i2s/i2s_test_protocol_driver.c b/drivers/misc/i2s/i2s_test_protocol_driver.c deleted file mode 100644 index 639a28454f5..00000000000 --- a/drivers/misc/i2s/i2s_test_protocol_driver.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2009 - * Author: Sandeep Kaushik, <sandeep-mmc.kaushik@st.com> - * License terms: GNU General Public License (GPL) version 2 - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/ioctl.h> -#include <linux/fs.h> -#include <linux/device.h> -#include <linux/err.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/mutex.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/i2s/i2s.h> -#include <linux/i2s/i2s_test_prot.h> -#include <mach/msp.h> - -int i2s_drv_offset = 1; - -module_param(i2s_drv_offset, int, 1); -MODULE_PARM_DESC(i2s_drv_offset, "i2s driver to be opened)=(0/1/2/3/4/5)"); - -#define MAX_I2S_CLIENTS 6 - -struct i2sdrv_data { - spinlock_t i2s_lock; - struct i2s_device *i2s; - /* flag to show the device is closed or not */ - bool device_closed; - u32 tx_status; - u32 rx_status; -}; - -static struct i2sdrv_data *i2sdrv[MAX_I2S_CLIENTS]; - -/*API Interface */ -int i2s_testprot_drv_open(int i2s_device_num) -{ - if (!i2sdrv[i2s_device_num]) - return -EINVAL; - - spin_lock_irq(&i2sdrv[i2s_device_num]->i2s_lock); - if (!i2sdrv[i2s_device_num]->device_closed) { - spin_unlock_irq(&i2sdrv[i2s_device_num]->i2s_lock); - return -EBUSY; - } - i2sdrv[i2s_device_num]->device_closed = false; - spin_unlock_irq(&i2sdrv[i2s_device_num]->i2s_lock); - - return 0; -} -EXPORT_SYMBOL(i2s_testprot_drv_open); - -int i2s_config_default_protocol(int i2s_device_num, - struct test_prot_config *config) -{ - return __i2s_testprot_drv_configure(i2s_device_num, config, true); -} -EXPORT_SYMBOL(i2s_config_default_protocol); - -int i2s_testprot_drv_configure(int i2s_device_num, - struct test_prot_config *config) -{ - return __i2s_testprot_drv_configure(i2s_device_num, config, false); -} -EXPORT_SYMBOL(i2s_testprot_drv_configure); - -int __i2s_testprot_drv_configure(int i2s_device_num, - struct test_prot_config *config, bool use_default) -{ - int error_status = 0; - struct i2s_device *i2s_dev; - struct msp_config msp_config = { - .tx_clock_sel = TX_CLK_SEL_SRG, - .rx_clock_sel = 0x0, - .tx_frame_sync_sel = TX_SYNC_SRG_AUTO, - .rx_frame_sync_sel = 0x0, - .input_clock_freq = MSP_INPUT_FREQ_48MHZ, - .srg_clock_sel = SRG_CLK_SEL_APB, - .rx_frame_sync_pol = RX_FIFO_SYNC_HI, - .tx_frame_sync_pol = TX_FIFO_SYNC_HI, - .rx_fifo_config = RX_FIFO_ENABLE, - .tx_fifo_config = TX_FIFO_ENABLE, - .spi_clk_mode = SPI_CLK_MODE_NORMAL, - .tx_data_enable = 0x8000, - .spi_burst_mode = 0, - .loopback_enable = 0x80, - }; - - msp_config.default_protocol_desc = use_default; - - if (!i2sdrv[i2s_device_num]) - return -EINVAL; - - i2s_dev = i2sdrv[i2s_device_num]->i2s; - - if (i2sdrv[i2s_device_num]->device_closed) - return -EINVAL; - - if (!config) - return -EINVAL; - - msp_config.handler = config->handler; - msp_config.tx_callback_data = config->tx_callback_data; - msp_config.rx_callback_data = config->rx_callback_data; - msp_config.frame_freq = config->frame_freq; - msp_config.frame_size = config->frame_size; - msp_config.data_size = config->data_size; - msp_config.direction = config->direction; - msp_config.protocol = config->protocol; - msp_config.work_mode = config->work_mode; - - msp_config.def_elem_len = use_default; - - msp_config.multichannel_configured = 0; - msp_config.protocol_desc = config->protocol_desc; - - msp_config.multichannel_configured = config->multichannel_configured; - msp_config.multichannel_config.tx_multichannel_enable = - config->multichannel_config.tx_multichannel_enable; - /* Channel 1 to 3 */ - msp_config.multichannel_config.tx_channel_0_enable = - config->multichannel_config.tx_channel_0_enable; - /* Channel 33 to 64 */ - msp_config.multichannel_config.tx_channel_1_enable = - config->multichannel_config.tx_channel_1_enable; - /* Channel 65 to 96 */ - msp_config.multichannel_config.tx_channel_2_enable = - config->multichannel_config.tx_channel_2_enable; - /* Channel 97 to 128 */ - msp_config.multichannel_config.tx_channel_3_enable = - config->multichannel_config.tx_channel_3_enable; - msp_config.multichannel_config.rx_multichannel_enable = - config->multichannel_config.rx_multichannel_enable; - /* Channel 1 to 32 */ - msp_config.multichannel_config.rx_channel_0_enable = - config->multichannel_config.rx_channel_0_enable; - /* Channel 33 to 64 */ - msp_config.multichannel_config.rx_channel_1_enable = - config->multichannel_config.rx_channel_1_enable; - /* Channel 65 to 96 */ - msp_config.multichannel_config.rx_channel_2_enable = - config->multichannel_config.rx_channel_2_enable; - /* Channel 97 to 128 */ - msp_config.multichannel_config.rx_channel_3_enable = - config->multichannel_config.rx_channel_3_enable; - msp_config.multichannel_config.rx_comparison_enable_mode = - config->multichannel_config.rx_comparison_enable_mode; - msp_config.multichannel_config.comparison_value = - config->multichannel_config.comparison_value; - msp_config.multichannel_config.comparison_mask = - config->multichannel_config.comparison_mask; - - error_status = - i2s_setup(i2s_dev->controller, &msp_config); - if (error_status < 0) - dev_err(&i2s_dev->dev, "error in msp enable, error_status is %d\n", - error_status); - - return error_status; - -} - -int i2s_testprot_drv_transfer(int i2s_device_num, - void *txdata, size_t txbytes, void *rxdata, size_t rxbytes, - enum i2s_transfer_mode_t transfer_mode) -{ - int bytes_transreceive; - struct i2s_device *i2s_dev; - struct i2s_message message = {}; - - if (!i2sdrv[i2s_device_num]) - return -EINVAL; - - i2s_dev = i2sdrv[i2s_device_num]->i2s; - - if (i2sdrv[i2s_device_num]->device_closed) { - dev_info(&i2s_dev->dev, "msp device not opened yet\n"); - return -EINVAL; - } - - message.i2s_transfer_mode = transfer_mode; - message.i2s_direction = I2S_DIRECTION_BOTH; - message.txbytes = txbytes; - message.txdata = txdata; - message.rxbytes = rxbytes; - message.rxdata = rxdata; - message.dma_flag = 1; - bytes_transreceive = i2s_transfer(i2s_dev->controller, &message); - dev_dbg(&i2s_dev->dev, "bytes transreceived %d\n", bytes_transreceive); - - return bytes_transreceive; -} -EXPORT_SYMBOL(i2s_testprot_drv_transfer); - -int i2s_testprot_drv_close(int i2s_device_num) -{ - int status; - struct i2s_device *i2s_dev; - - if (!i2sdrv[i2s_device_num]) - return -EINVAL; - - i2s_dev = i2sdrv[i2s_device_num]->i2s; - - if (i2sdrv[i2s_device_num]->device_closed) - return -EINVAL; - - status = i2s_cleanup(i2s_dev->controller, DISABLE_ALL); - if (status) - return status; - - /* Mark the device as closed */ - i2sdrv[i2s_device_num]->device_closed = true; - - return 0; -} -EXPORT_SYMBOL(i2s_testprot_drv_close); - -static int i2sdrv_probe(struct i2s_device *i2s) -{ - int status = 0; - - /* Allocate driver data */ - if (!try_module_get(i2s->controller->dev.parent->driver->owner)) - return -ENOENT; - - i2sdrv[i2s->chip_select] = kzalloc(sizeof(*i2sdrv[i2s->chip_select]), - GFP_KERNEL); - - if (!i2sdrv[i2s->chip_select]) - return -ENOMEM; - - /* Initialize the driver data */ - i2sdrv[i2s->chip_select]->i2s = i2s; - i2sdrv[i2s->chip_select]->device_closed = true; - i2sdrv[i2s->chip_select]->tx_status = 0; - i2sdrv[i2s->chip_select]->rx_status = 0; - spin_lock_init(&i2sdrv[i2s->chip_select]->i2s_lock); - - i2s_set_drvdata(i2s, (void *)i2sdrv[i2s->chip_select]); - return status; -} - -static int i2sdrv_remove(struct i2s_device *i2s) -{ - spin_lock_irq(&i2sdrv[i2s->chip_select]->i2s_lock); - i2sdrv[i2s->chip_select]->i2s = NULL; - i2s_set_drvdata(i2s, NULL); - module_put(i2s->controller->dev.parent->driver->owner); - spin_unlock_irq(&i2sdrv[i2s->chip_select]->i2s_lock); - - kfree(i2sdrv[i2s->chip_select]); - - return 0; -} - -static const struct i2s_device_id i2s_test_prot_id_table[] = { - { "i2s_device.0", 0, 0 }, - { "i2s_device.1", 0, 0 }, - { "i2s_device.2", 0, 0 }, - { "i2s_device.3", 0, 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2s, i2s_test_prot_id_table); - -static struct i2s_driver i2sdrv_i2s = { - .driver = { - .name = "i2s_test_protocol_driver", - .owner = THIS_MODULE, - }, - .probe = i2sdrv_probe, - .remove = __devexit_p(i2sdrv_remove), - .id_table = i2s_test_prot_id_table, - - /* - * NOTE: suspend/resume methods are not necessary here. - */ -}; - -static int __init i2sdrv_init(void) -{ - int status; - - status = i2s_register_driver(&i2sdrv_i2s); - if (status < 0) - printk(KERN_ERR "Unable to register i2s driver\n"); - - return status; -} -module_init(i2sdrv_init); - -static void __exit i2sdrv_exit(void) -{ - i2s_unregister_driver(&i2sdrv_i2s); -} -module_exit(i2sdrv_exit); - -MODULE_AUTHOR("Sandeep Kaushik, <sandeep-mmc.kaushik@st.com>"); -MODULE_DESCRIPTION("Test Driver module I2S device interface"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/i2s/msp_i2s.c b/drivers/misc/i2s/msp_i2s.c index 72fc51315ce..8dcf86d4b64 100644 --- a/drivers/misc/i2s/msp_i2s.c +++ b/drivers/misc/i2s/msp_i2s.c @@ -1227,19 +1227,6 @@ static int msp_dma_xfer(struct msp *msp, struct i2s_message *msg) switch (msg->i2s_transfer_mode) { default: case I2S_TRANSFER_MODE_SINGLE_DMA: - if (msg->i2s_direction == I2S_DIRECTION_TX || - msg->i2s_direction == I2S_DIRECTION_BOTH) - if (msg->txdata && (msg->txbytes > 0)) { - if (!msg->dma_flag) - msg->txdata = - (void *)dma_map_single(NULL, - msg->txdata, - msg->txbytes, - DMA_TO_DEVICE); - status = msp_single_dma_tx(msp, - (dma_addr_t)msg->txdata, - msg->txbytes); - } if (msg->i2s_direction == I2S_DIRECTION_RX || msg->i2s_direction == I2S_DIRECTION_BOTH) if (msg->rxdata && (msg->rxbytes > 0)) { @@ -1254,6 +1241,19 @@ static int msp_dma_xfer(struct msp *msp, struct i2s_message *msg) (dma_addr_t)msg->rxdata, msg->rxbytes); } + if (msg->i2s_direction == I2S_DIRECTION_TX || + msg->i2s_direction == I2S_DIRECTION_BOTH) + if (msg->txdata && (msg->txbytes > 0)) { + if (!msg->dma_flag) + msg->txdata = + (void *)dma_map_single(NULL, + msg->txdata, + msg->txbytes, + DMA_TO_DEVICE); + status = msp_single_dma_tx(msp, + (dma_addr_t)msg->txdata, + msg->txbytes); + } break; case I2S_TRANSFER_MODE_CYCLIC_DMA: diff --git a/include/linux/i2s/i2s.h b/include/linux/i2s/i2s.h index b67fdb2d80d..94e461656a4 100644 --- a/include/linux/i2s/i2s.h +++ b/include/linux/i2s/i2s.h @@ -212,6 +212,7 @@ extern int i2s_hw_status(struct i2s_controller *i2s_cont); extern dma_addr_t i2s_get_pointer(struct i2s_controller *i2s_cont, enum i2s_direction_t i2s_direction); +extern struct i2s_device *i2s_get_device_from_boardinfo(int chip_select); /* used in MSP LTP tests */ extern struct i2s_device *i2s_alloc_device(struct device *dev); extern int i2s_add_device(struct i2s_device *i2s); diff --git a/include/linux/i2s/i2s_test_prot.h b/include/linux/i2s/i2s_test_prot.h deleted file mode 100644 index 003d0e6e3ab..00000000000 --- a/include/linux/i2s/i2s_test_prot.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License terms: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#ifndef __I2S_TEST_PROT_DRIVER_IF_H__ -#define __I2S_TEST_PROT_DRIVER_IF_H__ -#include <mach/msp.h> -struct test_prot_config { - u32 tx_config_desc; - u32 rx_config_desc; - u32 frame_freq; - u32 frame_size; - u32 data_size; - u32 direction; - u32 protocol; - u32 work_mode; - struct msp_protocol_desc protocol_desc; - void (*handler) (void *data); - void *tx_callback_data; - void *rx_callback_data; - int multichannel_configured; - struct msp_multichannel_config multichannel_config; -}; - -int i2s_testprot_drv_open(int i2s_device_num); -int i2s_testprot_drv_configure(int i2s_device_num, - struct test_prot_config *config); -int i2s_config_default_protocol(int i2s_device_num, - struct test_prot_config *config); -int __i2s_testprot_drv_configure(int i2s_device_num, - struct test_prot_config *config, - bool use_default); -int i2s_testprot_drv_transfer(int i2s_device_num, void *txdata, size_t txbytes, - void *rxdata, size_t rxbytes, - enum i2s_transfer_mode_t transfer_mode); -int i2s_testprot_drv_close(int i2s_device_num); - -#endif |