diff options
Diffstat (limited to 'drivers/mxc/dam')
-rw-r--r-- | drivers/mxc/dam/Kconfig | 13 | ||||
-rw-r--r-- | drivers/mxc/dam/Makefile | 9 | ||||
-rw-r--r-- | drivers/mxc/dam/dam.c | 427 | ||||
-rw-r--r-- | drivers/mxc/dam/dam.h | 258 | ||||
-rw-r--r-- | drivers/mxc/dam/dam_v1.c | 616 |
5 files changed, 1323 insertions, 0 deletions
diff --git a/drivers/mxc/dam/Kconfig b/drivers/mxc/dam/Kconfig new file mode 100644 index 000000000000..7b4bee92f648 --- /dev/null +++ b/drivers/mxc/dam/Kconfig @@ -0,0 +1,13 @@ +# +# DAM API configuration +# + +menu "MXC Digital Audio Multiplexer support" + +config MXC_DAM + tristate "DAM support" + depends on ARCH_MXC + ---help--- + Say Y to get the Digital Audio Multiplexer services API available on MXC platform. + +endmenu diff --git a/drivers/mxc/dam/Makefile b/drivers/mxc/dam/Makefile new file mode 100644 index 000000000000..b5afdc143dfa --- /dev/null +++ b/drivers/mxc/dam/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the kernel Digital Audio MUX (DAM) device driver. +# + +ifeq ($(CONFIG_ARCH_MX27),y) + obj-$(CONFIG_MXC_DAM) += dam_v1.o +else + obj-$(CONFIG_MXC_DAM) += dam.o +endif diff --git a/drivers/mxc/dam/dam.c b/drivers/mxc/dam/dam.c new file mode 100644 index 000000000000..54c7dbc78625 --- /dev/null +++ b/drivers/mxc/dam/dam.c @@ -0,0 +1,427 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file dam.c + * @brief This is the brief documentation for this dam.c file. + * + * This file contains the implementation of the DAM driver main services + * + * @ingroup DAM + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <asm/uaccess.h> +#include "dam.h" + +/*! + * This include to define bool type, false and true definitions. + */ +#include <asm/hardware.h> + +#define ModifyRegister32(a,b,c) (c = ( ( (c)&(~(a)) ) | (b) )) + +#define DAM_VIRT_BASE_ADDR IO_ADDRESS(AUDMUX_BASE_ADDR) + +#ifndef _reg_DAM_PTCR1 +#define _reg_DAM_PTCR1 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x00))) +#endif + +#ifndef _reg_DAM_PDCR1 +#define _reg_DAM_PDCR1 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x04))) +#endif + +#ifndef _reg_DAM_PTCR2 +#define _reg_DAM_PTCR2 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x08))) +#endif + +#ifndef _reg_DAM_PDCR2 +#define _reg_DAM_PDCR2 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x0C))) +#endif + +#ifndef _reg_DAM_PTCR3 +#define _reg_DAM_PTCR3 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x10))) +#endif + +#ifndef _reg_DAM_PDCR3 +#define _reg_DAM_PDCR3 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x14))) +#endif + +#ifndef _reg_DAM_PTCR4 +#define _reg_DAM_PTCR4 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x18))) +#endif + +#ifndef _reg_DAM_PDCR4 +#define _reg_DAM_PDCR4 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x1C))) +#endif + +#ifndef _reg_DAM_PTCR5 +#define _reg_DAM_PTCR5 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x20))) +#endif + +#ifndef _reg_DAM_PDCR5 +#define _reg_DAM_PDCR5 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x24))) +#endif + +#ifndef _reg_DAM_PTCR6 +#define _reg_DAM_PTCR6 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x28))) +#endif + +#ifndef _reg_DAM_PDCR6 +#define _reg_DAM_PDCR6 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x2C))) +#endif + +#ifndef _reg_DAM_PTCR7 +#define _reg_DAM_PTCR7 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x30))) +#endif + +#ifndef _reg_DAM_PDCR7 +#define _reg_DAM_PDCR7 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x34))) +#endif + +#ifndef _reg_DAM_CNMCR +#define _reg_DAM_CNMCR (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x38))) +#endif + +#ifndef _reg_DAM_PTCR +#define _reg_DAM_PTCR(a) (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + a*8))) +#endif + +#ifndef _reg_DAM_PDCR +#define _reg_DAM_PDCR(a) (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 4 + a*8))) +#endif + +/*! + * PTCR Registers bit shift definitions + */ +#define dam_synchronous_mode_shift 11 +#define dam_receive_clock_select_shift 12 +#define dam_receive_clock_direction_shift 16 +#define dam_receive_frame_sync_select_shift 17 +#define dam_receive_frame_sync_direction_shift 21 +#define dam_transmit_clock_select_shift 22 +#define dam_transmit_clock_direction_shift 26 +#define dam_transmit_frame_sync_select_shift 27 +#define dam_transmit_frame_sync_direction_shift 31 +#define dam_selection_mask 0xF + +/*! + * HPDCR Register bit shift definitions + */ +#define dam_internal_network_mode_shift 0 +#define dam_mode_shift 8 +#define dam_transmit_receive_switch_shift 12 +#define dam_receive_data_select_shift 13 + +/*! + * HPDCR Register bit masq definitions + */ +#define dam_mode_masq 0x03 +#define dam_internal_network_mode_mask 0xFF + +/*! + * CNMCR Register bit shift definitions + */ +#define dam_ce_bus_port_cntlow_shift 0 +#define dam_ce_bus_port_cnthigh_shift 8 +#define dam_ce_bus_port_clkpol_shift 16 +#define dam_ce_bus_port_fspol_shift 17 +#define dam_ce_bus_port_enable_shift 18 + +#define DAM_NAME "dam" + +EXPORT_SYMBOL(dam_select_mode); +EXPORT_SYMBOL(dam_select_RxClk_direction); +EXPORT_SYMBOL(dam_select_RxClk_source); +EXPORT_SYMBOL(dam_select_RxD_source); +EXPORT_SYMBOL(dam_select_RxFS_direction); +EXPORT_SYMBOL(dam_select_RxFS_source); +EXPORT_SYMBOL(dam_select_TxClk_direction); +EXPORT_SYMBOL(dam_select_TxClk_source); +EXPORT_SYMBOL(dam_select_TxFS_direction); +EXPORT_SYMBOL(dam_select_TxFS_source); +EXPORT_SYMBOL(dam_set_internal_network_mode_mask); +EXPORT_SYMBOL(dam_set_synchronous); +EXPORT_SYMBOL(dam_switch_Tx_Rx); +EXPORT_SYMBOL(dam_reset_register); + +/*! + * This function selects the operation mode of the port. + * + * @param port the DAM port to configure + * @param the_mode the operation mode of the port + * + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_select_mode(dam_port port, dam_mode the_mode) +{ + int result; + result = 0; + + ModifyRegister32(dam_mode_masq << dam_mode_shift, + the_mode << dam_mode_shift, _reg_DAM_PDCR(port)); + + return result; +} + +/*! + * This function controls Receive clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx clock signal direction + */ +void dam_select_RxClk_direction(dam_port port, signal_direction direction) +{ + ModifyRegister32(1 << dam_receive_clock_direction_shift, + direction << dam_receive_clock_direction_shift, + _reg_DAM_PTCR(port)); +} + +/*! + * This function controls Receive clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_RxClk_source(dam_port p_config, + bool from_RxClk, dam_port p_source) +{ + ModifyRegister32(dam_selection_mask << dam_receive_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_receive_clock_select_shift, + _reg_DAM_PTCR(p_config)); +} + +/*! + * This function selects the source port for the RxD data. + * + * @param p_config the DAM port to configure + * @param p_source the source port + */ +void dam_select_RxD_source(dam_port p_config, dam_port p_source) +{ + ModifyRegister32(dam_selection_mask << dam_receive_data_select_shift, + p_source << dam_receive_data_select_shift, + _reg_DAM_PDCR(p_config)); +} + +/*! + * This function controls Receive Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx Frame Sync signal direction + */ +void dam_select_RxFS_direction(dam_port port, signal_direction direction) +{ + ModifyRegister32(1 << dam_receive_frame_sync_direction_shift, + direction << dam_receive_frame_sync_direction_shift, + _reg_DAM_PTCR(port)); +} + +/*! + * This function controls Receive Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_RxFS_source(dam_port p_config, + bool from_RxFS, dam_port p_source) +{ + ModifyRegister32(dam_selection_mask << + dam_receive_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_receive_frame_sync_select_shift, + _reg_DAM_PTCR(p_config)); +} + +/*! + * This function controls Transmit clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx clock signal direction + */ +void dam_select_TxClk_direction(dam_port port, signal_direction direction) +{ + ModifyRegister32(1 << dam_transmit_clock_direction_shift, + direction << dam_transmit_clock_direction_shift, + _reg_DAM_PTCR(port)); +} + +/*! + * This function controls Transmit clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_TxClk_source(dam_port p_config, + bool from_RxClk, dam_port p_source) +{ + ModifyRegister32(dam_selection_mask << dam_transmit_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_transmit_clock_select_shift, + _reg_DAM_PTCR(p_config)); +} + +/*! + * This function controls Transmit Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx Frame Sync signal direction + */ +void dam_select_TxFS_direction(dam_port port, signal_direction direction) +{ + ModifyRegister32(1 << dam_transmit_frame_sync_direction_shift, + direction << dam_transmit_frame_sync_direction_shift, + _reg_DAM_PTCR(port)); +} + +/*! + * This function controls Transmit Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_TxFS_source(dam_port p_config, + bool from_RxFS, dam_port p_source) +{ + ModifyRegister32(dam_selection_mask << + dam_transmit_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_transmit_frame_sync_select_shift, + _reg_DAM_PTCR(p_config)); +} + +/*! + * This function sets a bit mask that selects the port from which of the RxD + * signals are to be ANDed together for internal network mode. + * Bit 6 represents RxD from Port7 and bit0 represents RxD from Port1. + * 1 excludes RxDn from ANDing. 0 includes RxDn for ANDing. + * + * @param port the DAM port to configure + * @param bit_mask the bit mask + * + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_set_internal_network_mode_mask(dam_port port, unsigned char bit_mask) +{ + int result; + result = 0; + + ModifyRegister32(dam_internal_network_mode_mask << + dam_internal_network_mode_shift, + bit_mask << dam_internal_network_mode_shift, + _reg_DAM_PDCR(port)); + + return result; +} + +/*! + * This function controls whether or not the port is in synchronous mode. + * When the synchronous mode is selected, the receive and the transmit sections + * use common clock and frame sync signals. + * When the synchronous mode is not selected, separate clock and frame sync + * signals are used for the transmit and the receive sections. + * The defaut value is the synchronous mode selected. + * + * @param port the DAM port to configure + * @param synchronous the state to assign + */ +void dam_set_synchronous(dam_port port, bool synchronous) +{ + ModifyRegister32(1 << dam_synchronous_mode_shift, + synchronous << dam_synchronous_mode_shift, + _reg_DAM_PTCR(port)); +} + +/*! + * This function swaps the transmit and receive signals from (Da-TxD, Db-RxD) + * to (Da-RxD, Db-TxD). + * This default signal configuration is Da-TxD, Db-RxD. + * + * @param port the DAM port to configure + * @param value the switch state + */ +void dam_switch_Tx_Rx(dam_port port, bool value) +{ + ModifyRegister32(1 << dam_transmit_receive_switch_shift, + value << dam_transmit_receive_switch_shift, + _reg_DAM_PDCR(port)); +} + +/*! + * This function resets the two registers of the selected port. + * + * @param port the DAM port to reset + */ +void dam_reset_register(dam_port port) +{ + ModifyRegister32(0xFFFFFFFF, 0x00000000, _reg_DAM_PTCR(port)); + ModifyRegister32(0xFFFFFFFF, 0x00000000, _reg_DAM_PDCR(port)); +} + +/*! + * This function implements the init function of the DAM device. + * This function is called when the module is loaded. + * + * @return This function returns 0. + */ +static int __init dam_init(void) +{ + return 0; +} + +/*! + * This function implements the exit function of the SPI device. + * This function is called when the module is unloaded. + * + */ +static void __exit dam_exit(void) +{ +} + +module_init(dam_init); +module_exit(dam_exit); + +MODULE_DESCRIPTION("DAM char device driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); diff --git a/drivers/mxc/dam/dam.h b/drivers/mxc/dam/dam.h new file mode 100644 index 000000000000..cb9ead53f689 --- /dev/null +++ b/drivers/mxc/dam/dam.h @@ -0,0 +1,258 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + + /*! + * @defgroup DAM Digital Audio Multiplexer (AUDMUX) Driver + */ + + /*! + * @file dam.h + * @brief This is the brief documentation for this dam.h file. + * + * This header file contains DAM driver functions prototypes. + * + * @ingroup DAM + */ + +#ifndef __MXC_DAM_H__ +#define __MXC_DAM_H__ + +/*! + * This enumeration describes the Digital Audio Multiplexer mode. + */ +typedef enum { + + /*! + * Normal mode + */ + normal_mode = 0, + + /*! + * Internal network mode + */ + internal_network_mode = 1, + + /*! + * CE bus network mode + */ + CE_bus_network_mode = 2 +} dam_mode; + +/*! + * This enumeration describes the port. + */ +typedef enum { + + /*! + * The port 1 + */ + port_1 = 0, + + /*! + * The port 2 + */ + port_2 = 1, + + /*! + * The port 3 + */ + port_3 = 2, + + /*! + * The port 4 + */ + port_4 = 3, + + /*! + * The port 5 + */ + port_5 = 4, + + /*! + * The port 6 + */ + port_6 = 5, + + /*! + * The port 7 + */ + port_7 = 6 +} dam_port; + +/*! + * This enumeration describes the signal direction. + */ +typedef enum { + + /*! + * Signal In + */ + signal_in = 0, + + /*! + * Signal Out + */ + signal_out = 1 +} signal_direction; + +/*! + * Test purpose definition + */ +#define TEST_DAM 1 + +#ifdef TEST_DAM + +#define DAM_IOCTL 0x55 +#define DAM_CONFIG_SSI1_MC13783 _IOWR(DAM_IOCTL, 1, int) +#define DAM_CONFIG_SSI2_MC13783 _IOWR(DAM_IOCTL, 2, int) +#define DAM_CONFIG_SSI_NETWORK_MODE_MC13783 _IOWR(DAM_IOCTL, 3, int) +#endif + +/*! + * This function selects the operation mode of the port. + * + * @param port the DAM port to configure + * @param the_mode the operation mode of the port + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_select_mode(dam_port port, dam_mode the_mode); + +/*! + * This function controls Receive clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx clock signal direction + */ +void dam_select_RxClk_direction(dam_port port, signal_direction direction); + +/*! + * This function controls Receive clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_RxClk_source(dam_port p_config, bool from_RxClk, + dam_port p_source); + +/*! + * This function selects the source port for the RxD data. + * + * @param p_config the DAM port to configure + * @param p_source the source port + */ +void dam_select_RxD_source(dam_port p_config, dam_port p_source); + +/*! + * This function controls Receive Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx Frame Sync signal direction + */ +void dam_select_RxFS_direction(dam_port port, signal_direction direction); + +/*! + * This function controls Receive Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_RxFS_source(dam_port p_config, bool from_RxFS, + dam_port p_source); + +/*! + * This function controls Transmit clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx clock signal direction + */ +void dam_select_TxClk_direction(dam_port port, signal_direction direction); + +/*! + * This function controls Transmit clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_TxClk_source(dam_port p_config, bool from_RxClk, + dam_port p_source); + +/*! + * This function controls Transmit Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx Frame Sync signal direction + */ +void dam_select_TxFS_direction(dam_port port, signal_direction direction); + +/*! + * This function controls Transmit Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_TxFS_source(dam_port p_config, bool from_RxFS, + dam_port p_source); + +/*! + * This function sets a bit mask that selects the port from which of + * the RxD signals are to be ANDed together for internal network mode. + * Bit 6 represents RxD from Port7 and bit0 represents RxD from Port1. + * 1 excludes RxDn from ANDing. 0 includes RxDn for ANDing. + * + * @param port the DAM port to configure + * @param bit_mask the bit mask + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_set_internal_network_mode_mask(dam_port port, unsigned char bit_mask); + +/*! + * This function controls whether or not the port is in synchronous mode. + * When the synchronous mode is selected, the receive and the transmit sections + * use common clock and frame sync signals. + * When the synchronous mode is not selected, separate clock and frame sync + * signals are used for the transmit and the receive sections. + * The defaut value is the synchronous mode selected. + * + * @param port the DAM port to configure + * @param synchronous the state to assign + */ +void dam_set_synchronous(dam_port port, bool synchronous); + +/*! + * This function swaps the transmit and receive signals from (Da-TxD, Db-RxD) to + * (Da-RxD, Db-TxD). + * This default signal configuration is Da-TxD, Db-RxD. + * + * @param port the DAM port to configure + * @param value the switch state + */ +void dam_switch_Tx_Rx(dam_port port, bool value); + +/*! + * This function resets the two registers of the selected port. + * + * @param port the DAM port to reset + */ +void dam_reset_register(dam_port port); + +#endif diff --git a/drivers/mxc/dam/dam_v1.c b/drivers/mxc/dam/dam_v1.c new file mode 100644 index 000000000000..ee5575213e65 --- /dev/null +++ b/drivers/mxc/dam/dam_v1.c @@ -0,0 +1,616 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file dam_v1.c + * @brief This is the brief documentation for this dam_v1.c file. + * + * This file contains the implementation of the DAM driver main services + * + * @ingroup DAM + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <asm/uaccess.h> +#include "dam.h" + +/*! + * This include to define bool type, false and true definitions. + */ +#include <asm/hardware.h> + +#define DAM_VIRT_BASE_ADDR IO_ADDRESS(AUDMUX_BASE_ADDR) + +#define ModifyRegister32(a,b,c) do{\ + __raw_writel( ((__raw_readl(c)) & (~(a))) | (b),(c) );\ +}while(0) + +#ifndef _reg_DAM_HPCR1 +#define _reg_DAM_HPCR1 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x00))) +#endif + +#ifndef _reg_DAM_HPCR2 +#define _reg_DAM_HPCR2 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x04))) +#endif + +#ifndef _reg_DAM_HPCR3 +#define _reg_DAM_HPCR3 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x08))) +#endif + +#ifndef _reg_DAM_PPCR1 +#define _reg_DAM_PPCR1 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x10))) +#endif + +#ifndef _reg_DAM_PPCR2 +#define _reg_DAM_PPCR2 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x14))) +#endif + +#ifndef _reg_DAM_PPCR3 +#define _reg_DAM_PPCR3 (*((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x1c))) +#endif + +#ifndef _reg_DAM_HPCR +#define _reg_DAM_HPCR(a) ((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + (a)*4)) +#endif + +#ifndef _reg_DAM_PPCR +#define _reg_DAM_PPCR(a) ((volatile unsigned long *) \ + (DAM_VIRT_BASE_ADDR + 0x0c + (0x04 << (a-3)) )) +#endif + +/*! + * HPCR/PPCR Registers bit shift definitions + */ +#define dam_transmit_frame_sync_direction_shift 31 +#define dam_transmit_clock_direction_shift 30 +#define dam_transmit_frame_sync_select_shift 26 +#define dam_transmit_clock_select_shift 26 +#define dam_receive_frame_sync_direction_shift 25 +#define dam_receive_clock_direction_shift 24 +#define dam_receive_clock_select_shift 20 +#define dam_receive_frame_sync_select_shift 20 + +#define dam_receive_data_select_shift 13 +#define dam_synchronous_mode_shift 12 + +#define dam_transmit_receive_switch_shift 10 + +#define dam_mode_shift 8 +#define dam_internal_network_mode_shift 0 + +/*! + * HPCR/PPCR Register bit masq definitions + */ +//#define dam_selection_mask 0xF +#define dam_fs_selection_mask 0xF +#define dam_clk_selection_mask 0xF +#define dam_dat_selection_mask 0x7 +//#define dam_mode_masq 0x03 +#define dam_internal_network_mode_mask 0xFF + +/*! + * HPCR/PPCR Register reset value definitions + */ +#define dam_hpcr_default_value 0x00001000 +#define dam_ppcr_default_value 0x00001000 + +#define DAM_NAME "dam" +static struct class *mxc_dam_class; + +EXPORT_SYMBOL(dam_select_mode); +EXPORT_SYMBOL(dam_select_RxClk_direction); +EXPORT_SYMBOL(dam_select_RxClk_source); +EXPORT_SYMBOL(dam_select_RxD_source); +EXPORT_SYMBOL(dam_select_RxFS_direction); +EXPORT_SYMBOL(dam_select_RxFS_source); +EXPORT_SYMBOL(dam_select_TxClk_direction); +EXPORT_SYMBOL(dam_select_TxClk_source); +EXPORT_SYMBOL(dam_select_TxFS_direction); +EXPORT_SYMBOL(dam_select_TxFS_source); +EXPORT_SYMBOL(dam_set_internal_network_mode_mask); +EXPORT_SYMBOL(dam_set_synchronous); +EXPORT_SYMBOL(dam_switch_Tx_Rx); +EXPORT_SYMBOL(dam_reset_register); + +/*! + * DAM major + */ +#ifdef TEST_DAM +static int major_dam; + +typedef struct _mxc_cfg { + int reg; + int val; +} mxc_cfg; + +#endif + +/*! + * This function selects the operation mode of the port. + * + * @param port the DAM port to configure + * @param the_mode the operation mode of the port + * + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_select_mode(dam_port port, dam_mode the_mode) +{ + int result; + result = 0; + + if (port >= 3) + the_mode = normal_mode; + ModifyRegister32(1 << dam_mode_shift, + the_mode << dam_mode_shift, _reg_DAM_HPCR(port)); + + return result; +} + +/*! + * This function controls Receive clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx clock signal direction + */ +void dam_select_RxClk_direction(dam_port port, signal_direction direction) +{ + if (port < 3) { + ModifyRegister32(1 << dam_receive_clock_direction_shift, + direction << dam_receive_clock_direction_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_receive_clock_direction_shift, + direction << dam_receive_clock_direction_shift, + _reg_DAM_PPCR(port)); + } + return; +} + +/*! + * This function controls Receive clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_RxClk_source(dam_port p_config, + bool from_RxClk, dam_port p_source) +{ + if (p_config < 3) { + ModifyRegister32(dam_clk_selection_mask << + dam_receive_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_receive_clock_select_shift, + _reg_DAM_HPCR(p_config)); + } else { + ModifyRegister32(dam_clk_selection_mask << + dam_receive_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_receive_clock_select_shift, + _reg_DAM_PPCR(p_config)); + } + return; +} + +/*! + * This function selects the source port for the RxD data. + * + * @param p_config the DAM port to configure + * @param p_source the source port + */ +void dam_select_RxD_source(dam_port p_config, dam_port p_source) +{ + if (p_config < 3) { + ModifyRegister32(dam_dat_selection_mask << + dam_receive_data_select_shift, + p_source << dam_receive_data_select_shift, + _reg_DAM_HPCR(p_config)); + } else { + ModifyRegister32(dam_dat_selection_mask << + dam_receive_data_select_shift, + p_source << dam_receive_data_select_shift, + _reg_DAM_PPCR(p_config)); + } + return; +} + +/*! + * This function controls Receive Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Rx Frame Sync signal direction + */ +void dam_select_RxFS_direction(dam_port port, signal_direction direction) +{ + if (port < 3) { + ModifyRegister32(1 << dam_receive_frame_sync_direction_shift, + direction << + dam_receive_frame_sync_direction_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_receive_frame_sync_direction_shift, + direction << + dam_receive_frame_sync_direction_shift, + _reg_DAM_PPCR(port)); + } + return; +} + +/*! + * This function controls Receive Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_RxFS_source(dam_port p_config, + bool from_RxFS, dam_port p_source) +{ + if (p_config < 3) { + ModifyRegister32(dam_fs_selection_mask << + dam_receive_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_receive_frame_sync_select_shift, + _reg_DAM_HPCR(p_config)); + } else { + ModifyRegister32(dam_fs_selection_mask << + dam_receive_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_receive_frame_sync_select_shift, + _reg_DAM_PPCR(p_config)); + } + return; +} + +/*! + * This function controls Transmit clock signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx clock signal direction + */ +void dam_select_TxClk_direction(dam_port port, signal_direction direction) +{ + if (port < 3) { + ModifyRegister32(1 << dam_transmit_clock_direction_shift, + direction << + dam_transmit_clock_direction_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_transmit_clock_direction_shift, + direction << + dam_transmit_clock_direction_shift, + _reg_DAM_PPCR(port)); + } + return; +} + +/*! + * This function controls Transmit clock signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxClk the signal comes from RxClk or TxClk of + * the source port + * @param p_source the source port + */ +void dam_select_TxClk_source(dam_port p_config, + bool from_RxClk, dam_port p_source) +{ + if (p_config < 3) { + ModifyRegister32(dam_clk_selection_mask << + dam_transmit_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_transmit_clock_select_shift, + _reg_DAM_HPCR(p_config)); + } else { + ModifyRegister32(dam_clk_selection_mask << + dam_transmit_clock_select_shift, + ((from_RxClk << 3) | p_source) << + dam_transmit_clock_select_shift, + _reg_DAM_PPCR(p_config)); + } + return; +} + +/*! + * This function controls Transmit Frame Sync signal direction for the port. + * + * @param port the DAM port to configure + * @param direction the Tx Frame Sync signal direction + */ +void dam_select_TxFS_direction(dam_port port, signal_direction direction) +{ + if (port < 3) { + ModifyRegister32(1 << dam_transmit_frame_sync_direction_shift, + direction << + dam_transmit_frame_sync_direction_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_transmit_frame_sync_direction_shift, + direction << + dam_transmit_frame_sync_direction_shift, + _reg_DAM_HPCR(port)); + } + return; +} + +/*! + * This function controls Transmit Frame Sync signal source for the port. + * + * @param p_config the DAM port to configure + * @param from_RxFS the signal comes from RxFS or TxFS of + * the source port + * @param p_source the source port + */ +void dam_select_TxFS_source(dam_port p_config, + bool from_RxFS, dam_port p_source) +{ + if (p_config < 3) { + ModifyRegister32(dam_fs_selection_mask << + dam_transmit_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_transmit_frame_sync_select_shift, + _reg_DAM_HPCR(p_config)); + } else { + ModifyRegister32(dam_fs_selection_mask << + dam_transmit_frame_sync_select_shift, + ((from_RxFS << 3) | p_source) << + dam_transmit_frame_sync_select_shift, + _reg_DAM_PPCR(p_config)); + } + return; +} + +/*! + * This function sets a bit mask that selects the port from which of the RxD + * signals are to be ANDed together for internal network mode. + * Bit 6 represents RxD from Port7 and bit0 represents RxD from Port1. + * 1 excludes RxDn from ANDing. 0 includes RxDn for ANDing. + * + * @param port the DAM port to configure + * @param bit_mask the bit mask + * + * @return This function returns the result of the operation + * (0 if successful, -1 otherwise). + */ +int dam_set_internal_network_mode_mask(dam_port port, unsigned char bit_mask) +{ + int result; + result = 0; + + ModifyRegister32(dam_internal_network_mode_mask << + dam_internal_network_mode_shift, + bit_mask << dam_internal_network_mode_shift, + _reg_DAM_HPCR(port)); + return result; +} + +/*! + * This function controls whether or not the port is in synchronous mode. + * When the synchronous mode is selected, the receive and the transmit sections + * use common clock and frame sync signals. + * When the synchronous mode is not selected, separate clock and frame sync + * signals are used for the transmit and the receive sections. + * The defaut value is the synchronous mode selected. + * + * @param port the DAM port to configure + * @param synchronous the state to assign + */ +void dam_set_synchronous(dam_port port, bool synchronous) +{ + if (port < 3) { + ModifyRegister32(1 << dam_synchronous_mode_shift, + synchronous << dam_synchronous_mode_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_synchronous_mode_shift, + synchronous << dam_synchronous_mode_shift, + _reg_DAM_PPCR(port)); + } + return; +} + +/*! + * This function swaps the transmit and receive signals from (Da-TxD, Db-RxD) + * to (Da-RxD, Db-TxD). + * This default signal configuration is Da-TxD, Db-RxD. + * + * @param port the DAM port to configure + * @param value the switch state + */ +void dam_switch_Tx_Rx(dam_port port, bool value) +{ + if (port < 3) { + ModifyRegister32(1 << dam_transmit_receive_switch_shift, + value << dam_transmit_receive_switch_shift, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(1 << dam_transmit_receive_switch_shift, + value << dam_transmit_receive_switch_shift, + _reg_DAM_PPCR(port)); + } + return; +} + +/*! + * This function resets the two registers of the selected port. + * + * @param port the DAM port to reset + */ +void dam_reset_register(dam_port port) +{ + if (port < 3) { + ModifyRegister32(0xFFFFFFFF, dam_hpcr_default_value, + _reg_DAM_HPCR(port)); + } else { + ModifyRegister32(0xFFFFFFFF, dam_ppcr_default_value, + _reg_DAM_PPCR(port)); + } + return; +} + +#ifdef TEST_DAM + +/*! + * This function implements IOCTL controls on a DAM device. + * + * @param inode pointer on the node + * @param file pointer on the file + * @param cmd the command + * @param arg the parameter :\n + * DAM_CONFIG_SSI1:\n + * data from port 1 to port 4, clock and FS from port 1 (SSI1)\n + * DAM_CONFIG_SSI2:\n + * data from port 2 to port 5, clock and FS from port 2 (SSI2)\n + * DAM_CONFIG_SSI_NETWORK_MODE:\n + * network mode for mix digital with data from port 1 to port4,\n + * data from port 2 to port 4, clock and FS from port 1 (SSI1) + * + * @return This function returns 0 if successful. + */ +static int dam_ioctl(struct inode *inode, + struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +/*! + * This function implements the open method on a DAM device. + * + * @param inode pointer on the node + * @param file pointer on the file + * + * @return This function returns 0. + */ +static int dam_open(struct inode *inode, struct file *file) +{ + /* DBG_PRINTK("ssi : dam_open()\n"); */ + return 0; +} + +/*! + * This function implements the release method on a DAM device. + * + * @param inode pointer on the node + * @param file pointer on the file + * + * @return This function returns 0. + */ +static int dam_free(struct inode *inode, struct file *file) +{ + /* DBG_PRINTK("ssi : dam_free()\n"); */ + return 0; +} + +/*! + * This structure defines file operations for a DAM device. + */ +static struct file_operations dam_fops = { + + /*! + * the owner + */ + .owner = THIS_MODULE, + + /*! + * the ioctl operation + */ + .ioctl = dam_ioctl, + + /*! + * the open operation + */ + .open = dam_open, + + /*! + * the release operation + */ + .release = dam_free, +}; + +#endif + +/*! + * This function implements the init function of the DAM device. + * This function is called when the module is loaded. + * + * @return This function returns 0. + */ +static int __init dam_init(void) +{ +#ifdef TEST_DAM + struct class_device *temp_class; + printk(KERN_DEBUG "dam : dam_init(void) \n"); + + major_dam = register_chrdev(0, DAM_NAME, &dam_fops); + if (major_dam < 0) { + printk(KERN_WARNING "Unable to get a major for dam"); + return major_dam; + } + + mxc_dam_class = class_create(THIS_MODULE, DAM_NAME); + if (IS_ERR(mxc_dam_class)) { + goto err_out; + } + + temp_class = class_device_create(mxc_dam_class, NULL, + MKDEV(major_dam, 0), NULL, DAM_NAME); + if (IS_ERR(temp_class)) { + goto err_out; + } +#endif + return 0; + + err_out: + printk(KERN_ERR "Error creating dam class device.\n"); + class_device_destroy(mxc_dam_class, MKDEV(major_dam, 0)); + class_destroy(mxc_dam_class); + unregister_chrdev(major_dam, DAM_NAME); + return -1; +} + +/*! + * This function implements the exit function of the SPI device. + * This function is called when the module is unloaded. + * + */ +static void __exit dam_exit(void) +{ +#ifdef TEST_DAM + class_device_destroy(mxc_dam_class, MKDEV(major_dam, 0)); + class_destroy(mxc_dam_class); + unregister_chrdev(major_dam, DAM_NAME); + printk(KERN_DEBUG "dam : successfully unloaded\n"); +#endif +} + +module_init(dam_init); +module_exit(dam_exit); + +MODULE_DESCRIPTION("DAM char device driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); |