Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98cb20e8 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown
Browse files

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: default avatarPeter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: default avatarEduardo Valentin <eduardo.valentin@nokia.com>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 4c8200ae
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -255,6 +255,11 @@
/********************** McBSP SYSCONFIG bit definitions ********************/
#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 */
struct omap_mcbsp_reg_cfg {
	u16 spcr2;
@@ -385,6 +390,7 @@ struct omap_mcbsp {
	struct clk *iclk;
	struct clk *fclk;
#ifdef CONFIG_ARCH_OMAP34XX
	int dma_op_mode;
	u16 max_tx_thres;
	u16 max_rx_thres;
#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);
u16 omap_mcbsp_get_max_tx_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
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_rx_threshold(unsigned int id) { return 0; }
static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
#endif
int omap_mcbsp_request(unsigned int id);
void omap_mcbsp_free(unsigned int id);
+84 −0
Original line number Diff line number Diff line
@@ -282,6 +282,29 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
	return mcbsp->max_rx_thres;
}
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

/*
@@ -1077,9 +1100,65 @@ static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
THRESHOLD_PROP_BUILDER(max_tx_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[] = {
	&dev_attr_max_tx_thres.attr,
	&dev_attr_max_rx_thres.attr,
	&dev_attr_dma_op_mode.attr,
	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)
{
	mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
	if (cpu_is_omap34xx()) {
		mcbsp->max_tx_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))
			dev_warn(mcbsp->dev,
				"Unable to create additional controls\n");