Skip to content

Commit

Permalink
OMAP: McBSP: Create and export max_(r|t)x_thres property
Browse files Browse the repository at this point in the history
This patch export through sysfs two properties to configure
maximum threshold for transmission and reception on each
mcbsp instance. Also, it exports two helper functions to
allow mcbsp users to read this values.

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>
  • Loading branch information
Eduardo Valentin authored and Mark Brown committed Aug 20, 2009
1 parent 7aa9ff5 commit a1a56f5
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/arm/mach-omap2/mcbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.buffer_size = 0x7F,
},
{
.phys_base = OMAP34XX_MCBSP2_BASE,
Expand All @@ -137,6 +138,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.buffer_size = 0x3FF,
},
{
.phys_base = OMAP34XX_MCBSP3_BASE,
Expand All @@ -145,6 +147,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.buffer_size = 0x7F,
},
{
.phys_base = OMAP34XX_MCBSP4_BASE,
Expand All @@ -153,6 +156,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.buffer_size = 0x7F,
},
{
.phys_base = OMAP34XX_MCBSP5_BASE,
Expand All @@ -161,6 +165,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.buffer_size = 0x7F,
},
};
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/plat-omap/include/mach/mcbsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ struct omap_mcbsp_platform_data {
u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops;
#ifdef CONFIG_ARCH_OMAP34XX
u16 buffer_size;
#endif
};

struct omap_mcbsp {
Expand Down Expand Up @@ -381,6 +384,10 @@ struct omap_mcbsp {
struct omap_mcbsp_platform_data *pdata;
struct clk *iclk;
struct clk *fclk;
#ifdef CONFIG_ARCH_OMAP34XX
u16 max_tx_thres;
u16 max_rx_thres;
#endif
};
extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count;
Expand All @@ -392,11 +399,15 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config
#ifdef CONFIG_ARCH_OMAP34XX
void omap_mcbsp_set_tx_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_rx_threshold(unsigned int id);
#else
static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{ }
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_rx_threshold(unsigned int id) { return 0; }
#endif
int omap_mcbsp_request(unsigned int id);
void omap_mcbsp_free(unsigned int id);
Expand Down
122 changes: 122 additions & 0 deletions arch/arm/plat-omap/mcbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,42 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
}
EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);

/*
* omap_mcbsp_get_max_tx_thres just return the current configured
* maximum threshold for transmission
*/
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
{
struct omap_mcbsp *mcbsp;

if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);

return mcbsp->max_tx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);

/*
* omap_mcbsp_get_max_rx_thres just return the current configured
* maximum threshold for reception
*/
u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
{
struct omap_mcbsp *mcbsp;

if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);

return mcbsp->max_rx_thres;
}
EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
#endif

/*
Expand Down Expand Up @@ -1005,6 +1041,86 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
}
EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);

#ifdef CONFIG_ARCH_OMAP34XX
#define max_thres(m) (mcbsp->pdata->buffer_size)
#define valid_threshold(m, val) ((val) <= max_thres(m))
#define THRESHOLD_PROP_BUILDER(prop) \
static ssize_t prop##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
\
return sprintf(buf, "%u\n", mcbsp->prop); \
} \
\
static ssize_t prop##_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; \
\
if (!valid_threshold(mcbsp, val)) \
return -EDOM; \
\
mcbsp->prop = val; \
return size; \
} \
\
static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);

THRESHOLD_PROP_BUILDER(max_tx_thres);
THRESHOLD_PROP_BUILDER(max_rx_thres);

static const struct attribute *threshold_attrs[] = {
&dev_attr_max_tx_thres.attr,
&dev_attr_max_rx_thres.attr,
NULL,
};

static const struct attribute_group threshold_attr_group = {
.attrs = (struct attribute **)threshold_attrs,
};

static inline int __devinit omap_thres_add(struct device *dev)
{
return sysfs_create_group(&dev->kobj, &threshold_attr_group);
}

static inline void __devexit omap_thres_remove(struct device *dev)
{
sysfs_remove_group(&dev->kobj, &threshold_attr_group);
}

static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
{
if (cpu_is_omap34xx()) {
mcbsp->max_tx_thres = max_thres(mcbsp);
mcbsp->max_rx_thres = max_thres(mcbsp);
if (omap_thres_add(mcbsp->dev))
dev_warn(mcbsp->dev,
"Unable to create threshold controls\n");
} else {
mcbsp->max_tx_thres = -EINVAL;
mcbsp->max_rx_thres = -EINVAL;
}
}

static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
{
if (cpu_is_omap34xx())
omap_thres_remove(mcbsp->dev);
}
#else
static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
#endif /* CONFIG_ARCH_OMAP34XX */

/*
* McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
* 730 has only 2 McBSP, and both of them are MPU peripherals.
Expand Down Expand Up @@ -1075,6 +1191,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
mcbsp->dev = &pdev->dev;
mcbsp_ptr[id] = mcbsp;
platform_set_drvdata(pdev, mcbsp);

/* Initialize mcbsp properties for OMAP34XX if needed / applicable */
omap34xx_device_init(mcbsp);

return 0;

err_fclk:
Expand All @@ -1098,6 +1218,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id);

omap34xx_device_exit(mcbsp);

clk_disable(mcbsp->fclk);
clk_disable(mcbsp->iclk);
clk_put(mcbsp->fclk);
Expand Down

0 comments on commit a1a56f5

Please sign in to comment.