Merge remote-tracking branches 'asoc/topic/rcar', 'asoc/topic/reg-default', 'asoc/topic/rl6231', 'asoc/topic/rockchip' and 'asoc/topic/rt286' into asoc-next
This commit is contained in:
commit
532161e6cc
|
@ -18,6 +18,12 @@ Required properties:
|
||||||
- rcar_sound,src : Should contain SRC feature.
|
- rcar_sound,src : Should contain SRC feature.
|
||||||
The number of SRC subnode should be same as HW.
|
The number of SRC subnode should be same as HW.
|
||||||
see below for detail.
|
see below for detail.
|
||||||
|
- rcar_sound,ctu : Should contain CTU feature.
|
||||||
|
The number of CTU subnode should be same as HW.
|
||||||
|
see below for detail.
|
||||||
|
- rcar_sound,mix : Should contain MIX feature.
|
||||||
|
The number of MIX subnode should be same as HW.
|
||||||
|
see below for detail.
|
||||||
- rcar_sound,dvc : Should contain DVC feature.
|
- rcar_sound,dvc : Should contain DVC feature.
|
||||||
The number of DVC subnode should be same as HW.
|
The number of DVC subnode should be same as HW.
|
||||||
see below for detail.
|
see below for detail.
|
||||||
|
@ -90,6 +96,22 @@ rcar_sound: sound@ec500000 {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rcar_sound,mix {
|
||||||
|
mix0: mix@0 { };
|
||||||
|
mix1: mix@1 { };
|
||||||
|
};
|
||||||
|
|
||||||
|
rcar_sound,ctu {
|
||||||
|
ctu00: ctu@0 { };
|
||||||
|
ctu01: ctu@1 { };
|
||||||
|
ctu02: ctu@2 { };
|
||||||
|
ctu03: ctu@3 { };
|
||||||
|
ctu10: ctu@4 { };
|
||||||
|
ctu11: ctu@5 { };
|
||||||
|
ctu12: ctu@6 { };
|
||||||
|
ctu13: ctu@7 { };
|
||||||
|
};
|
||||||
|
|
||||||
rcar_sound,src {
|
rcar_sound,src {
|
||||||
src0: src@0 {
|
src0: src@0 {
|
||||||
interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
|
@ -6,6 +6,7 @@ Required properties:
|
||||||
|
|
||||||
- compatible : "renesas,rsrc-card,<board>"
|
- compatible : "renesas,rsrc-card,<board>"
|
||||||
Examples with soctypes are:
|
Examples with soctypes are:
|
||||||
|
- "renesas,rsrc-card"
|
||||||
- "renesas,rsrc-card,lager"
|
- "renesas,rsrc-card,lager"
|
||||||
- "renesas,rsrc-card,koelsch"
|
- "renesas,rsrc-card,koelsch"
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
@ -29,6 +30,12 @@ Optional subnode properties:
|
||||||
- frame-inversion : bool property. Add this if the
|
- frame-inversion : bool property. Add this if the
|
||||||
dai-link uses frame clock inversion.
|
dai-link uses frame clock inversion.
|
||||||
- convert-rate : platform specified sampling rate convert
|
- convert-rate : platform specified sampling rate convert
|
||||||
|
- audio-prefix : see audio-routing
|
||||||
|
- audio-routing : A list of the connections between audio components.
|
||||||
|
Each entry is a pair of strings, the first being the connection's sink,
|
||||||
|
the second being the connection's source. Valid names for sources.
|
||||||
|
use audio-prefix if some components is using same sink/sources naming.
|
||||||
|
it can be used if compatible was "renesas,rsrc-card";
|
||||||
|
|
||||||
Required CPU/CODEC subnodes properties:
|
Required CPU/CODEC subnodes properties:
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ struct regmap {
|
||||||
/* if set, the HW registers are known to match map->reg_defaults */
|
/* if set, the HW registers are known to match map->reg_defaults */
|
||||||
bool no_sync_defaults;
|
bool no_sync_defaults;
|
||||||
|
|
||||||
struct reg_default *patch;
|
struct reg_sequence *patch;
|
||||||
int patch_regs;
|
int patch_regs;
|
||||||
|
|
||||||
/* if set, converts bulk rw to single rw */
|
/* if set, converts bulk rw to single rw */
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
unsigned int mask, unsigned int val,
|
unsigned int mask, unsigned int val,
|
||||||
bool *change);
|
bool *change, bool force_write);
|
||||||
|
|
||||||
static int _regmap_bus_reg_read(void *context, unsigned int reg,
|
static int _regmap_bus_reg_read(void *context, unsigned int reg,
|
||||||
unsigned int *val);
|
unsigned int *val);
|
||||||
|
@ -1178,7 +1178,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
|
||||||
ret = _regmap_update_bits(map, range->selector_reg,
|
ret = _regmap_update_bits(map, range->selector_reg,
|
||||||
range->selector_mask,
|
range->selector_mask,
|
||||||
win_page << range->selector_shift,
|
win_page << range->selector_shift,
|
||||||
&page_chg);
|
&page_chg, false);
|
||||||
|
|
||||||
map->work_buf = orig_work_buf;
|
map->work_buf = orig_work_buf;
|
||||||
|
|
||||||
|
@ -1624,6 +1624,18 @@ int regmap_fields_write(struct regmap_field *field, unsigned int id,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regmap_fields_write);
|
EXPORT_SYMBOL_GPL(regmap_fields_write);
|
||||||
|
|
||||||
|
int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
|
||||||
|
unsigned int val)
|
||||||
|
{
|
||||||
|
if (id >= field->id_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return regmap_write_bits(field->regmap,
|
||||||
|
field->reg + (field->id_offset * id),
|
||||||
|
field->mask, val << field->shift);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(regmap_fields_force_write);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regmap_fields_update_bits(): Perform a read/modify/write cycle
|
* regmap_fields_update_bits(): Perform a read/modify/write cycle
|
||||||
* on the register field
|
* on the register field
|
||||||
|
@ -1743,7 +1755,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write);
|
||||||
* relative. The page register has been written if that was neccessary.
|
* relative. The page register has been written if that was neccessary.
|
||||||
*/
|
*/
|
||||||
static int _regmap_raw_multi_reg_write(struct regmap *map,
|
static int _regmap_raw_multi_reg_write(struct regmap *map,
|
||||||
const struct reg_default *regs,
|
const struct reg_sequence *regs,
|
||||||
size_t num_regs)
|
size_t num_regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1800,12 +1812,12 @@ static unsigned int _regmap_register_page(struct regmap *map,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
||||||
struct reg_default *regs,
|
struct reg_sequence *regs,
|
||||||
size_t num_regs)
|
size_t num_regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int i, n;
|
int i, n;
|
||||||
struct reg_default *base;
|
struct reg_sequence *base;
|
||||||
unsigned int this_page = 0;
|
unsigned int this_page = 0;
|
||||||
/*
|
/*
|
||||||
* the set of registers are not neccessarily in order, but
|
* the set of registers are not neccessarily in order, but
|
||||||
|
@ -1843,7 +1855,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _regmap_multi_reg_write(struct regmap *map,
|
static int _regmap_multi_reg_write(struct regmap *map,
|
||||||
const struct reg_default *regs,
|
const struct reg_sequence *regs,
|
||||||
size_t num_regs)
|
size_t num_regs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1895,8 +1907,8 @@ static int _regmap_multi_reg_write(struct regmap *map,
|
||||||
struct regmap_range_node *range;
|
struct regmap_range_node *range;
|
||||||
range = _regmap_range_lookup(map, reg);
|
range = _regmap_range_lookup(map, reg);
|
||||||
if (range) {
|
if (range) {
|
||||||
size_t len = sizeof(struct reg_default)*num_regs;
|
size_t len = sizeof(struct reg_sequence)*num_regs;
|
||||||
struct reg_default *base = kmemdup(regs, len,
|
struct reg_sequence *base = kmemdup(regs, len,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!base)
|
if (!base)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1929,7 +1941,7 @@ static int _regmap_multi_reg_write(struct regmap *map,
|
||||||
* A value of zero will be returned on success, a negative errno will be
|
* A value of zero will be returned on success, a negative errno will be
|
||||||
* returned in error cases.
|
* returned in error cases.
|
||||||
*/
|
*/
|
||||||
int regmap_multi_reg_write(struct regmap *map, const struct reg_default *regs,
|
int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
|
||||||
int num_regs)
|
int num_regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1962,7 +1974,7 @@ EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
|
||||||
* be returned in error cases.
|
* be returned in error cases.
|
||||||
*/
|
*/
|
||||||
int regmap_multi_reg_write_bypassed(struct regmap *map,
|
int regmap_multi_reg_write_bypassed(struct regmap *map,
|
||||||
const struct reg_default *regs,
|
const struct reg_sequence *regs,
|
||||||
int num_regs)
|
int num_regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2327,7 +2339,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_read);
|
||||||
|
|
||||||
static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
unsigned int mask, unsigned int val,
|
unsigned int mask, unsigned int val,
|
||||||
bool *change)
|
bool *change, bool force_write)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int tmp, orig;
|
unsigned int tmp, orig;
|
||||||
|
@ -2339,7 +2351,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
tmp = orig & ~mask;
|
tmp = orig & ~mask;
|
||||||
tmp |= val & mask;
|
tmp |= val & mask;
|
||||||
|
|
||||||
if (tmp != orig) {
|
if (force_write || (tmp != orig)) {
|
||||||
ret = _regmap_write(map, reg, tmp);
|
ret = _regmap_write(map, reg, tmp);
|
||||||
if (change)
|
if (change)
|
||||||
*change = true;
|
*change = true;
|
||||||
|
@ -2367,13 +2379,36 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
map->lock(map->lock_arg);
|
map->lock(map->lock_arg);
|
||||||
ret = _regmap_update_bits(map, reg, mask, val, NULL);
|
ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
|
||||||
map->unlock(map->lock_arg);
|
map->unlock(map->lock_arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regmap_update_bits);
|
EXPORT_SYMBOL_GPL(regmap_update_bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regmap_write_bits: Perform a read/modify/write cycle on the register map
|
||||||
|
*
|
||||||
|
* @map: Register map to update
|
||||||
|
* @reg: Register to update
|
||||||
|
* @mask: Bitmask to change
|
||||||
|
* @val: New value for bitmask
|
||||||
|
*
|
||||||
|
* Returns zero for success, a negative number on error.
|
||||||
|
*/
|
||||||
|
int regmap_write_bits(struct regmap *map, unsigned int reg,
|
||||||
|
unsigned int mask, unsigned int val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
map->lock(map->lock_arg);
|
||||||
|
ret = _regmap_update_bits(map, reg, mask, val, NULL, true);
|
||||||
|
map->unlock(map->lock_arg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(regmap_write_bits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regmap_update_bits_async: Perform a read/modify/write cycle on the register
|
* regmap_update_bits_async: Perform a read/modify/write cycle on the register
|
||||||
* map asynchronously
|
* map asynchronously
|
||||||
|
@ -2398,7 +2433,7 @@ int regmap_update_bits_async(struct regmap *map, unsigned int reg,
|
||||||
|
|
||||||
map->async = true;
|
map->async = true;
|
||||||
|
|
||||||
ret = _regmap_update_bits(map, reg, mask, val, NULL);
|
ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
|
||||||
|
|
||||||
map->async = false;
|
map->async = false;
|
||||||
|
|
||||||
|
@ -2427,7 +2462,7 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
map->lock(map->lock_arg);
|
map->lock(map->lock_arg);
|
||||||
ret = _regmap_update_bits(map, reg, mask, val, change);
|
ret = _regmap_update_bits(map, reg, mask, val, change, false);
|
||||||
map->unlock(map->lock_arg);
|
map->unlock(map->lock_arg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2460,7 +2495,7 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg,
|
||||||
|
|
||||||
map->async = true;
|
map->async = true;
|
||||||
|
|
||||||
ret = _regmap_update_bits(map, reg, mask, val, change);
|
ret = _regmap_update_bits(map, reg, mask, val, change, false);
|
||||||
|
|
||||||
map->async = false;
|
map->async = false;
|
||||||
|
|
||||||
|
@ -2552,10 +2587,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
|
||||||
* The caller must ensure that this function cannot be called
|
* The caller must ensure that this function cannot be called
|
||||||
* concurrently with either itself or regcache_sync().
|
* concurrently with either itself or regcache_sync().
|
||||||
*/
|
*/
|
||||||
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
|
int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs,
|
||||||
int num_regs)
|
int num_regs)
|
||||||
{
|
{
|
||||||
struct reg_default *p;
|
struct reg_sequence *p;
|
||||||
int ret;
|
int ret;
|
||||||
bool bypass;
|
bool bypass;
|
||||||
|
|
||||||
|
@ -2564,7 +2599,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
p = krealloc(map->patch,
|
p = krealloc(map->patch,
|
||||||
sizeof(struct reg_default) * (map->patch_regs + num_regs),
|
sizeof(struct reg_sequence) * (map->patch_regs + num_regs),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (p) {
|
if (p) {
|
||||||
memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
|
memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
|
||||||
|
|
|
@ -54,7 +54,7 @@ static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADI recommended values for proper operation. */
|
/* ADI recommended values for proper operation. */
|
||||||
static const struct reg_default adv7511_fixed_registers[] = {
|
static const struct reg_sequence adv7511_fixed_registers[] = {
|
||||||
{ 0x98, 0x03 },
|
{ 0x98, 0x03 },
|
||||||
{ 0x9a, 0xe0 },
|
{ 0x9a, 0xe0 },
|
||||||
{ 0x9c, 0x30 },
|
{ 0x9c, 0x30 },
|
||||||
|
|
|
@ -313,14 +313,14 @@ static void drv260x_close(struct input_dev *input)
|
||||||
gpiod_set_value(haptics->enable_gpio, 0);
|
gpiod_set_value(haptics->enable_gpio, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct reg_default drv260x_lra_cal_regs[] = {
|
static const struct reg_sequence drv260x_lra_cal_regs[] = {
|
||||||
{ DRV260X_MODE, DRV260X_AUTO_CAL },
|
{ DRV260X_MODE, DRV260X_AUTO_CAL },
|
||||||
{ DRV260X_CTRL3, DRV260X_NG_THRESH_2 },
|
{ DRV260X_CTRL3, DRV260X_NG_THRESH_2 },
|
||||||
{ DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE |
|
{ DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE |
|
||||||
DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH },
|
DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default drv260x_lra_init_regs[] = {
|
static const struct reg_sequence drv260x_lra_init_regs[] = {
|
||||||
{ DRV260X_MODE, DRV260X_RT_PLAYBACK },
|
{ DRV260X_MODE, DRV260X_RT_PLAYBACK },
|
||||||
{ DRV260X_A_TO_V_CTRL, DRV260X_AUDIO_HAPTICS_PEAK_20MS |
|
{ DRV260X_A_TO_V_CTRL, DRV260X_AUDIO_HAPTICS_PEAK_20MS |
|
||||||
DRV260X_AUDIO_HAPTICS_FILTER_125HZ },
|
DRV260X_AUDIO_HAPTICS_FILTER_125HZ },
|
||||||
|
@ -337,7 +337,7 @@ static const struct reg_default drv260x_lra_init_regs[] = {
|
||||||
{ DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
|
{ DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default drv260x_erm_cal_regs[] = {
|
static const struct reg_sequence drv260x_erm_cal_regs[] = {
|
||||||
{ DRV260X_MODE, DRV260X_AUTO_CAL },
|
{ DRV260X_MODE, DRV260X_AUTO_CAL },
|
||||||
{ DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
|
{ DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
|
||||||
{ DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
|
{ DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
|
||||||
|
|
|
@ -132,7 +132,7 @@ static void drv2665_close(struct input_dev *input)
|
||||||
"Failed to enter standby mode: %d\n", error);
|
"Failed to enter standby mode: %d\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct reg_default drv2665_init_regs[] = {
|
static const struct reg_sequence drv2665_init_regs[] = {
|
||||||
{ DRV2665_CTRL_2, 0 | DRV2665_10_MS_IDLE_TOUT },
|
{ DRV2665_CTRL_2, 0 | DRV2665_10_MS_IDLE_TOUT },
|
||||||
{ DRV2665_CTRL_1, DRV2665_25_VPP_GAIN },
|
{ DRV2665_CTRL_1, DRV2665_25_VPP_GAIN },
|
||||||
};
|
};
|
||||||
|
|
|
@ -262,14 +262,14 @@ static void drv2667_close(struct input_dev *input)
|
||||||
"Failed to enter standby mode: %d\n", error);
|
"Failed to enter standby mode: %d\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct reg_default drv2667_init_regs[] = {
|
static const struct reg_sequence drv2667_init_regs[] = {
|
||||||
{ DRV2667_CTRL_2, 0 },
|
{ DRV2667_CTRL_2, 0 },
|
||||||
{ DRV2667_CTRL_1, DRV2667_25_VPP_GAIN },
|
{ DRV2667_CTRL_1, DRV2667_25_VPP_GAIN },
|
||||||
{ DRV2667_WV_SEQ_0, 1 },
|
{ DRV2667_WV_SEQ_0, 1 },
|
||||||
{ DRV2667_WV_SEQ_1, 0 }
|
{ DRV2667_WV_SEQ_1, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default drv2667_page1_init[] = {
|
static const struct reg_sequence drv2667_page1_init[] = {
|
||||||
{ DRV2667_RAM_HDR_SZ, 0x05 },
|
{ DRV2667_RAM_HDR_SZ, 0x05 },
|
||||||
{ DRV2667_RAM_START_HI, 0x80 },
|
{ DRV2667_RAM_START_HI, 0x80 },
|
||||||
{ DRV2667_RAM_START_LO, 0x06 },
|
{ DRV2667_RAM_START_LO, 0x06 },
|
||||||
|
|
|
@ -392,7 +392,7 @@ err:
|
||||||
* Register patch to some of the CODECs internal write sequences
|
* Register patch to some of the CODECs internal write sequences
|
||||||
* to ensure a clean exit from the low power sleep state.
|
* to ensure a clean exit from the low power sleep state.
|
||||||
*/
|
*/
|
||||||
static const struct reg_default wm5110_sleep_patch[] = {
|
static const struct reg_sequence wm5110_sleep_patch[] = {
|
||||||
{ 0x337A, 0xC100 },
|
{ 0x337A, 0xC100 },
|
||||||
{ 0x337B, 0x0041 },
|
{ 0x337B, 0x0041 },
|
||||||
{ 0x3300, 0xA210 },
|
{ 0x3300, 0xA210 },
|
||||||
|
|
|
@ -86,7 +86,7 @@ static const struct reg_default twl6040_defaults[] = {
|
||||||
{ 0x2E, 0x00 }, /* REG_STATUS (ro) */
|
{ 0x2E, 0x00 }, /* REG_STATUS (ro) */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct reg_default twl6040_patch[] = {
|
static struct reg_sequence twl6040_patch[] = {
|
||||||
/*
|
/*
|
||||||
* Select I2C bus access to dual access registers
|
* Select I2C bus access to dual access registers
|
||||||
* Interrupt register is cleared on read
|
* Interrupt register is cleared on read
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define WM5102_NUM_AOD_ISR 2
|
#define WM5102_NUM_AOD_ISR 2
|
||||||
#define WM5102_NUM_ISR 5
|
#define WM5102_NUM_ISR 5
|
||||||
|
|
||||||
static const struct reg_default wm5102_reva_patch[] = {
|
static const struct reg_sequence wm5102_reva_patch[] = {
|
||||||
{ 0x80, 0x0003 },
|
{ 0x80, 0x0003 },
|
||||||
{ 0x221, 0x0090 },
|
{ 0x221, 0x0090 },
|
||||||
{ 0x211, 0x0014 },
|
{ 0x211, 0x0014 },
|
||||||
|
@ -57,7 +57,7 @@ static const struct reg_default wm5102_reva_patch[] = {
|
||||||
{ 0x80, 0x0000 },
|
{ 0x80, 0x0000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm5102_revb_patch[] = {
|
static const struct reg_sequence wm5102_revb_patch[] = {
|
||||||
{ 0x19, 0x0001 },
|
{ 0x19, 0x0001 },
|
||||||
{ 0x80, 0x0003 },
|
{ 0x80, 0x0003 },
|
||||||
{ 0x081, 0xE022 },
|
{ 0x081, 0xE022 },
|
||||||
|
@ -80,7 +80,7 @@ static const struct reg_default wm5102_revb_patch[] = {
|
||||||
/* We use a function so we can use ARRAY_SIZE() */
|
/* We use a function so we can use ARRAY_SIZE() */
|
||||||
int wm5102_patch(struct arizona *arizona)
|
int wm5102_patch(struct arizona *arizona)
|
||||||
{
|
{
|
||||||
const struct reg_default *wm5102_patch;
|
const struct reg_sequence *wm5102_patch;
|
||||||
int patch_size;
|
int patch_size;
|
||||||
|
|
||||||
switch (arizona->rev) {
|
switch (arizona->rev) {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define WM5110_NUM_AOD_ISR 2
|
#define WM5110_NUM_AOD_ISR 2
|
||||||
#define WM5110_NUM_ISR 5
|
#define WM5110_NUM_ISR 5
|
||||||
|
|
||||||
static const struct reg_default wm5110_reva_patch[] = {
|
static const struct reg_sequence wm5110_reva_patch[] = {
|
||||||
{ 0x80, 0x3 },
|
{ 0x80, 0x3 },
|
||||||
{ 0x44, 0x20 },
|
{ 0x44, 0x20 },
|
||||||
{ 0x45, 0x40 },
|
{ 0x45, 0x40 },
|
||||||
|
@ -134,7 +134,7 @@ static const struct reg_default wm5110_reva_patch[] = {
|
||||||
{ 0x209, 0x002A },
|
{ 0x209, 0x002A },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm5110_revb_patch[] = {
|
static const struct reg_sequence wm5110_revb_patch[] = {
|
||||||
{ 0x80, 0x3 },
|
{ 0x80, 0x3 },
|
||||||
{ 0x36e, 0x0210 },
|
{ 0x36e, 0x0210 },
|
||||||
{ 0x370, 0x0210 },
|
{ 0x370, 0x0210 },
|
||||||
|
@ -224,7 +224,7 @@ static const struct reg_default wm5110_revb_patch[] = {
|
||||||
{ 0x80, 0x0 },
|
{ 0x80, 0x0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm5110_revd_patch[] = {
|
static const struct reg_sequence wm5110_revd_patch[] = {
|
||||||
{ 0x80, 0x3 },
|
{ 0x80, 0x3 },
|
||||||
{ 0x80, 0x3 },
|
{ 0x80, 0x3 },
|
||||||
{ 0x393, 0x27 },
|
{ 0x393, 0x27 },
|
||||||
|
|
|
@ -243,21 +243,21 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct reg_default wm8994_revc_patch[] = {
|
static const struct reg_sequence wm8994_revc_patch[] = {
|
||||||
{ 0x102, 0x3 },
|
{ 0x102, 0x3 },
|
||||||
{ 0x56, 0x3 },
|
{ 0x56, 0x3 },
|
||||||
{ 0x817, 0x0 },
|
{ 0x817, 0x0 },
|
||||||
{ 0x102, 0x0 },
|
{ 0x102, 0x0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm8958_reva_patch[] = {
|
static const struct reg_sequence wm8958_reva_patch[] = {
|
||||||
{ 0x102, 0x3 },
|
{ 0x102, 0x3 },
|
||||||
{ 0xcb, 0x81 },
|
{ 0xcb, 0x81 },
|
||||||
{ 0x817, 0x0 },
|
{ 0x817, 0x0 },
|
||||||
{ 0x102, 0x0 },
|
{ 0x102, 0x0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm1811_reva_patch[] = {
|
static const struct reg_sequence wm1811_reva_patch[] = {
|
||||||
{ 0x102, 0x3 },
|
{ 0x102, 0x3 },
|
||||||
{ 0x56, 0xc07 },
|
{ 0x56, 0xc07 },
|
||||||
{ 0x5d, 0x7e },
|
{ 0x5d, 0x7e },
|
||||||
|
@ -326,7 +326,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
||||||
{
|
{
|
||||||
struct wm8994_pdata *pdata;
|
struct wm8994_pdata *pdata;
|
||||||
struct regmap_config *regmap_config;
|
struct regmap_config *regmap_config;
|
||||||
const struct reg_default *regmap_patch = NULL;
|
const struct reg_sequence *regmap_patch = NULL;
|
||||||
const char *devname;
|
const char *devname;
|
||||||
int ret, i, patch_regs = 0;
|
int ret, i, patch_regs = 0;
|
||||||
int pulls = 0;
|
int pulls = 0;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "arizona.h"
|
#include "arizona.h"
|
||||||
|
|
||||||
static const struct reg_default wm8997_reva_patch[] = {
|
static const struct reg_sequence wm8997_reva_patch[] = {
|
||||||
{ 0x80, 0x0003 },
|
{ 0x80, 0x0003 },
|
||||||
{ 0x214, 0x0008 },
|
{ 0x214, 0x0008 },
|
||||||
{ 0x458, 0x0000 },
|
{ 0x458, 0x0000 },
|
||||||
|
|
|
@ -50,6 +50,17 @@ struct reg_default {
|
||||||
unsigned int def;
|
unsigned int def;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register/value pairs for sequences of writes
|
||||||
|
*
|
||||||
|
* @reg: Register address.
|
||||||
|
* @def: Register value.
|
||||||
|
*/
|
||||||
|
struct reg_sequence {
|
||||||
|
unsigned int reg;
|
||||||
|
unsigned int def;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_REGMAP
|
#ifdef CONFIG_REGMAP
|
||||||
|
|
||||||
enum regmap_endian {
|
enum regmap_endian {
|
||||||
|
@ -410,10 +421,10 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
|
||||||
const void *val, size_t val_len);
|
const void *val, size_t val_len);
|
||||||
int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
|
int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
|
||||||
size_t val_count);
|
size_t val_count);
|
||||||
int regmap_multi_reg_write(struct regmap *map, const struct reg_default *regs,
|
int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
|
||||||
int num_regs);
|
int num_regs);
|
||||||
int regmap_multi_reg_write_bypassed(struct regmap *map,
|
int regmap_multi_reg_write_bypassed(struct regmap *map,
|
||||||
const struct reg_default *regs,
|
const struct reg_sequence *regs,
|
||||||
int num_regs);
|
int num_regs);
|
||||||
int regmap_raw_write_async(struct regmap *map, unsigned int reg,
|
int regmap_raw_write_async(struct regmap *map, unsigned int reg,
|
||||||
const void *val, size_t val_len);
|
const void *val, size_t val_len);
|
||||||
|
@ -424,6 +435,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
|
||||||
size_t val_count);
|
size_t val_count);
|
||||||
int regmap_update_bits(struct regmap *map, unsigned int reg,
|
int regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
unsigned int mask, unsigned int val);
|
unsigned int mask, unsigned int val);
|
||||||
|
int regmap_write_bits(struct regmap *map, unsigned int reg,
|
||||||
|
unsigned int mask, unsigned int val);
|
||||||
int regmap_update_bits_async(struct regmap *map, unsigned int reg,
|
int regmap_update_bits_async(struct regmap *map, unsigned int reg,
|
||||||
unsigned int mask, unsigned int val);
|
unsigned int mask, unsigned int val);
|
||||||
int regmap_update_bits_check(struct regmap *map, unsigned int reg,
|
int regmap_update_bits_check(struct regmap *map, unsigned int reg,
|
||||||
|
@ -450,7 +463,7 @@ void regcache_mark_dirty(struct regmap *map);
|
||||||
bool regmap_check_range_table(struct regmap *map, unsigned int reg,
|
bool regmap_check_range_table(struct regmap *map, unsigned int reg,
|
||||||
const struct regmap_access_table *table);
|
const struct regmap_access_table *table);
|
||||||
|
|
||||||
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
|
int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs,
|
||||||
int num_regs);
|
int num_regs);
|
||||||
int regmap_parse_val(struct regmap *map, const void *buf,
|
int regmap_parse_val(struct regmap *map, const void *buf,
|
||||||
unsigned int *val);
|
unsigned int *val);
|
||||||
|
@ -503,6 +516,8 @@ int regmap_field_update_bits(struct regmap_field *field,
|
||||||
|
|
||||||
int regmap_fields_write(struct regmap_field *field, unsigned int id,
|
int regmap_fields_write(struct regmap_field *field, unsigned int id,
|
||||||
unsigned int val);
|
unsigned int val);
|
||||||
|
int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
|
||||||
|
unsigned int val);
|
||||||
int regmap_fields_read(struct regmap_field *field, unsigned int id,
|
int regmap_fields_read(struct regmap_field *field, unsigned int id,
|
||||||
unsigned int *val);
|
unsigned int *val);
|
||||||
int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
|
int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
|
||||||
|
@ -645,6 +660,13 @@ static inline int regmap_update_bits(struct regmap *map, unsigned int reg,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int regmap_write_bits(struct regmap *map, unsigned int reg,
|
||||||
|
unsigned int mask, unsigned int val)
|
||||||
|
{
|
||||||
|
WARN_ONCE(1, "regmap API is disabled");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int regmap_update_bits_async(struct regmap *map,
|
static inline int regmap_update_bits_async(struct regmap *map,
|
||||||
unsigned int reg,
|
unsigned int reg,
|
||||||
unsigned int mask, unsigned int val)
|
unsigned int mask, unsigned int val)
|
||||||
|
|
|
@ -61,6 +61,14 @@ struct rsnd_src_platform_info {
|
||||||
/*
|
/*
|
||||||
* flags
|
* flags
|
||||||
*/
|
*/
|
||||||
|
struct rsnd_ctu_platform_info {
|
||||||
|
u32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rsnd_mix_platform_info {
|
||||||
|
u32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
struct rsnd_dvc_platform_info {
|
struct rsnd_dvc_platform_info {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
@ -68,6 +76,8 @@ struct rsnd_dvc_platform_info {
|
||||||
struct rsnd_dai_path_info {
|
struct rsnd_dai_path_info {
|
||||||
struct rsnd_ssi_platform_info *ssi;
|
struct rsnd_ssi_platform_info *ssi;
|
||||||
struct rsnd_src_platform_info *src;
|
struct rsnd_src_platform_info *src;
|
||||||
|
struct rsnd_ctu_platform_info *ctu;
|
||||||
|
struct rsnd_mix_platform_info *mix;
|
||||||
struct rsnd_dvc_platform_info *dvc;
|
struct rsnd_dvc_platform_info *dvc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,6 +103,10 @@ struct rcar_snd_info {
|
||||||
int ssi_info_nr;
|
int ssi_info_nr;
|
||||||
struct rsnd_src_platform_info *src_info;
|
struct rsnd_src_platform_info *src_info;
|
||||||
int src_info_nr;
|
int src_info_nr;
|
||||||
|
struct rsnd_ctu_platform_info *ctu_info;
|
||||||
|
int ctu_info_nr;
|
||||||
|
struct rsnd_mix_platform_info *mix_info;
|
||||||
|
int mix_info_nr;
|
||||||
struct rsnd_dvc_platform_info *dvc_info;
|
struct rsnd_dvc_platform_info *dvc_info;
|
||||||
int dvc_info_nr;
|
int dvc_info_nr;
|
||||||
struct rsnd_dai_platform_info *dai_info;
|
struct rsnd_dai_platform_info *dai_info;
|
||||||
|
|
|
@ -1366,7 +1366,7 @@ static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
|
||||||
{
|
{
|
||||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||||
struct arizona *arizona = priv->arizona;
|
struct arizona *arizona = priv->arizona;
|
||||||
struct reg_default dac_comp[] = {
|
struct reg_sequence dac_comp[] = {
|
||||||
{ 0x80, 0x3 },
|
{ 0x80, 0x3 },
|
||||||
{ ARIZONA_DAC_COMP_1, 0 },
|
{ ARIZONA_DAC_COMP_1, 0 },
|
||||||
{ ARIZONA_DAC_COMP_2, 0 },
|
{ ARIZONA_DAC_COMP_2, 0 },
|
||||||
|
|
|
@ -241,7 +241,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Current and threshold powerup sequence Pg37 in datasheet */
|
/* Current and threshold powerup sequence Pg37 in datasheet */
|
||||||
static const struct reg_default cs35l32_monitor_patch[] = {
|
static const struct reg_sequence cs35l32_monitor_patch[] = {
|
||||||
|
|
||||||
{ 0x00, 0x99 },
|
{ 0x00, 0x99 },
|
||||||
{ 0x48, 0x17 },
|
{ 0x48, 0x17 },
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Current and threshold powerup sequence Pg37 */
|
/* Current and threshold powerup sequence Pg37 */
|
||||||
static const struct reg_default cs42l52_threshold_patch[] = {
|
static const struct reg_sequence cs42l52_threshold_patch[] = {
|
||||||
|
|
||||||
{ 0x00, 0x99 },
|
{ 0x00, 0x99 },
|
||||||
{ 0x3E, 0xBA },
|
{ 0x3E, 0xBA },
|
||||||
|
|
|
@ -1182,7 +1182,7 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_I2C)
|
#if IS_ENABLED(CONFIG_I2C)
|
||||||
|
|
||||||
static const struct reg_default da7210_regmap_i2c_patch[] = {
|
static const struct reg_sequence da7210_regmap_i2c_patch[] = {
|
||||||
|
|
||||||
/* System controller master disable */
|
/* System controller master disable */
|
||||||
{ DA7210_STARTUP1, 0x00 },
|
{ DA7210_STARTUP1, 0x00 },
|
||||||
|
@ -1268,7 +1268,7 @@ static struct i2c_driver da7210_i2c_driver = {
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_MASTER)
|
#if defined(CONFIG_SPI_MASTER)
|
||||||
|
|
||||||
static const struct reg_default da7210_regmap_spi_patch[] = {
|
static const struct reg_sequence da7210_regmap_spi_patch[] = {
|
||||||
/* Dummy read to give two pulses over nCS for SPI */
|
/* Dummy read to give two pulses over nCS for SPI */
|
||||||
{ DA7210_AUX2, 0x00 },
|
{ DA7210_AUX2, 0x00 },
|
||||||
{ DA7210_AUX2, 0x00 },
|
{ DA7210_AUX2, 0x00 },
|
||||||
|
|
|
@ -11,38 +11,98 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
#include "rl6231.h"
|
#include "rl6231.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rl6231_calc_dmic_clk - Calculate the parameter of dmic.
|
* rl6231_get_pre_div - Return the value of pre divider.
|
||||||
|
*
|
||||||
|
* @map: map for setting.
|
||||||
|
* @reg: register.
|
||||||
|
* @sft: shift.
|
||||||
|
*
|
||||||
|
* Return the value of pre divider from given register value.
|
||||||
|
* Return negative error code for unexpected register value.
|
||||||
|
*/
|
||||||
|
int rl6231_get_pre_div(struct regmap *map, unsigned int reg, int sft)
|
||||||
|
{
|
||||||
|
int pd, val;
|
||||||
|
|
||||||
|
regmap_read(map, reg, &val);
|
||||||
|
|
||||||
|
val = (val >> sft) & 0x7;
|
||||||
|
|
||||||
|
switch (val) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
pd = val + 1;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
pd = 6;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
pd = 8;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
pd = 12;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
pd = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pd = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pd;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rl6231_get_pre_div);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rl6231_calc_dmic_clk - Calculate the frequency divider parameter of dmic.
|
||||||
*
|
*
|
||||||
* @rate: base clock rate.
|
* @rate: base clock rate.
|
||||||
*
|
*
|
||||||
* Choose dmic clock between 1MHz and 3MHz.
|
* Choose divider parameter that gives the highest possible DMIC frequency in
|
||||||
* It is better for clock to approximate 3MHz.
|
* 1MHz - 3MHz range.
|
||||||
*/
|
*/
|
||||||
int rl6231_calc_dmic_clk(int rate)
|
int rl6231_calc_dmic_clk(int rate)
|
||||||
{
|
{
|
||||||
int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL;
|
int div[] = {2, 3, 4, 6, 8, 12};
|
||||||
int i, red, bound, temp;
|
int i;
|
||||||
|
|
||||||
red = 3000000 * 12;
|
if (rate < 1000000 * div[0]) {
|
||||||
for (i = 0; i < ARRAY_SIZE(div); i++) {
|
pr_warn("Base clock rate %d is too low\n", rate);
|
||||||
bound = div[i] * 3000000;
|
return -EINVAL;
|
||||||
if (rate > bound)
|
|
||||||
continue;
|
|
||||||
temp = bound - rate;
|
|
||||||
if (temp < red) {
|
|
||||||
red = temp;
|
|
||||||
idx = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx;
|
for (i = 0; i < ARRAY_SIZE(div); i++) {
|
||||||
|
/* find divider that gives DMIC frequency below 3MHz */
|
||||||
|
if (3000000 * div[i] >= rate)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_warn("Base clock rate %d is too high\n", rate);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rl6231_calc_dmic_clk);
|
EXPORT_SYMBOL_GPL(rl6231_calc_dmic_clk);
|
||||||
|
|
||||||
|
struct pll_calc_map {
|
||||||
|
unsigned int pll_in;
|
||||||
|
unsigned int pll_out;
|
||||||
|
int k;
|
||||||
|
int n;
|
||||||
|
int m;
|
||||||
|
bool m_bp;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pll_calc_map pll_preset_table[] = {
|
||||||
|
{19200000, 24576000, 3, 30, 3, false},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rl6231_pll_calc - Calcualte PLL M/N/K code.
|
* rl6231_pll_calc - Calcualte PLL M/N/K code.
|
||||||
* @freq_in: external clock provided to codec.
|
* @freq_in: external clock provided to codec.
|
||||||
|
@ -57,7 +117,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||||
const unsigned int freq_out, struct rl6231_pll_code *pll_code)
|
const unsigned int freq_out, struct rl6231_pll_code *pll_code)
|
||||||
{
|
{
|
||||||
int max_n = RL6231_PLL_N_MAX, max_m = RL6231_PLL_M_MAX;
|
int max_n = RL6231_PLL_N_MAX, max_m = RL6231_PLL_M_MAX;
|
||||||
int k, red, n_t, pll_out, in_t, out_t;
|
int i, k, red, n_t, pll_out, in_t, out_t;
|
||||||
int n = 0, m = 0, m_t = 0;
|
int n = 0, m = 0, m_t = 0;
|
||||||
int red_t = abs(freq_out - freq_in);
|
int red_t = abs(freq_out - freq_in);
|
||||||
bool bypass = false;
|
bool bypass = false;
|
||||||
|
@ -65,6 +125,18 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||||
if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in)
|
if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(pll_preset_table); i++) {
|
||||||
|
if (freq_in == pll_preset_table[i].pll_in &&
|
||||||
|
freq_out == pll_preset_table[i].pll_out) {
|
||||||
|
k = pll_preset_table[i].k;
|
||||||
|
m = pll_preset_table[i].m;
|
||||||
|
n = pll_preset_table[i].n;
|
||||||
|
bypass = pll_preset_table[i].m_bp;
|
||||||
|
pr_debug("Use preset PLL parameter table\n");
|
||||||
|
goto code_find;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
k = 100000000 / freq_out - 2;
|
k = 100000000 / freq_out - 2;
|
||||||
if (k > RL6231_PLL_K_MAX)
|
if (k > RL6231_PLL_K_MAX)
|
||||||
k = RL6231_PLL_K_MAX;
|
k = RL6231_PLL_K_MAX;
|
||||||
|
|
|
@ -30,5 +30,6 @@ int rl6231_calc_dmic_clk(int rate);
|
||||||
int rl6231_pll_calc(const unsigned int freq_in,
|
int rl6231_pll_calc(const unsigned int freq_in,
|
||||||
const unsigned int freq_out, struct rl6231_pll_code *pll_code);
|
const unsigned int freq_out, struct rl6231_pll_code *pll_code);
|
||||||
int rl6231_get_clk_info(int sclk, int rate);
|
int rl6231_get_clk_info(int sclk, int rate);
|
||||||
|
int rl6231_get_pre_div(struct regmap *map, unsigned int reg, int sft);
|
||||||
|
|
||||||
#endif /* __RL6231_H__ */
|
#endif /* __RL6231_H__ */
|
||||||
|
|
|
@ -1108,7 +1108,7 @@ static const struct acpi_device_id rt286_acpi_match[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);
|
MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);
|
||||||
|
|
||||||
static struct dmi_system_id force_combo_jack_table[] = {
|
static const struct dmi_system_id force_combo_jack_table[] = {
|
||||||
{
|
{
|
||||||
.ident = "Intel Wilson Beach",
|
.ident = "Intel Wilson Beach",
|
||||||
.matches = {
|
.matches = {
|
||||||
|
@ -1118,7 +1118,7 @@ static struct dmi_system_id force_combo_jack_table[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dmi_system_id dmi_dell_dino[] = {
|
static const struct dmi_system_id dmi_dell_dino[] = {
|
||||||
{
|
{
|
||||||
.ident = "Dell Dino",
|
.ident = "Dell Dino",
|
||||||
.matches = {
|
.matches = {
|
||||||
|
@ -1157,7 +1157,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
|
||||||
}
|
}
|
||||||
if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
|
if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
|
||||||
dev_err(&i2c->dev,
|
dev_err(&i2c->dev,
|
||||||
"Device with ID register %x is not rt286\n", val);
|
"Device with ID register %#x is not rt286\n", val);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ static const struct regmap_range_cfg rt5640_ranges[] = {
|
||||||
.window_len = 0x1, },
|
.window_len = 0x1, },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default init_list[] = {
|
static const struct reg_sequence init_list[] = {
|
||||||
{RT5640_PR_BASE + 0x3d, 0x3600},
|
{RT5640_PR_BASE + 0x3d, 0x3600},
|
||||||
{RT5640_PR_BASE + 0x12, 0x0aa8},
|
{RT5640_PR_BASE + 0x12, 0x0aa8},
|
||||||
{RT5640_PR_BASE + 0x14, 0x0aaa},
|
{RT5640_PR_BASE + 0x14, 0x0aaa},
|
||||||
|
@ -459,10 +459,11 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||||
int idx = -EINVAL;
|
int idx, rate;
|
||||||
|
|
||||||
idx = rl6231_calc_dmic_clk(rt5640->sysclk);
|
|
||||||
|
|
||||||
|
rate = rt5640->sysclk / rl6231_get_pre_div(rt5640->regmap,
|
||||||
|
RT5640_ADDA_CLK1, RT5640_I2S_PD1_SFT);
|
||||||
|
idx = rl6231_calc_dmic_clk(rate);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -55,7 +55,7 @@ static const struct regmap_range_cfg rt5645_ranges[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default init_list[] = {
|
static const struct reg_sequence init_list[] = {
|
||||||
{RT5645_PR_BASE + 0x3d, 0x3600},
|
{RT5645_PR_BASE + 0x3d, 0x3600},
|
||||||
{RT5645_PR_BASE + 0x1c, 0xfd20},
|
{RT5645_PR_BASE + 0x1c, 0xfd20},
|
||||||
{RT5645_PR_BASE + 0x20, 0x611f},
|
{RT5645_PR_BASE + 0x20, 0x611f},
|
||||||
|
@ -64,7 +64,7 @@ static const struct reg_default init_list[] = {
|
||||||
};
|
};
|
||||||
#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
|
#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
|
||||||
|
|
||||||
static const struct reg_default rt5650_init_list[] = {
|
static const struct reg_sequence rt5650_init_list[] = {
|
||||||
{0xf6, 0x0100},
|
{0xf6, 0x0100},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -545,10 +545,11 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||||
int idx = -EINVAL;
|
int idx, rate;
|
||||||
|
|
||||||
idx = rl6231_calc_dmic_clk(rt5645->sysclk);
|
|
||||||
|
|
||||||
|
rate = rt5645->sysclk / rl6231_get_pre_div(rt5645->regmap,
|
||||||
|
RT5645_ADDA_CLK1, RT5645_I2S_PD1_SFT);
|
||||||
|
idx = rl6231_calc_dmic_clk(rate);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -46,7 +46,7 @@ static const struct regmap_range_cfg rt5651_ranges[] = {
|
||||||
.window_len = 0x1, },
|
.window_len = 0x1, },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default init_list[] = {
|
static const struct reg_sequence init_list[] = {
|
||||||
{RT5651_PR_BASE + 0x3d, 0x3e00},
|
{RT5651_PR_BASE + 0x3d, 0x3e00},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -378,10 +378,11 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
||||||
int idx = -EINVAL;
|
int idx, rate;
|
||||||
|
|
||||||
idx = rl6231_calc_dmic_clk(rt5651->sysclk);
|
|
||||||
|
|
||||||
|
rate = rt5651->sysclk / rl6231_get_pre_div(rt5651->regmap,
|
||||||
|
RT5651_ADDA_CLK1, RT5651_I2S_PD1_SFT);
|
||||||
|
idx = rl6231_calc_dmic_clk(rate);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -51,7 +51,7 @@ static const struct regmap_range_cfg rt5670_ranges[] = {
|
||||||
.window_len = 0x1, },
|
.window_len = 0x1, },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default init_list[] = {
|
static const struct reg_sequence init_list[] = {
|
||||||
{ RT5670_PR_BASE + 0x14, 0x9a8a },
|
{ RT5670_PR_BASE + 0x14, 0x9a8a },
|
||||||
{ RT5670_PR_BASE + 0x38, 0x3ba1 },
|
{ RT5670_PR_BASE + 0x38, 0x3ba1 },
|
||||||
{ RT5670_PR_BASE + 0x3d, 0x3640 },
|
{ RT5670_PR_BASE + 0x3d, 0x3640 },
|
||||||
|
@ -683,10 +683,11 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
|
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
|
||||||
int idx = -EINVAL;
|
int idx, rate;
|
||||||
|
|
||||||
idx = rl6231_calc_dmic_clk(rt5670->sysclk);
|
|
||||||
|
|
||||||
|
rate = rt5670->sysclk / rl6231_get_pre_div(rt5670->regmap,
|
||||||
|
RT5670_ADDA_CLK1, RT5670_I2S_PD1_SFT);
|
||||||
|
idx = rl6231_calc_dmic_clk(rate);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -54,7 +54,7 @@ static const struct regmap_range_cfg rt5677_ranges[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default init_list[] = {
|
static const struct reg_sequence init_list[] = {
|
||||||
{RT5677_ASRC_12, 0x0018},
|
{RT5677_ASRC_12, 0x0018},
|
||||||
{RT5677_PR_BASE + 0x3d, 0x364d},
|
{RT5677_PR_BASE + 0x3d, 0x364d},
|
||||||
{RT5677_PR_BASE + 0x17, 0x4fc0},
|
{RT5677_PR_BASE + 0x17, 0x4fc0},
|
||||||
|
@ -917,8 +917,11 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||||
int idx = rl6231_calc_dmic_clk(rt5677->lrck[RT5677_AIF1] << 8);
|
int idx, rate;
|
||||||
|
|
||||||
|
rate = rt5677->sysclk / rl6231_get_pre_div(rt5677->regmap,
|
||||||
|
RT5677_CLK_TREE_CTRL1, RT5677_I2S_PD1_SFT);
|
||||||
|
idx = rl6231_calc_dmic_clk(rate);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
dev_err(codec->dev, "Failed to set DMIC clock\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -1668,7 +1668,7 @@ static const struct i2c_device_id aic3x_i2c_id[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
|
MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
|
||||||
|
|
||||||
static const struct reg_default aic3007_class_d[] = {
|
static const struct reg_sequence aic3007_class_d[] = {
|
||||||
/* Class-D speaker driver init; datasheet p. 46 */
|
/* Class-D speaker driver init; datasheet p. 46 */
|
||||||
{ AIC3X_PAGE_SELECT, 0x0D },
|
{ AIC3X_PAGE_SELECT, 0x0D },
|
||||||
{ 0xD, 0x0D },
|
{ 0xD, 0x0D },
|
||||||
|
|
|
@ -897,7 +897,7 @@ static bool wm2200_readable_register(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct reg_default wm2200_reva_patch[] = {
|
static const struct reg_sequence wm2200_reva_patch[] = {
|
||||||
{ 0x07, 0x0003 },
|
{ 0x07, 0x0003 },
|
||||||
{ 0x102, 0x0200 },
|
{ 0x102, 0x0200 },
|
||||||
{ 0x203, 0x0084 },
|
{ 0x203, 0x0084 },
|
||||||
|
|
|
@ -1247,7 +1247,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
|
||||||
{ "PWM2", NULL, "PWM2 Driver" },
|
{ "PWM2", NULL, "PWM2 Driver" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct reg_default wm5100_reva_patches[] = {
|
static const struct reg_sequence wm5100_reva_patches[] = {
|
||||||
{ WM5100_AUDIO_IF_1_10, 0 },
|
{ WM5100_AUDIO_IF_1_10, 0 },
|
||||||
{ WM5100_AUDIO_IF_1_11, 1 },
|
{ WM5100_AUDIO_IF_1_11, 1 },
|
||||||
{ WM5100_AUDIO_IF_1_12, 2 },
|
{ WM5100_AUDIO_IF_1_12, 2 },
|
||||||
|
|
|
@ -3495,7 +3495,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Improve power consumption for IN4 DC measurement mode */
|
/* Improve power consumption for IN4 DC measurement mode */
|
||||||
static const struct reg_default wm8962_dc_measure[] = {
|
static const struct reg_sequence wm8962_dc_measure[] = {
|
||||||
{ 0xfd, 0x1 },
|
{ 0xfd, 0x1 },
|
||||||
{ 0xcc, 0x40 },
|
{ 0xcc, 0x40 },
|
||||||
{ 0xfd, 0 },
|
{ 0xfd, 0 },
|
||||||
|
|
|
@ -1595,7 +1595,7 @@ static int wm8993_resume(struct snd_soc_codec *codec)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Tune DC servo configuration */
|
/* Tune DC servo configuration */
|
||||||
static const struct reg_default wm8993_regmap_patch[] = {
|
static const struct reg_sequence wm8993_regmap_patch[] = {
|
||||||
{ 0x44, 3 },
|
{ 0x44, 3 },
|
||||||
{ 0x56, 3 },
|
{ 0x56, 3 },
|
||||||
{ 0x44, 0 },
|
{ 0x44, 0 },
|
||||||
|
|
|
@ -223,7 +223,6 @@ static struct platform_driver snd_rk_mc_driver = {
|
||||||
.probe = snd_rk_mc_probe,
|
.probe = snd_rk_mc_probe,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.pm = &snd_soc_pm_ops,
|
.pm = &snd_soc_pm_ops,
|
||||||
.of_match_table = rockchip_max98090_of_match,
|
.of_match_table = rockchip_max98090_of_match,
|
||||||
},
|
},
|
||||||
|
|
|
@ -118,7 +118,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||||
&headset_jack, NULL, 0);
|
&headset_jack, NULL, 0);
|
||||||
if (!ret) {
|
if (ret) {
|
||||||
dev_err(card->dev, "New Headset Jack failed! (%d)\n", ret);
|
dev_err(card->dev, "New Headset Jack failed! (%d)\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,6 @@ static struct platform_driver snd_rk_mc_driver = {
|
||||||
.probe = snd_rk_mc_probe,
|
.probe = snd_rk_mc_probe,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.pm = &snd_soc_pm_ops,
|
.pm = &snd_soc_pm_ops,
|
||||||
.of_match_table = rockchip_rt5645_of_match,
|
.of_match_table = rockchip_rt5645_of_match,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
snd-soc-rcar-objs := core.o gen.o dma.o src.o adg.o ssi.o dvc.o
|
snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o
|
||||||
obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
|
obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
|
||||||
|
|
||||||
snd-soc-rsrc-card-objs := rsrc-card.o
|
snd-soc-rsrc-card-objs := rsrc-card.o
|
||||||
|
|
|
@ -203,9 +203,9 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* settting function
|
* ADINR function
|
||||||
*/
|
*/
|
||||||
u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
{
|
{
|
||||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||||
|
@ -227,6 +227,64 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
return adinr;
|
return adinr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
|
{
|
||||||
|
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||||
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
u32 chan = runtime->channels;
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(dev, "not supported channel\n");
|
||||||
|
chan = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DALIGN function
|
||||||
|
*/
|
||||||
|
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
|
{
|
||||||
|
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
|
||||||
|
struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
|
||||||
|
struct rsnd_mod *target = src ? src : ssi;
|
||||||
|
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||||
|
u32 val = 0x76543210;
|
||||||
|
u32 mask = ~0;
|
||||||
|
|
||||||
|
mask <<= runtime->channels * 4;
|
||||||
|
val = val & mask;
|
||||||
|
|
||||||
|
switch (runtime->sample_bits) {
|
||||||
|
case 16:
|
||||||
|
val |= 0x67452301 & ~mask;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
val |= 0x76543210 & ~mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* exchange channeles on SRC if possible,
|
||||||
|
* otherwise, R/L volume settings on DVC
|
||||||
|
* changes inverted channels
|
||||||
|
*/
|
||||||
|
if (mod == target)
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return 0x76543210;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rsnd_dai functions
|
* rsnd_dai functions
|
||||||
*/
|
*/
|
||||||
|
@ -242,9 +300,9 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
if (val == __rsnd_mod_call_##func) { \
|
if (val == __rsnd_mod_call_##func) { \
|
||||||
called = 1; \
|
called = 1; \
|
||||||
ret = (mod)->ops->func(mod, io, param); \
|
ret = (mod)->ops->func(mod, io, param); \
|
||||||
mod->status = (mod->status & ~mask) + \
|
|
||||||
(add << __rsnd_mod_shift_##func); \
|
|
||||||
} \
|
} \
|
||||||
|
mod->status = (mod->status & ~mask) + \
|
||||||
|
(add << __rsnd_mod_shift_##func); \
|
||||||
dev_dbg(dev, "%s[%d] 0x%08x %s\n", \
|
dev_dbg(dev, "%s[%d] 0x%08x %s\n", \
|
||||||
rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \
|
rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \
|
||||||
called ? #func : ""); \
|
called ? #func : ""); \
|
||||||
|
@ -274,21 +332,21 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
|
||||||
static int rsnd_dai_connect(struct rsnd_mod *mod,
|
static int rsnd_dai_connect(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io)
|
struct rsnd_dai_stream *io)
|
||||||
{
|
{
|
||||||
|
struct rsnd_priv *priv;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
if (!mod)
|
if (!mod)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (io->mod[mod->type]) {
|
priv = rsnd_mod_to_priv(mod);
|
||||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
dev = rsnd_priv_to_dev(priv);
|
||||||
struct device *dev = rsnd_priv_to_dev(priv);
|
|
||||||
|
|
||||||
dev_err(dev, "%s[%d] is not empty\n",
|
|
||||||
rsnd_mod_name(mod),
|
|
||||||
rsnd_mod_id(mod));
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
io->mod[mod->type] = mod;
|
io->mod[mod->type] = mod;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s[%d] is connected to io (%s)\n",
|
||||||
|
rsnd_mod_name(mod), rsnd_mod_id(mod),
|
||||||
|
rsnd_io_is_play(io) ? "Playback" : "Capture");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +575,7 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
|
||||||
.set_fmt = rsnd_soc_dai_set_fmt,
|
.set_fmt = rsnd_soc_dai_set_fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define rsnd_path_parse(priv, io, type) \
|
#define rsnd_path_add(priv, io, type) \
|
||||||
({ \
|
({ \
|
||||||
struct rsnd_mod *mod; \
|
struct rsnd_mod *mod; \
|
||||||
int ret = 0; \
|
int ret = 0; \
|
||||||
|
@ -533,7 +591,7 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
|
||||||
ret; \
|
ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define rsnd_path_break(priv, io, type) \
|
#define rsnd_path_remove(priv, io, type) \
|
||||||
{ \
|
{ \
|
||||||
struct rsnd_mod *mod; \
|
struct rsnd_mod *mod; \
|
||||||
int id = -1; \
|
int id = -1; \
|
||||||
|
@ -547,6 +605,79 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rsnd_path_parse(struct rsnd_priv *priv,
|
||||||
|
struct rsnd_dai_stream *io)
|
||||||
|
{
|
||||||
|
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
|
||||||
|
struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
|
||||||
|
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
|
||||||
|
struct rsnd_mod *cmd;
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
u32 data;
|
||||||
|
|
||||||
|
/* Gen1 is not supported */
|
||||||
|
if (rsnd_is_gen1(priv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!mix && !dvc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mix) {
|
||||||
|
struct rsnd_dai *rdai;
|
||||||
|
int i;
|
||||||
|
u32 path[] = {
|
||||||
|
[0] = 0,
|
||||||
|
[1] = 1 << 0,
|
||||||
|
[2] = 0,
|
||||||
|
[3] = 0,
|
||||||
|
[4] = 0,
|
||||||
|
[5] = 1 << 8
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* it is assuming that integrater is well understanding about
|
||||||
|
* data path. Here doesn't check impossible connection,
|
||||||
|
* like src2 + src5
|
||||||
|
*/
|
||||||
|
data = 0;
|
||||||
|
for_each_rsnd_dai(rdai, priv, i) {
|
||||||
|
io = &rdai->playback;
|
||||||
|
if (mix == rsnd_io_to_mod_mix(io))
|
||||||
|
data |= path[rsnd_mod_id(src)];
|
||||||
|
|
||||||
|
io = &rdai->capture;
|
||||||
|
if (mix == rsnd_io_to_mod_mix(io))
|
||||||
|
data |= path[rsnd_mod_id(src)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can't use ctu = rsnd_io_ctu() here.
|
||||||
|
* Since, ID of dvc/mix are 0 or 1 (= same as CMD number)
|
||||||
|
* but ctu IDs are 0 - 7 (= CTU00 - CTU13)
|
||||||
|
*/
|
||||||
|
cmd = mix;
|
||||||
|
} else {
|
||||||
|
u32 path[] = {
|
||||||
|
[0] = 0x30000,
|
||||||
|
[1] = 0x30001,
|
||||||
|
[2] = 0x40000,
|
||||||
|
[3] = 0x10000,
|
||||||
|
[4] = 0x20000,
|
||||||
|
[5] = 0x40100
|
||||||
|
};
|
||||||
|
|
||||||
|
data = path[rsnd_mod_id(src)];
|
||||||
|
|
||||||
|
cmd = dvc;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dev, "ctu/mix path = 0x%08x", data);
|
||||||
|
|
||||||
|
rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
|
||||||
|
|
||||||
|
rsnd_mod_write(cmd, CMD_CTRL, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
static int rsnd_path_init(struct rsnd_priv *priv,
|
static int rsnd_path_init(struct rsnd_priv *priv,
|
||||||
struct rsnd_dai *rdai,
|
struct rsnd_dai *rdai,
|
||||||
struct rsnd_dai_stream *io)
|
struct rsnd_dai_stream *io)
|
||||||
|
@ -564,18 +695,28 @@ static int rsnd_path_init(struct rsnd_priv *priv,
|
||||||
* using fixed path.
|
* using fixed path.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* SRC */
|
/* SSI */
|
||||||
ret = rsnd_path_parse(priv, io, src);
|
ret = rsnd_path_add(priv, io, ssi);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* SSI */
|
/* SRC */
|
||||||
ret = rsnd_path_parse(priv, io, ssi);
|
ret = rsnd_path_add(priv, io, src);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* CTU */
|
||||||
|
ret = rsnd_path_add(priv, io, ctu);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* MIX */
|
||||||
|
ret = rsnd_path_add(priv, io, mix);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* DVC */
|
/* DVC */
|
||||||
ret = rsnd_path_parse(priv, io, dvc);
|
ret = rsnd_path_add(priv, io, dvc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -589,13 +730,15 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
|
||||||
struct device_node *dai_node, *dai_np;
|
struct device_node *dai_node, *dai_np;
|
||||||
struct device_node *ssi_node, *ssi_np;
|
struct device_node *ssi_node, *ssi_np;
|
||||||
struct device_node *src_node, *src_np;
|
struct device_node *src_node, *src_np;
|
||||||
|
struct device_node *ctu_node, *ctu_np;
|
||||||
|
struct device_node *mix_node, *mix_np;
|
||||||
struct device_node *dvc_node, *dvc_np;
|
struct device_node *dvc_node, *dvc_np;
|
||||||
struct device_node *playback, *capture;
|
struct device_node *playback, *capture;
|
||||||
struct rsnd_dai_platform_info *dai_info;
|
struct rsnd_dai_platform_info *dai_info;
|
||||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
int nr, i;
|
int nr, i;
|
||||||
int dai_i, ssi_i, src_i, dvc_i;
|
int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i;
|
||||||
|
|
||||||
if (!of_data)
|
if (!of_data)
|
||||||
return;
|
return;
|
||||||
|
@ -621,6 +764,8 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
|
||||||
|
|
||||||
ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
|
ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
|
||||||
src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
|
src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
|
||||||
|
ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
|
||||||
|
mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
|
||||||
dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
|
dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
|
||||||
|
|
||||||
#define mod_parse(name) \
|
#define mod_parse(name) \
|
||||||
|
@ -657,6 +802,8 @@ if (name##_node) { \
|
||||||
|
|
||||||
mod_parse(ssi);
|
mod_parse(ssi);
|
||||||
mod_parse(src);
|
mod_parse(src);
|
||||||
|
mod_parse(ctu);
|
||||||
|
mod_parse(mix);
|
||||||
mod_parse(dvc);
|
mod_parse(dvc);
|
||||||
|
|
||||||
of_node_put(playback);
|
of_node_put(playback);
|
||||||
|
@ -1033,8 +1180,8 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
|
||||||
/*
|
/*
|
||||||
* remove SRC/DVC from DAI,
|
* remove SRC/DVC from DAI,
|
||||||
*/
|
*/
|
||||||
rsnd_path_break(priv, io, src);
|
rsnd_path_remove(priv, io, src);
|
||||||
rsnd_path_break(priv, io, dvc);
|
rsnd_path_remove(priv, io, dvc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fallback
|
* fallback
|
||||||
|
@ -1069,6 +1216,8 @@ static int rsnd_probe(struct platform_device *pdev)
|
||||||
rsnd_dma_probe,
|
rsnd_dma_probe,
|
||||||
rsnd_ssi_probe,
|
rsnd_ssi_probe,
|
||||||
rsnd_src_probe,
|
rsnd_src_probe,
|
||||||
|
rsnd_ctu_probe,
|
||||||
|
rsnd_mix_probe,
|
||||||
rsnd_dvc_probe,
|
rsnd_dvc_probe,
|
||||||
rsnd_adg_probe,
|
rsnd_adg_probe,
|
||||||
rsnd_dai_probe,
|
rsnd_dai_probe,
|
||||||
|
@ -1164,6 +1313,8 @@ static int rsnd_remove(struct platform_device *pdev)
|
||||||
struct rsnd_priv *priv) = {
|
struct rsnd_priv *priv) = {
|
||||||
rsnd_ssi_remove,
|
rsnd_ssi_remove,
|
||||||
rsnd_src_remove,
|
rsnd_src_remove,
|
||||||
|
rsnd_ctu_remove,
|
||||||
|
rsnd_mix_remove,
|
||||||
rsnd_dvc_remove,
|
rsnd_dvc_remove,
|
||||||
};
|
};
|
||||||
int ret = 0, i;
|
int ret = 0, i;
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* ctu.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include "rsnd.h"
|
||||||
|
|
||||||
|
#define CTU_NAME_SIZE 16
|
||||||
|
#define CTU_NAME "ctu"
|
||||||
|
|
||||||
|
struct rsnd_ctu {
|
||||||
|
struct rsnd_ctu_platform_info *info; /* rcar_snd.h */
|
||||||
|
struct rsnd_mod mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
|
||||||
|
#define for_each_rsnd_ctu(pos, priv, i) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < rsnd_ctu_nr(priv)) && \
|
||||||
|
((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \
|
||||||
|
i++)
|
||||||
|
|
||||||
|
#define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1)
|
||||||
|
#define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0)
|
||||||
|
static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, CTU_CTUIR, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsnd_ctu_init(struct rsnd_mod *mod,
|
||||||
|
struct rsnd_dai_stream *io,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
rsnd_mod_hw_start(mod);
|
||||||
|
|
||||||
|
rsnd_ctu_initialize_lock(mod);
|
||||||
|
|
||||||
|
rsnd_mod_write(mod, CTU_ADINR, rsnd_get_adinr_chan(mod, io));
|
||||||
|
|
||||||
|
rsnd_ctu_initialize_unlock(mod);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsnd_ctu_quit(struct rsnd_mod *mod,
|
||||||
|
struct rsnd_dai_stream *io,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
rsnd_mod_hw_stop(mod);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rsnd_mod_ops rsnd_ctu_ops = {
|
||||||
|
.name = CTU_NAME,
|
||||||
|
.init = rsnd_ctu_init,
|
||||||
|
.quit = rsnd_ctu_quit,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
|
||||||
|
{
|
||||||
|
if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
|
||||||
|
id = 0;
|
||||||
|
|
||||||
|
return &((struct rsnd_ctu *)(priv->ctu) + id)->mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsnd_of_parse_ctu(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct device_node *node;
|
||||||
|
struct rsnd_ctu_platform_info *ctu_info;
|
||||||
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
int nr;
|
||||||
|
|
||||||
|
if (!of_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nr = of_get_child_count(node);
|
||||||
|
if (!nr)
|
||||||
|
goto rsnd_of_parse_ctu_end;
|
||||||
|
|
||||||
|
ctu_info = devm_kzalloc(dev,
|
||||||
|
sizeof(struct rsnd_ctu_platform_info) * nr,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!ctu_info) {
|
||||||
|
dev_err(dev, "ctu info allocation error\n");
|
||||||
|
goto rsnd_of_parse_ctu_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->ctu_info = ctu_info;
|
||||||
|
info->ctu_info_nr = nr;
|
||||||
|
|
||||||
|
rsnd_of_parse_ctu_end:
|
||||||
|
of_node_put(node);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int rsnd_ctu_probe(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
struct rsnd_ctu *ctu;
|
||||||
|
struct clk *clk;
|
||||||
|
char name[CTU_NAME_SIZE];
|
||||||
|
int i, nr, ret;
|
||||||
|
|
||||||
|
/* This driver doesn't support Gen1 at this point */
|
||||||
|
if (rsnd_is_gen1(priv)) {
|
||||||
|
dev_warn(dev, "CTU is not supported on Gen1\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsnd_of_parse_ctu(pdev, of_data, priv);
|
||||||
|
|
||||||
|
nr = info->ctu_info_nr;
|
||||||
|
if (!nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL);
|
||||||
|
if (!ctu)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv->ctu_nr = nr;
|
||||||
|
priv->ctu = ctu;
|
||||||
|
|
||||||
|
for_each_rsnd_ctu(ctu, priv, i) {
|
||||||
|
/*
|
||||||
|
* CTU00, CTU01, CTU02, CTU03 => CTU0
|
||||||
|
* CTU10, CTU11, CTU12, CTU13 => CTU1
|
||||||
|
*/
|
||||||
|
snprintf(name, CTU_NAME_SIZE, "%s.%d",
|
||||||
|
CTU_NAME, i / 4);
|
||||||
|
|
||||||
|
clk = devm_clk_get(dev, name);
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return PTR_ERR(clk);
|
||||||
|
|
||||||
|
ctu->info = &info->ctu_info[i];
|
||||||
|
|
||||||
|
ret = rsnd_mod_init(priv, &ctu->mod, &rsnd_ctu_ops,
|
||||||
|
clk, RSND_MOD_CTU, i);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsnd_ctu_remove(struct platform_device *pdev,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct rsnd_ctu *ctu;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_rsnd_ctu(ctu, priv, i) {
|
||||||
|
rsnd_mod_quit(&ctu->mod);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,15 @@ struct rsnd_dma_ctrl {
|
||||||
int dmapp_num;
|
int dmapp_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rsnd_dma_ops {
|
||||||
|
char *name;
|
||||||
|
void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
||||||
|
void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
||||||
|
int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
|
||||||
|
struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
|
||||||
|
void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
||||||
|
};
|
||||||
|
|
||||||
#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
|
#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,7 +177,7 @@ static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
|
||||||
dma_cap_set(DMA_SLAVE, mask);
|
dma_cap_set(DMA_SLAVE, mask);
|
||||||
|
|
||||||
dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
|
dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
|
||||||
(void *)id);
|
(void *)(uintptr_t)id);
|
||||||
}
|
}
|
||||||
if (IS_ERR_OR_NULL(dmaen->chan)) {
|
if (IS_ERR_OR_NULL(dmaen->chan)) {
|
||||||
dmaen->chan = NULL;
|
dmaen->chan = NULL;
|
||||||
|
@ -182,7 +191,8 @@ static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
|
||||||
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||||
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||||
|
|
||||||
dev_dbg(dev, "dma : %pad -> %pad\n",
|
dev_dbg(dev, "%s %pad -> %pad\n",
|
||||||
|
dma->ops->name,
|
||||||
&cfg.src_addr, &cfg.dst_addr);
|
&cfg.src_addr, &cfg.dst_addr);
|
||||||
|
|
||||||
ret = dmaengine_slave_config(dmaen->chan, &cfg);
|
ret = dmaengine_slave_config(dmaen->chan, &cfg);
|
||||||
|
@ -215,6 +225,7 @@ static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rsnd_dma_ops rsnd_dmaen_ops = {
|
static struct rsnd_dma_ops rsnd_dmaen_ops = {
|
||||||
|
.name = "audmac",
|
||||||
.start = rsnd_dmaen_start,
|
.start = rsnd_dmaen_start,
|
||||||
.stop = rsnd_dmaen_stop,
|
.stop = rsnd_dmaen_stop,
|
||||||
.init = rsnd_dmaen_init,
|
.init = rsnd_dmaen_init,
|
||||||
|
@ -360,6 +371,7 @@ static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rsnd_dma_ops rsnd_dmapp_ops = {
|
static struct rsnd_dma_ops rsnd_dmapp_ops = {
|
||||||
|
.name = "audmac-pp",
|
||||||
.start = rsnd_dmapp_start,
|
.start = rsnd_dmapp_start,
|
||||||
.stop = rsnd_dmapp_stop,
|
.stop = rsnd_dmapp_stop,
|
||||||
.init = rsnd_dmapp_init,
|
.init = rsnd_dmapp_init,
|
||||||
|
@ -414,7 +426,9 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
|
||||||
phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
|
phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
|
||||||
int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
|
int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
|
||||||
int use_src = !!rsnd_io_to_mod_src(io);
|
int use_src = !!rsnd_io_to_mod_src(io);
|
||||||
int use_dvc = !!rsnd_io_to_mod_dvc(io);
|
int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
|
||||||
|
!!rsnd_io_to_mod_mix(io) ||
|
||||||
|
!!rsnd_io_to_mod_ctu(io);
|
||||||
int id = rsnd_mod_id(mod);
|
int id = rsnd_mod_id(mod);
|
||||||
struct dma_addr {
|
struct dma_addr {
|
||||||
dma_addr_t out_addr;
|
dma_addr_t out_addr;
|
||||||
|
@ -452,7 +466,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* it shouldn't happen */
|
/* it shouldn't happen */
|
||||||
if (use_dvc && !use_src)
|
if (use_cmd && !use_src)
|
||||||
dev_err(dev, "DVC is selected without SRC\n");
|
dev_err(dev, "DVC is selected without SRC\n");
|
||||||
|
|
||||||
/* use SSIU or SSI ? */
|
/* use SSIU or SSI ? */
|
||||||
|
@ -460,8 +474,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
|
||||||
is_ssi++;
|
is_ssi++;
|
||||||
|
|
||||||
return (is_from) ?
|
return (is_from) ?
|
||||||
dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
|
dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr :
|
||||||
dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
|
dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
|
static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
|
||||||
|
@ -482,7 +496,7 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
|
||||||
return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
|
return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
|
#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
|
||||||
static void rsnd_dma_of_path(struct rsnd_dma *dma,
|
static void rsnd_dma_of_path(struct rsnd_dma *dma,
|
||||||
struct rsnd_dai_stream *io,
|
struct rsnd_dai_stream *io,
|
||||||
int is_play,
|
int is_play,
|
||||||
|
@ -492,55 +506,81 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
|
||||||
struct rsnd_mod *this = rsnd_dma_to_mod(dma);
|
struct rsnd_mod *this = rsnd_dma_to_mod(dma);
|
||||||
struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
|
struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
|
||||||
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
|
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
|
||||||
|
struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
|
||||||
|
struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
|
||||||
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
|
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
|
||||||
struct rsnd_mod *mod[MOD_MAX];
|
struct rsnd_mod *mod[MOD_MAX];
|
||||||
int i, index;
|
struct rsnd_mod *mod_start, *mod_end;
|
||||||
|
struct rsnd_priv *priv = rsnd_mod_to_priv(this);
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
int nr, i;
|
||||||
|
|
||||||
|
if (!ssi)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < MOD_MAX; i++)
|
nr = 0;
|
||||||
|
for (i = 0; i < MOD_MAX; i++) {
|
||||||
mod[i] = NULL;
|
mod[i] = NULL;
|
||||||
|
nr += !!rsnd_io_to_mod(io, i);
|
||||||
/*
|
|
||||||
* in play case...
|
|
||||||
*
|
|
||||||
* src -> dst
|
|
||||||
*
|
|
||||||
* mem -> SSI
|
|
||||||
* mem -> SRC -> SSI
|
|
||||||
* mem -> SRC -> DVC -> SSI
|
|
||||||
*/
|
|
||||||
mod[0] = NULL; /* for "mem" */
|
|
||||||
index = 1;
|
|
||||||
for (i = 1; i < MOD_MAX; i++) {
|
|
||||||
if (!src) {
|
|
||||||
mod[i] = ssi;
|
|
||||||
} else if (!dvc) {
|
|
||||||
mod[i] = src;
|
|
||||||
src = NULL;
|
|
||||||
} else {
|
|
||||||
if ((!is_play) && (this == src))
|
|
||||||
this = dvc;
|
|
||||||
|
|
||||||
mod[i] = (is_play) ? src : dvc;
|
|
||||||
i++;
|
|
||||||
mod[i] = (is_play) ? dvc : src;
|
|
||||||
src = NULL;
|
|
||||||
dvc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mod[i] == this)
|
|
||||||
index = i;
|
|
||||||
|
|
||||||
if (mod[i] == ssi)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_play) {
|
/*
|
||||||
*mod_from = mod[index - 1];
|
* [S] -*-> [E]
|
||||||
*mod_to = mod[index];
|
* [S] -*-> SRC -o-> [E]
|
||||||
|
* [S] -*-> SRC -> DVC -o-> [E]
|
||||||
|
* [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E]
|
||||||
|
*
|
||||||
|
* playback [S] = mem
|
||||||
|
* [E] = SSI
|
||||||
|
*
|
||||||
|
* capture [S] = SSI
|
||||||
|
* [E] = mem
|
||||||
|
*
|
||||||
|
* -*-> Audio DMAC
|
||||||
|
* -o-> Audio DMAC peri peri
|
||||||
|
*/
|
||||||
|
mod_start = (is_play) ? NULL : ssi;
|
||||||
|
mod_end = (is_play) ? ssi : NULL;
|
||||||
|
|
||||||
|
mod[0] = mod_start;
|
||||||
|
for (i = 1; i < nr; i++) {
|
||||||
|
if (src) {
|
||||||
|
mod[i] = src;
|
||||||
|
src = NULL;
|
||||||
|
} else if (ctu) {
|
||||||
|
mod[i] = ctu;
|
||||||
|
ctu = NULL;
|
||||||
|
} else if (mix) {
|
||||||
|
mod[i] = mix;
|
||||||
|
mix = NULL;
|
||||||
|
} else if (dvc) {
|
||||||
|
mod[i] = dvc;
|
||||||
|
dvc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod[i] = mod_end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* | SSI | SRC |
|
||||||
|
* -------------+-----+-----+
|
||||||
|
* is_play | o | * |
|
||||||
|
* !is_play | * | o |
|
||||||
|
*/
|
||||||
|
if ((this == ssi) == (is_play)) {
|
||||||
|
*mod_from = mod[nr - 1];
|
||||||
|
*mod_to = mod[nr];
|
||||||
} else {
|
} else {
|
||||||
*mod_from = mod[index];
|
*mod_from = mod[0];
|
||||||
*mod_to = mod[index - 1];
|
*mod_to = mod[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dev, "module connection (this is %s[%d])\n",
|
||||||
|
rsnd_mod_name(this), rsnd_mod_id(this));
|
||||||
|
for (i = 0; i <= nr; i++) {
|
||||||
|
dev_dbg(dev, " %s[%d]%s\n",
|
||||||
|
rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
|
||||||
|
(mod[i] == *mod_from) ? " from" :
|
||||||
|
(mod[i] == *mod_to) ? " to" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,10 +608,11 @@ void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
|
||||||
|
|
||||||
int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
|
int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
|
||||||
{
|
{
|
||||||
struct rsnd_mod *mod_from;
|
struct rsnd_mod *mod_from = NULL;
|
||||||
struct rsnd_mod *mod_to;
|
struct rsnd_mod *mod_to = NULL;
|
||||||
struct rsnd_priv *priv = rsnd_io_to_priv(io);
|
struct rsnd_priv *priv = rsnd_io_to_priv(io);
|
||||||
struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
|
struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
int is_play = rsnd_io_is_play(io);
|
int is_play = rsnd_io_is_play(io);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -598,6 +639,11 @@ int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
|
||||||
if (rsnd_is_gen1(priv))
|
if (rsnd_is_gen1(priv))
|
||||||
dma->ops = &rsnd_dmaen_ops;
|
dma->ops = &rsnd_dmaen_ops;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s %s[%d] -> %s[%d]\n",
|
||||||
|
dma->ops->name,
|
||||||
|
rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
|
||||||
|
rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
|
||||||
|
|
||||||
return dma->ops->init(io, dma, id, mod_from, mod_to);
|
return dma->ops->init(io, dma, id, mod_from, mod_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ struct rsnd_dvc {
|
||||||
struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
|
struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
|
||||||
#define rsnd_dvc_of_node(priv) \
|
#define rsnd_dvc_of_node(priv) \
|
||||||
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
|
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
|
||||||
|
|
||||||
|
@ -63,6 +64,19 @@ static const char * const dvc_ramp_rate[] = {
|
||||||
"0.125 dB/8192 steps", /* 10111 */
|
"0.125 dB/8192 steps", /* 10111 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void rsnd_dvc_soft_reset(struct rsnd_mod *mod)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, DVC_SWRSR, 0);
|
||||||
|
rsnd_mod_write(mod, DVC_SWRSR, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1)
|
||||||
|
#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0)
|
||||||
|
static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, DVC_DVUIR, enable);
|
||||||
|
}
|
||||||
|
|
||||||
static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
|
static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
|
||||||
struct rsnd_mod *mod)
|
struct rsnd_mod *mod)
|
||||||
{
|
{
|
||||||
|
@ -135,49 +149,24 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
static int rsnd_dvc_init(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io,
|
struct rsnd_dai_stream *io,
|
||||||
struct rsnd_priv *priv)
|
struct rsnd_priv *priv)
|
||||||
{
|
{
|
||||||
struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
|
rsnd_mod_hw_start(mod);
|
||||||
struct device *dev = rsnd_priv_to_dev(priv);
|
|
||||||
int dvc_id = rsnd_mod_id(dvc_mod);
|
|
||||||
int src_id = rsnd_mod_id(src_mod);
|
|
||||||
u32 route[] = {
|
|
||||||
[0] = 0x30000,
|
|
||||||
[1] = 0x30001,
|
|
||||||
[2] = 0x40000,
|
|
||||||
[3] = 0x10000,
|
|
||||||
[4] = 0x20000,
|
|
||||||
[5] = 0x40100
|
|
||||||
};
|
|
||||||
|
|
||||||
if (src_id >= ARRAY_SIZE(route)) {
|
rsnd_dvc_soft_reset(mod);
|
||||||
dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rsnd_mod_hw_start(dvc_mod);
|
rsnd_dvc_initialize_lock(mod);
|
||||||
|
|
||||||
/*
|
rsnd_path_parse(priv, io);
|
||||||
* fixme
|
|
||||||
* it doesn't support CTU/MIX
|
|
||||||
*/
|
|
||||||
rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]);
|
|
||||||
|
|
||||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 0);
|
rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
|
||||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 1);
|
|
||||||
|
|
||||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
|
|
||||||
|
|
||||||
rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod, io));
|
|
||||||
|
|
||||||
/* ch0/ch1 Volume */
|
/* ch0/ch1 Volume */
|
||||||
rsnd_dvc_volume_update(io, dvc_mod);
|
rsnd_dvc_volume_update(io, mod);
|
||||||
|
|
||||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
|
rsnd_adg_set_cmd_timsel_gen2(mod, io);
|
||||||
|
|
||||||
rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +184,8 @@ static int rsnd_dvc_start(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io,
|
struct rsnd_dai_stream *io,
|
||||||
struct rsnd_priv *priv)
|
struct rsnd_priv *priv)
|
||||||
{
|
{
|
||||||
|
rsnd_dvc_initialize_unlock(mod);
|
||||||
|
|
||||||
rsnd_mod_write(mod, CMD_CTRL, 0x10);
|
rsnd_mod_write(mod, CMD_CTRL, 0x10);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -341,23 +332,21 @@ int rsnd_dvc_probe(struct platform_device *pdev,
|
||||||
char name[RSND_DVC_NAME_SIZE];
|
char name[RSND_DVC_NAME_SIZE];
|
||||||
int i, nr, ret;
|
int i, nr, ret;
|
||||||
|
|
||||||
rsnd_of_parse_dvc(pdev, of_data, priv);
|
|
||||||
|
|
||||||
nr = info->dvc_info_nr;
|
|
||||||
if (!nr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* This driver doesn't support Gen1 at this point */
|
/* This driver doesn't support Gen1 at this point */
|
||||||
if (rsnd_is_gen1(priv)) {
|
if (rsnd_is_gen1(priv)) {
|
||||||
dev_warn(dev, "CMD is not supported on Gen1\n");
|
dev_warn(dev, "CMD is not supported on Gen1\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rsnd_of_parse_dvc(pdev, of_data, priv);
|
||||||
|
|
||||||
|
nr = info->dvc_info_nr;
|
||||||
|
if (!nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
|
dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
|
||||||
if (!dvc) {
|
if (!dvc)
|
||||||
dev_err(dev, "CMD allocate failed\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
priv->dvc_nr = nr;
|
priv->dvc_nr = nr;
|
||||||
priv->dvc = dvc;
|
priv->dvc = dvc;
|
||||||
|
|
|
@ -103,6 +103,22 @@ void rsnd_write(struct rsnd_priv *priv,
|
||||||
regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
|
regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rsnd_force_write(struct rsnd_priv *priv,
|
||||||
|
struct rsnd_mod *mod,
|
||||||
|
enum rsnd_reg reg, u32 data)
|
||||||
|
{
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
|
||||||
|
|
||||||
|
if (!rsnd_is_accessible_reg(priv, gen, reg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
|
||||||
|
rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
|
||||||
|
|
||||||
|
regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data);
|
||||||
|
}
|
||||||
|
|
||||||
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
||||||
enum rsnd_reg reg, u32 mask, u32 data)
|
enum rsnd_reg reg, u32 mask, u32 data)
|
||||||
{
|
{
|
||||||
|
@ -200,12 +216,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
|
||||||
/* FIXME: it needs SSI_MODE2/3 in the future */
|
/* FIXME: it needs SSI_MODE2/3 in the future */
|
||||||
RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80),
|
RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80),
|
||||||
RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80),
|
RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80),
|
||||||
RSND_GEN_M_REG(BUSIF_DALIGN, 0x8, 0x80),
|
RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80),
|
||||||
RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
|
RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
|
||||||
RSND_GEN_M_REG(INT_ENABLE, 0x18, 0x80),
|
RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
|
||||||
};
|
};
|
||||||
struct rsnd_regmap_field_conf conf_scu[] = {
|
struct rsnd_regmap_field_conf conf_scu[] = {
|
||||||
RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20),
|
RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20),
|
||||||
|
RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20),
|
||||||
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
|
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
|
||||||
RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
|
RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
|
||||||
RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
|
RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
|
||||||
|
@ -223,6 +240,18 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
|
||||||
RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
|
RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
|
||||||
RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40),
|
RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40),
|
||||||
RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
|
RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
|
||||||
|
RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100),
|
||||||
|
RSND_GEN_M_REG(CTU_ADINR, 0x508, 0x100),
|
||||||
|
RSND_GEN_M_REG(MIX_SWRSR, 0xd00, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MIXIR, 0xd04, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_ADINR, 0xd08, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40),
|
||||||
|
RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40),
|
||||||
RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
|
RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
|
||||||
RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
|
RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
|
||||||
RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
|
RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
* mix.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include "rsnd.h"
|
||||||
|
|
||||||
|
#define MIX_NAME_SIZE 16
|
||||||
|
#define MIX_NAME "mix"
|
||||||
|
|
||||||
|
struct rsnd_mix {
|
||||||
|
struct rsnd_mix_platform_info *info; /* rcar_snd.h */
|
||||||
|
struct rsnd_mod mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define rsnd_mix_nr(priv) ((priv)->mix_nr)
|
||||||
|
#define for_each_rsnd_mix(pos, priv, i) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < rsnd_mix_nr(priv)) && \
|
||||||
|
((pos) = (struct rsnd_mix *)(priv)->mix + i); \
|
||||||
|
i++)
|
||||||
|
|
||||||
|
|
||||||
|
static void rsnd_mix_soft_reset(struct rsnd_mod *mod)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, MIX_SWRSR, 0);
|
||||||
|
rsnd_mod_write(mod, MIX_SWRSR, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define rsnd_mix_initialize_lock(mod) __rsnd_mix_initialize_lock(mod, 1)
|
||||||
|
#define rsnd_mix_initialize_unlock(mod) __rsnd_mix_initialize_lock(mod, 0)
|
||||||
|
static void __rsnd_mix_initialize_lock(struct rsnd_mod *mod, u32 enable)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, MIX_MIXIR, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
|
||||||
|
struct rsnd_mod *mod)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Disable MIX dB setting */
|
||||||
|
rsnd_mod_write(mod, MIX_MDBER, 0);
|
||||||
|
|
||||||
|
rsnd_mod_write(mod, MIX_MDBAR, 0);
|
||||||
|
rsnd_mod_write(mod, MIX_MDBBR, 0);
|
||||||
|
rsnd_mod_write(mod, MIX_MDBCR, 0);
|
||||||
|
rsnd_mod_write(mod, MIX_MDBDR, 0);
|
||||||
|
|
||||||
|
/* Enable MIX dB setting */
|
||||||
|
rsnd_mod_write(mod, MIX_MDBER, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsnd_mix_init(struct rsnd_mod *mod,
|
||||||
|
struct rsnd_dai_stream *io,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
rsnd_mod_hw_start(mod);
|
||||||
|
|
||||||
|
rsnd_mix_soft_reset(mod);
|
||||||
|
|
||||||
|
rsnd_mix_initialize_lock(mod);
|
||||||
|
|
||||||
|
rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
|
||||||
|
|
||||||
|
rsnd_path_parse(priv, io);
|
||||||
|
|
||||||
|
/* volume step */
|
||||||
|
rsnd_mod_write(mod, MIX_MIXMR, 0);
|
||||||
|
rsnd_mod_write(mod, MIX_MVPDR, 0);
|
||||||
|
|
||||||
|
rsnd_mix_volume_update(io, mod);
|
||||||
|
|
||||||
|
rsnd_mix_initialize_unlock(mod);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsnd_mix_quit(struct rsnd_mod *mod,
|
||||||
|
struct rsnd_dai_stream *io,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
rsnd_mod_hw_stop(mod);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rsnd_mod_ops rsnd_mix_ops = {
|
||||||
|
.name = MIX_NAME,
|
||||||
|
.init = rsnd_mix_init,
|
||||||
|
.quit = rsnd_mix_quit,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
|
||||||
|
{
|
||||||
|
if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
|
||||||
|
id = 0;
|
||||||
|
|
||||||
|
return &((struct rsnd_mix *)(priv->mix) + id)->mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsnd_of_parse_mix(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct device_node *node;
|
||||||
|
struct rsnd_mix_platform_info *mix_info;
|
||||||
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
int nr;
|
||||||
|
|
||||||
|
if (!of_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nr = of_get_child_count(node);
|
||||||
|
if (!nr)
|
||||||
|
goto rsnd_of_parse_mix_end;
|
||||||
|
|
||||||
|
mix_info = devm_kzalloc(dev,
|
||||||
|
sizeof(struct rsnd_mix_platform_info) * nr,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!mix_info) {
|
||||||
|
dev_err(dev, "mix info allocation error\n");
|
||||||
|
goto rsnd_of_parse_mix_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->mix_info = mix_info;
|
||||||
|
info->mix_info_nr = nr;
|
||||||
|
|
||||||
|
rsnd_of_parse_mix_end:
|
||||||
|
of_node_put(node);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int rsnd_mix_probe(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||||
|
struct device *dev = rsnd_priv_to_dev(priv);
|
||||||
|
struct rsnd_mix *mix;
|
||||||
|
struct clk *clk;
|
||||||
|
char name[MIX_NAME_SIZE];
|
||||||
|
int i, nr, ret;
|
||||||
|
|
||||||
|
/* This driver doesn't support Gen1 at this point */
|
||||||
|
if (rsnd_is_gen1(priv)) {
|
||||||
|
dev_warn(dev, "MIX is not supported on Gen1\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsnd_of_parse_mix(pdev, of_data, priv);
|
||||||
|
|
||||||
|
nr = info->mix_info_nr;
|
||||||
|
if (!nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL);
|
||||||
|
if (!mix)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv->mix_nr = nr;
|
||||||
|
priv->mix = mix;
|
||||||
|
|
||||||
|
for_each_rsnd_mix(mix, priv, i) {
|
||||||
|
snprintf(name, MIX_NAME_SIZE, "%s.%d",
|
||||||
|
MIX_NAME, i);
|
||||||
|
|
||||||
|
clk = devm_clk_get(dev, name);
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return PTR_ERR(clk);
|
||||||
|
|
||||||
|
mix->info = &info->mix_info[i];
|
||||||
|
|
||||||
|
ret = rsnd_mod_init(priv, &mix->mod, &rsnd_mix_ops,
|
||||||
|
clk, RSND_MOD_MIX, i);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsnd_mix_remove(struct platform_device *pdev,
|
||||||
|
struct rsnd_priv *priv)
|
||||||
|
{
|
||||||
|
struct rsnd_mix *mix;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_rsnd_mix(mix, priv, i) {
|
||||||
|
rsnd_mod_quit(&mix->mod);
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,6 +47,18 @@ enum rsnd_reg {
|
||||||
RSND_REG_SCU_SYS_STATUS0,
|
RSND_REG_SCU_SYS_STATUS0,
|
||||||
RSND_REG_SCU_SYS_INT_EN0,
|
RSND_REG_SCU_SYS_INT_EN0,
|
||||||
RSND_REG_CMD_ROUTE_SLCT,
|
RSND_REG_CMD_ROUTE_SLCT,
|
||||||
|
RSND_REG_CTU_CTUIR,
|
||||||
|
RSND_REG_CTU_ADINR,
|
||||||
|
RSND_REG_MIX_SWRSR,
|
||||||
|
RSND_REG_MIX_MIXIR,
|
||||||
|
RSND_REG_MIX_ADINR,
|
||||||
|
RSND_REG_MIX_MIXMR,
|
||||||
|
RSND_REG_MIX_MVPDR,
|
||||||
|
RSND_REG_MIX_MDBAR,
|
||||||
|
RSND_REG_MIX_MDBBR,
|
||||||
|
RSND_REG_MIX_MDBCR,
|
||||||
|
RSND_REG_MIX_MDBDR,
|
||||||
|
RSND_REG_MIX_MDBER,
|
||||||
RSND_REG_DVC_SWRSR,
|
RSND_REG_DVC_SWRSR,
|
||||||
RSND_REG_DVC_DVUIR,
|
RSND_REG_DVC_DVUIR,
|
||||||
RSND_REG_DVC_ADINR,
|
RSND_REG_DVC_ADINR,
|
||||||
|
@ -99,6 +111,7 @@ enum rsnd_reg {
|
||||||
RSND_REG_SHARE26,
|
RSND_REG_SHARE26,
|
||||||
RSND_REG_SHARE27,
|
RSND_REG_SHARE27,
|
||||||
RSND_REG_SHARE28,
|
RSND_REG_SHARE28,
|
||||||
|
RSND_REG_SHARE29,
|
||||||
|
|
||||||
RSND_REG_MAX,
|
RSND_REG_MAX,
|
||||||
};
|
};
|
||||||
|
@ -119,7 +132,7 @@ enum rsnd_reg {
|
||||||
#define RSND_REG_SSI_CTRL RSND_REG_SHARE02
|
#define RSND_REG_SSI_CTRL RSND_REG_SHARE02
|
||||||
#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03
|
#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03
|
||||||
#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04
|
#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04
|
||||||
#define RSND_REG_INT_ENABLE RSND_REG_SHARE05
|
#define RSND_REG_SSI_INT_ENABLE RSND_REG_SHARE05
|
||||||
#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06
|
#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06
|
||||||
#define RSND_REG_SRC_BSISR RSND_REG_SHARE07
|
#define RSND_REG_SRC_BSISR RSND_REG_SHARE07
|
||||||
#define RSND_REG_DIV_EN RSND_REG_SHARE08
|
#define RSND_REG_DIV_EN RSND_REG_SHARE08
|
||||||
|
@ -136,13 +149,14 @@ enum rsnd_reg {
|
||||||
#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
|
#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
|
||||||
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
|
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
|
||||||
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
|
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
|
||||||
#define RSND_REG_BUSIF_DALIGN RSND_REG_SHARE22
|
#define RSND_REG_SSI_BUSIF_DALIGN RSND_REG_SHARE22
|
||||||
#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
|
#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
|
||||||
#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
|
#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
|
||||||
#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
|
#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
|
||||||
#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26
|
#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26
|
||||||
#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27
|
#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27
|
||||||
#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28
|
#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28
|
||||||
|
#define RSND_REG_SRC_BUSIF_DALIGN RSND_REG_SHARE29
|
||||||
|
|
||||||
struct rsnd_of_data;
|
struct rsnd_of_data;
|
||||||
struct rsnd_priv;
|
struct rsnd_priv;
|
||||||
|
@ -157,27 +171,28 @@ struct rsnd_dai_stream;
|
||||||
rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
|
rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
|
||||||
#define rsnd_mod_write(m, r, d) \
|
#define rsnd_mod_write(m, r, d) \
|
||||||
rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
|
rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
|
||||||
|
#define rsnd_mod_force_write(m, r, d) \
|
||||||
|
rsnd_force_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
|
||||||
#define rsnd_mod_bset(m, r, s, d) \
|
#define rsnd_mod_bset(m, r, s, d) \
|
||||||
rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
|
rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
|
||||||
|
|
||||||
u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
|
u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
|
||||||
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
||||||
enum rsnd_reg reg, u32 data);
|
enum rsnd_reg reg, u32 data);
|
||||||
|
void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
||||||
|
enum rsnd_reg reg, u32 data);
|
||||||
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
|
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
|
||||||
u32 mask, u32 data);
|
u32 mask, u32 data);
|
||||||
u32 rsnd_get_adinr(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
||||||
|
u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
||||||
|
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
|
||||||
|
void rsnd_path_parse(struct rsnd_priv *priv,
|
||||||
|
struct rsnd_dai_stream *io);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R-Car DMA
|
* R-Car DMA
|
||||||
*/
|
*/
|
||||||
struct rsnd_dma;
|
struct rsnd_dma;
|
||||||
struct rsnd_dma_ops {
|
|
||||||
void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
|
||||||
void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
|
||||||
int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
|
|
||||||
struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
|
|
||||||
void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rsnd_dmaen {
|
struct rsnd_dmaen {
|
||||||
struct dma_chan *chan;
|
struct dma_chan *chan;
|
||||||
|
@ -217,6 +232,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
|
||||||
*/
|
*/
|
||||||
enum rsnd_mod_type {
|
enum rsnd_mod_type {
|
||||||
RSND_MOD_DVC = 0,
|
RSND_MOD_DVC = 0,
|
||||||
|
RSND_MOD_MIX,
|
||||||
|
RSND_MOD_CTU,
|
||||||
RSND_MOD_SRC,
|
RSND_MOD_SRC,
|
||||||
RSND_MOD_SSI,
|
RSND_MOD_SSI,
|
||||||
RSND_MOD_MAX,
|
RSND_MOD_MAX,
|
||||||
|
@ -312,7 +329,7 @@ struct rsnd_mod {
|
||||||
|
|
||||||
#define rsnd_mod_to_priv(mod) ((mod)->priv)
|
#define rsnd_mod_to_priv(mod) ((mod)->priv)
|
||||||
#define rsnd_mod_to_dma(mod) (&(mod)->dma)
|
#define rsnd_mod_to_dma(mod) (&(mod)->dma)
|
||||||
#define rsnd_mod_id(mod) ((mod)->id)
|
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
|
||||||
#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
|
#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
|
||||||
#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
|
#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
|
||||||
|
|
||||||
|
@ -345,9 +362,12 @@ struct rsnd_dai_stream {
|
||||||
int byte_per_period;
|
int byte_per_period;
|
||||||
int next_period_byte;
|
int next_period_byte;
|
||||||
};
|
};
|
||||||
#define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI])
|
#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
|
||||||
#define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC])
|
#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
|
||||||
#define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC])
|
#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC)
|
||||||
|
#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU)
|
||||||
|
#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX)
|
||||||
|
#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC)
|
||||||
#define rsnd_io_to_rdai(io) ((io)->rdai)
|
#define rsnd_io_to_rdai(io) ((io)->rdai)
|
||||||
#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
|
#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
|
||||||
#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
|
#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
|
||||||
|
@ -436,12 +456,6 @@ struct rsnd_priv {
|
||||||
*/
|
*/
|
||||||
void *gen;
|
void *gen;
|
||||||
|
|
||||||
/*
|
|
||||||
* below value will be filled on rsnd_src_probe()
|
|
||||||
*/
|
|
||||||
void *src;
|
|
||||||
int src_nr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* below value will be filled on rsnd_adg_probe()
|
* below value will be filled on rsnd_adg_probe()
|
||||||
*/
|
*/
|
||||||
|
@ -458,6 +472,24 @@ struct rsnd_priv {
|
||||||
void *ssi;
|
void *ssi;
|
||||||
int ssi_nr;
|
int ssi_nr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* below value will be filled on rsnd_src_probe()
|
||||||
|
*/
|
||||||
|
void *src;
|
||||||
|
int src_nr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* below value will be filled on rsnd_ctu_probe()
|
||||||
|
*/
|
||||||
|
void *ctu;
|
||||||
|
int ctu_nr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* below value will be filled on rsnd_mix_probe()
|
||||||
|
*/
|
||||||
|
void *mix;
|
||||||
|
int mix_nr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* below value will be filled on rsnd_dvc_probe()
|
* below value will be filled on rsnd_dvc_probe()
|
||||||
*/
|
*/
|
||||||
|
@ -530,6 +562,19 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
|
||||||
const char * const *texts,
|
const char * const *texts,
|
||||||
u32 max);
|
u32 max);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* R-Car SSI
|
||||||
|
*/
|
||||||
|
int rsnd_ssi_probe(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv);
|
||||||
|
void rsnd_ssi_remove(struct platform_device *pdev,
|
||||||
|
struct rsnd_priv *priv);
|
||||||
|
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
|
||||||
|
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
|
||||||
|
int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
|
||||||
|
int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R-Car SRC
|
* R-Car SRC
|
||||||
*/
|
*/
|
||||||
|
@ -550,20 +595,27 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
|
||||||
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod);
|
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod);
|
||||||
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
|
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
|
||||||
|
|
||||||
#define rsnd_src_nr(priv) ((priv)->src_nr)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R-Car SSI
|
* R-Car CTU
|
||||||
*/
|
*/
|
||||||
int rsnd_ssi_probe(struct platform_device *pdev,
|
int rsnd_ctu_probe(struct platform_device *pdev,
|
||||||
const struct rsnd_of_data *of_data,
|
const struct rsnd_of_data *of_data,
|
||||||
struct rsnd_priv *priv);
|
struct rsnd_priv *priv);
|
||||||
void rsnd_ssi_remove(struct platform_device *pdev,
|
|
||||||
|
void rsnd_ctu_remove(struct platform_device *pdev,
|
||||||
struct rsnd_priv *priv);
|
struct rsnd_priv *priv);
|
||||||
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
|
struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
|
||||||
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
|
|
||||||
int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
|
/*
|
||||||
int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
|
* R-Car MIX
|
||||||
|
*/
|
||||||
|
int rsnd_mix_probe(struct platform_device *pdev,
|
||||||
|
const struct rsnd_of_data *of_data,
|
||||||
|
struct rsnd_priv *priv);
|
||||||
|
|
||||||
|
void rsnd_mix_remove(struct platform_device *pdev,
|
||||||
|
struct rsnd_priv *priv);
|
||||||
|
struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R-Car DVC
|
* R-Car DVC
|
||||||
|
@ -575,7 +627,4 @@ void rsnd_dvc_remove(struct platform_device *pdev,
|
||||||
struct rsnd_priv *priv);
|
struct rsnd_priv *priv);
|
||||||
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
|
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
|
||||||
|
|
||||||
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,6 +41,7 @@ static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
|
||||||
static const struct of_device_id rsrc_card_of_match[] = {
|
static const struct of_device_id rsrc_card_of_match[] = {
|
||||||
{ .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
|
{ .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
|
||||||
{ .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
|
{ .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
|
||||||
|
{ .compatible = "renesas,rsrc-card", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
|
MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
|
||||||
|
@ -242,8 +243,15 @@ static int rsrc_card_parse_links(struct device_node *np,
|
||||||
snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
|
snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
|
||||||
|
|
||||||
/* additional name prefix */
|
/* additional name prefix */
|
||||||
priv->codec_conf.of_node = dai_link->codec_of_node;
|
if (of_data) {
|
||||||
priv->codec_conf.name_prefix = of_data->prefix;
|
priv->codec_conf.of_node = dai_link->codec_of_node;
|
||||||
|
priv->codec_conf.name_prefix = of_data->prefix;
|
||||||
|
} else {
|
||||||
|
snd_soc_of_parse_audio_prefix(&priv->snd_card,
|
||||||
|
&priv->codec_conf,
|
||||||
|
dai_link->codec_of_node,
|
||||||
|
"audio-prefix");
|
||||||
|
}
|
||||||
|
|
||||||
/* set dai_name */
|
/* set dai_name */
|
||||||
snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s",
|
snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s",
|
||||||
|
@ -361,8 +369,14 @@ static int rsrc_card_parse_of(struct device_node *node,
|
||||||
priv->snd_card.num_links = num;
|
priv->snd_card.num_links = num;
|
||||||
priv->snd_card.codec_conf = &priv->codec_conf;
|
priv->snd_card.codec_conf = &priv->codec_conf;
|
||||||
priv->snd_card.num_configs = 1;
|
priv->snd_card.num_configs = 1;
|
||||||
priv->snd_card.of_dapm_routes = of_data->routes;
|
|
||||||
priv->snd_card.num_of_dapm_routes = of_data->num_routes;
|
if (of_data) {
|
||||||
|
priv->snd_card.of_dapm_routes = of_data->routes;
|
||||||
|
priv->snd_card.num_of_dapm_routes = of_data->num_routes;
|
||||||
|
} else {
|
||||||
|
snd_soc_of_parse_audio_routing(&priv->snd_card,
|
||||||
|
"audio-routing");
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the card name from DT */
|
/* Parse the card name from DT */
|
||||||
snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
|
snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct rsnd_src {
|
||||||
|
|
||||||
#define RSND_SRC_NAME_SIZE 16
|
#define RSND_SRC_NAME_SIZE 16
|
||||||
|
|
||||||
|
#define rsnd_src_nr(priv) ((priv)->src_nr)
|
||||||
#define rsnd_enable_sync_convert(src) ((src)->sen.val)
|
#define rsnd_enable_sync_convert(src) ((src)->sen.val)
|
||||||
#define rsnd_src_of_node(priv) \
|
#define rsnd_src_of_node(priv) \
|
||||||
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
|
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
|
||||||
|
@ -117,6 +118,20 @@ struct rsnd_src {
|
||||||
/*
|
/*
|
||||||
* Gen1/Gen2 common functions
|
* Gen1/Gen2 common functions
|
||||||
*/
|
*/
|
||||||
|
static void rsnd_src_soft_reset(struct rsnd_mod *mod)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, SRC_SWRSR, 0);
|
||||||
|
rsnd_mod_write(mod, SRC_SWRSR, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define rsnd_src_initialize_lock(mod) __rsnd_src_initialize_lock(mod, 1)
|
||||||
|
#define rsnd_src_initialize_unlock(mod) __rsnd_src_initialize_lock(mod, 0)
|
||||||
|
static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable)
|
||||||
|
{
|
||||||
|
rsnd_mod_write(mod, SRC_SRCIR, enable);
|
||||||
|
}
|
||||||
|
|
||||||
static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
|
static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
|
||||||
struct rsnd_mod *mod)
|
struct rsnd_mod *mod)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +148,6 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||||
int use_busif)
|
int use_busif)
|
||||||
{
|
{
|
||||||
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
||||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
|
||||||
int ssi_id = rsnd_mod_id(ssi_mod);
|
int ssi_id = rsnd_mod_id(ssi_mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -170,27 +184,14 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||||
* DMA settings for SSIU
|
* DMA settings for SSIU
|
||||||
*/
|
*/
|
||||||
if (use_busif) {
|
if (use_busif) {
|
||||||
u32 val = 0x76543210;
|
u32 val = rsnd_get_dalign(ssi_mod, io);
|
||||||
u32 mask = ~0;
|
|
||||||
|
|
||||||
rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
|
rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
|
||||||
rsnd_get_adinr(ssi_mod, io));
|
rsnd_get_adinr_bit(ssi_mod, io));
|
||||||
rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
|
rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
|
||||||
rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
|
rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
|
||||||
|
|
||||||
mask <<= runtime->channels * 4;
|
rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
|
||||||
val = val & mask;
|
|
||||||
|
|
||||||
switch (runtime->sample_bits) {
|
|
||||||
case 16:
|
|
||||||
val |= 0x67452301 & ~mask;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
val |= 0x76543210 & ~mask;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -215,10 +216,9 @@ int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* enable SSI interrupt if Gen2 */
|
/* enable SSI interrupt if Gen2 */
|
||||||
if (rsnd_ssi_is_dma_mode(ssi_mod))
|
rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
|
||||||
rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000);
|
rsnd_ssi_is_dma_mode(ssi_mod) ?
|
||||||
else
|
0x0e000000 : 0x0f000000);
|
||||||
rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* disable SSI interrupt if Gen2 */
|
/* disable SSI interrupt if Gen2 */
|
||||||
rsnd_mod_write(ssi_mod, INT_ENABLE, 0x00000000);
|
rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -294,12 +294,8 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
||||||
if (convert_rate)
|
if (convert_rate)
|
||||||
fsrate = 0x0400000 / convert_rate * runtime->rate;
|
fsrate = 0x0400000 / convert_rate * runtime->rate;
|
||||||
|
|
||||||
/* set/clear soft reset */
|
|
||||||
rsnd_mod_write(mod, SRC_SWRSR, 0);
|
|
||||||
rsnd_mod_write(mod, SRC_SWRSR, 1);
|
|
||||||
|
|
||||||
/* Set channel number and output bit length */
|
/* Set channel number and output bit length */
|
||||||
rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod, io));
|
rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io));
|
||||||
|
|
||||||
/* Enable the initial value of IFS */
|
/* Enable the initial value of IFS */
|
||||||
if (fsrate) {
|
if (fsrate) {
|
||||||
|
@ -358,17 +354,15 @@ static int rsnd_src_init(struct rsnd_mod *mod,
|
||||||
|
|
||||||
rsnd_mod_hw_start(mod);
|
rsnd_mod_hw_start(mod);
|
||||||
|
|
||||||
|
rsnd_src_soft_reset(mod);
|
||||||
|
|
||||||
|
rsnd_src_initialize_lock(mod);
|
||||||
|
|
||||||
src->err = 0;
|
src->err = 0;
|
||||||
|
|
||||||
/* reset sync convert_rate */
|
/* reset sync convert_rate */
|
||||||
src->sync.val = 0;
|
src->sync.val = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the operation of the SRC internal circuits
|
|
||||||
* see rsnd_src_start()
|
|
||||||
*/
|
|
||||||
rsnd_mod_write(mod, SRC_SRCIR, 1);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,11 +389,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
|
||||||
|
|
||||||
static int rsnd_src_start(struct rsnd_mod *mod)
|
static int rsnd_src_start(struct rsnd_mod *mod)
|
||||||
{
|
{
|
||||||
/*
|
rsnd_src_initialize_unlock(mod);
|
||||||
* Cancel the initialization and operate the SRC function
|
|
||||||
* see rsnd_src_init()
|
|
||||||
*/
|
|
||||||
rsnd_mod_write(mod, SRC_SRCIR, 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -617,6 +607,14 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
|
||||||
int_val = 0;
|
int_val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND
|
||||||
|
*
|
||||||
|
* ignore over flow error when rsnd_enable_sync_convert()
|
||||||
|
*/
|
||||||
|
if (rsnd_enable_sync_convert(src))
|
||||||
|
sys_int_val = sys_int_val & 0xffff;
|
||||||
|
|
||||||
rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
|
rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
|
||||||
rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
|
rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
|
||||||
rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
|
rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
|
||||||
|
@ -632,11 +630,22 @@ static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
|
||||||
|
|
||||||
static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
|
static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
|
||||||
{
|
{
|
||||||
u32 val = OUF_SRC(rsnd_mod_id(mod));
|
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||||
|
u32 val0, val1;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) ||
|
val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
|
||||||
(rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) {
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND
|
||||||
|
*
|
||||||
|
* ignore over flow error when rsnd_enable_sync_convert()
|
||||||
|
*/
|
||||||
|
if (rsnd_enable_sync_convert(src))
|
||||||
|
val0 = val0 & 0xffff;
|
||||||
|
|
||||||
|
if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
|
||||||
|
(rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1)) {
|
||||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||||
|
|
||||||
src->err++;
|
src->err++;
|
||||||
|
@ -652,7 +661,20 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
|
||||||
static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
|
static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io)
|
struct rsnd_dai_stream *io)
|
||||||
{
|
{
|
||||||
u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
|
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = rsnd_get_dalign(mod, io);
|
||||||
|
|
||||||
|
rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND
|
||||||
|
*
|
||||||
|
* Enable SRC output if you want to use sync convert together with DVC
|
||||||
|
*/
|
||||||
|
val = (rsnd_io_to_mod_dvc(io) && !rsnd_enable_sync_convert(src)) ?
|
||||||
|
0x01 : 0x11;
|
||||||
|
|
||||||
rsnd_mod_write(mod, SRC_CTRL, val);
|
rsnd_mod_write(mod, SRC_CTRL, val);
|
||||||
|
|
||||||
|
@ -921,13 +943,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
|
||||||
if (!rsnd_rdai_is_clk_master(rdai))
|
if (!rsnd_rdai_is_clk_master(rdai))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* We can't use SRC sync convert
|
|
||||||
* if it has DVC
|
|
||||||
*/
|
|
||||||
if (rsnd_io_to_mod_dvc(io))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enable sync convert
|
* enable sync convert
|
||||||
*/
|
*/
|
||||||
|
@ -1047,10 +1062,8 @@ int rsnd_src_probe(struct platform_device *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
|
src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
|
||||||
if (!src) {
|
if (!src)
|
||||||
dev_err(dev, "SRC allocate failed\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
priv->src_nr = nr;
|
priv->src_nr = nr;
|
||||||
priv->src = src;
|
priv->src = src;
|
||||||
|
|
|
@ -770,10 +770,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
||||||
*/
|
*/
|
||||||
nr = info->ssi_info_nr;
|
nr = info->ssi_info_nr;
|
||||||
ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL);
|
ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL);
|
||||||
if (!ssi) {
|
if (!ssi)
|
||||||
dev_err(dev, "SSI allocate failed\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
priv->ssi = ssi;
|
priv->ssi = ssi;
|
||||||
priv->ssi_nr = nr;
|
priv->ssi_nr = nr;
|
||||||
|
|
Loading…
Reference in New Issue