summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/i2s/Kconfig10
-rw-r--r--drivers/misc/i2s/Makefile1
-rw-r--r--drivers/misc/i2s/i2s.c52
-rw-r--r--drivers/misc/i2s/i2s_test_protocol_driver.c305
-rw-r--r--drivers/misc/i2s/msp_i2s.c26
-rw-r--r--include/linux/i2s/i2s.h1
-rw-r--r--include/linux/i2s/i2s_test_prot.h44
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