// SPDX-License-Identifier: GPL-2.0
//
// Socionext UniPhier AIO ALSA common driver.
//
// Copyright (c) 2016-2018 Socionext Inc.
#include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "aio.h"
#include "aio-reg.h"
static u64 rb_cnt(u64 wr, u64 rd, u64 len)
{
if (rd <= wr)
return wr - rd;
else
return len - (rd - wr);
}
static u64 rb_cnt_to_end(u64 wr, u64 rd, u64 len)
{
if (rd <= wr)
return wr - rd;
else
return len - rd;
}
static u64 rb_space(u64 wr, u64 rd, u64 len)
{
if (rd <= wr)
return len - (wr - rd) - 8;
else
return rd - wr - 8;
}
static u64 rb_space_to_end(u64 wr, u64 rd, u64 len)
{
if (rd > wr)
return rd - wr - 8;
else if (rd > 0)
return len - wr;
else
return len - wr - 8;
}
u64 aio_rb_cnt(struct uniphier_aio_sub *sub)
{
return rb_cnt(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
}
u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub)
{
return rb_cnt_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
}
u64 aio_rb_space(struct uniphier_aio_sub *sub)
{
return rb_space(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
}
u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub)
{
return rb_space_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
}
/**
* aio_iecout_set_enable - setup IEC output via SoC glue
* @chip: the AIO chip pointer
* @enable: false to stop the output, true to start
*
* Set enabled or disabled S/PDIF signal output to out of SoC via AOnIEC pins.
* This function need to call at driver startup.
*
* The regmap of SoC glue is specified by 'socionext,syscon' optional property
* of DT. This function has no effect if no property.
*/
void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable)
{
struct regmap *r = chip->regmap_sg;
if (!r)
return;
regmap_write(r, SG_AOUTEN, (enable) ? ~0 : 0);
}
/**
* aio_chip_set_pll - set frequency to audio PLL