OMAP: McBSP: Add link DMA mode selection
It adds a new sysfs file, where the user can configure the mcbsp mode to use. If the mcbsp channel is in use, it does not allow the change. Than in omap_pcm_open we can call the omap_mcbsp_get_opmode to get the mode, store it, than use it to implement the different modes. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
4c8200aeb0
commit
98cb20e889
@ -255,6 +255,11 @@
|
|||||||
/********************** McBSP SYSCONFIG bit definitions ********************/
|
/********************** McBSP SYSCONFIG bit definitions ********************/
|
||||||
#define SOFTRST 0x0002
|
#define SOFTRST 0x0002
|
||||||
|
|
||||||
|
/********************** McBSP DMA operating modes **************************/
|
||||||
|
#define MCBSP_DMA_MODE_ELEMENT 0
|
||||||
|
#define MCBSP_DMA_MODE_THRESHOLD 1
|
||||||
|
#define MCBSP_DMA_MODE_FRAME 2
|
||||||
|
|
||||||
/* we don't do multichannel for now */
|
/* we don't do multichannel for now */
|
||||||
struct omap_mcbsp_reg_cfg {
|
struct omap_mcbsp_reg_cfg {
|
||||||
u16 spcr2;
|
u16 spcr2;
|
||||||
@ -385,6 +390,7 @@ struct omap_mcbsp {
|
|||||||
struct clk *iclk;
|
struct clk *iclk;
|
||||||
struct clk *fclk;
|
struct clk *fclk;
|
||||||
#ifdef CONFIG_ARCH_OMAP34XX
|
#ifdef CONFIG_ARCH_OMAP34XX
|
||||||
|
int dma_op_mode;
|
||||||
u16 max_tx_thres;
|
u16 max_tx_thres;
|
||||||
u16 max_rx_thres;
|
u16 max_rx_thres;
|
||||||
#endif
|
#endif
|
||||||
@ -401,6 +407,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
|
|||||||
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
|
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
|
||||||
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
|
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
|
||||||
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
|
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
|
||||||
|
int omap_mcbsp_get_dma_op_mode(unsigned int id);
|
||||||
#else
|
#else
|
||||||
static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
|
static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
|
||||||
{ }
|
{ }
|
||||||
@ -408,6 +415,7 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
|
|||||||
{ }
|
{ }
|
||||||
static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
|
static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
|
||||||
static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
|
static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
|
||||||
|
static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
int omap_mcbsp_request(unsigned int id);
|
int omap_mcbsp_request(unsigned int id);
|
||||||
void omap_mcbsp_free(unsigned int id);
|
void omap_mcbsp_free(unsigned int id);
|
||||||
|
@ -282,6 +282,29 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
|
|||||||
return mcbsp->max_rx_thres;
|
return mcbsp->max_rx_thres;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
|
EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* omap_mcbsp_get_dma_op_mode just return the current configured
|
||||||
|
* operating mode for the mcbsp channel
|
||||||
|
*/
|
||||||
|
int omap_mcbsp_get_dma_op_mode(unsigned int id)
|
||||||
|
{
|
||||||
|
struct omap_mcbsp *mcbsp;
|
||||||
|
int dma_op_mode;
|
||||||
|
|
||||||
|
if (!omap_mcbsp_check_valid_id(id)) {
|
||||||
|
printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
mcbsp = id_to_mcbsp_ptr(id);
|
||||||
|
|
||||||
|
spin_lock_irq(&mcbsp->lock);
|
||||||
|
dma_op_mode = mcbsp->dma_op_mode;
|
||||||
|
spin_unlock_irq(&mcbsp->lock);
|
||||||
|
|
||||||
|
return dma_op_mode;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1077,9 +1100,65 @@ static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
|
|||||||
THRESHOLD_PROP_BUILDER(max_tx_thres);
|
THRESHOLD_PROP_BUILDER(max_tx_thres);
|
||||||
THRESHOLD_PROP_BUILDER(max_rx_thres);
|
THRESHOLD_PROP_BUILDER(max_rx_thres);
|
||||||
|
|
||||||
|
static ssize_t dma_op_mode_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
|
||||||
|
int dma_op_mode;
|
||||||
|
|
||||||
|
spin_lock_irq(&mcbsp->lock);
|
||||||
|
dma_op_mode = mcbsp->dma_op_mode;
|
||||||
|
spin_unlock_irq(&mcbsp->lock);
|
||||||
|
|
||||||
|
return sprintf(buf, "current mode: %d\n"
|
||||||
|
"possible mode values are:\n"
|
||||||
|
"%d - %s\n"
|
||||||
|
"%d - %s\n"
|
||||||
|
"%d - %s\n",
|
||||||
|
dma_op_mode,
|
||||||
|
MCBSP_DMA_MODE_ELEMENT, "element mode",
|
||||||
|
MCBSP_DMA_MODE_THRESHOLD, "threshold mode",
|
||||||
|
MCBSP_DMA_MODE_FRAME, "frame mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t dma_op_mode_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t size)
|
||||||
|
{
|
||||||
|
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
|
||||||
|
unsigned long val;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = strict_strtoul(buf, 0, &val);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
spin_lock_irq(&mcbsp->lock);
|
||||||
|
|
||||||
|
if (!mcbsp->free) {
|
||||||
|
size = -EBUSY;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val > MCBSP_DMA_MODE_FRAME || val < MCBSP_DMA_MODE_ELEMENT) {
|
||||||
|
size = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
mcbsp->dma_op_mode = val;
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
spin_unlock_irq(&mcbsp->lock);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
|
||||||
|
|
||||||
static const struct attribute *additional_attrs[] = {
|
static const struct attribute *additional_attrs[] = {
|
||||||
&dev_attr_max_tx_thres.attr,
|
&dev_attr_max_tx_thres.attr,
|
||||||
&dev_attr_max_rx_thres.attr,
|
&dev_attr_max_rx_thres.attr,
|
||||||
|
&dev_attr_dma_op_mode.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1099,9 +1178,14 @@ static inline void __devexit omap_additional_remove(struct device *dev)
|
|||||||
|
|
||||||
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
|
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
|
||||||
{
|
{
|
||||||
|
mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
|
||||||
if (cpu_is_omap34xx()) {
|
if (cpu_is_omap34xx()) {
|
||||||
mcbsp->max_tx_thres = max_thres(mcbsp);
|
mcbsp->max_tx_thres = max_thres(mcbsp);
|
||||||
mcbsp->max_rx_thres = max_thres(mcbsp);
|
mcbsp->max_rx_thres = max_thres(mcbsp);
|
||||||
|
/*
|
||||||
|
* REVISIT: Set dmap_op_mode to THRESHOLD as default
|
||||||
|
* for mcbsp2 instances.
|
||||||
|
*/
|
||||||
if (omap_additional_add(mcbsp->dev))
|
if (omap_additional_add(mcbsp->dev))
|
||||||
dev_warn(mcbsp->dev,
|
dev_warn(mcbsp->dev,
|
||||||
"Unable to create additional controls\n");
|
"Unable to create additional controls\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user