mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge tag 'sound-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"It's been busy summer weeks and hence lots of changes, partly for a
few new drivers and partly for a wide range of fixes.
Here are highlights:
ALSA Core:
- Fix rawmidi buffer management, code cleanup / refactoring
- Fix the SG-buffer page handling with incorrect fallback size
- Fix the stall at virmidi trigger callback with a large buffer; also
offloading and code-refactoring along with it
- Various ALSA sequencer code cleanups
ASoC:
- Deploy the standard snd_pcm_stop_xrun() helper in several drivers
- Support for providing name prefixes to generic component nodes
- Quite a few fixes for DPCM as it gains a bit wider use and more
robust testing
- Generalization of the DIO2125 support to a simple amplifier driver
- Accessory detection support for the audio graph card
- DT support for PXA AC'97 devices
- Quirks for a number of new x86 systems
- Support for AM Logic Meson, Everest ES7154, Intel systems with
RT5682, Qualcomm QDSP6 and WCD9335, Realtek RT5682 and TI TAS5707
HD-audio:
- Code refactoring in HD-audio ext codec codes to drop own classes;
preliminary works for the upcoming legacy codec support
- Generalized DRM audio component for the upcoming radeon / amdgpu
support
- Unification of mic mute-LED and GPIO support for various codecs
- Further improvement of CA0132 codec support including Recon3D
- Proper vga_switcheroo handling for AMD i-GPU
- Update of model list in documentation
- Fixups for another HP Spectre x360, Conexant codecs, power-save
blacklist update
USB-audio:
- Fix the invalid sample rate setup with external clock
- Support of UAC3 selector units and processing units
- Basic UAC3 power-domain support
- Support for Encore mDSD and Thesycon-based DSD devices
- Preparation for future complete callback changes
Firewire:
- Add support for MOTU Traveler
Misc:
- The endianess notation fixes in various drivers
- Add fall-through comment in lots of drivers
- Various sparse warning fixes, e.g. about PCM format types"
* tag 'sound-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (529 commits)
ASoC: adav80x: mark expected switch fall-through
ASoC: da7219: Add delays to capture path to remove DC offset noise
ALSA: usb-audio: Mark expected switch fall-through
ALSA: mixart: Mark expected switch fall-through
ALSA: opl3: Mark expected switch fall-through
ALSA: hda/ca0132 - Add exit commands for Recon3D
ALSA: hda/ca0132 - Change mixer controls for Recon3D
ALSA: hda/ca0132 - Add Recon3D input and output select commands
ALSA: hda/ca0132 - Add DSP setup defaults for Recon3D
ALSA: hda/ca0132 - Add Recon3D startup functions and setup
ALSA: hda/ca0132 - Add bool variable to enable/disable pci region2 mmio
ALSA: hda/ca0132 - Add Recon3D pincfg
ALSA: hda/ca0132 - Add quirk ID and enum for Recon3D
ALSA: hda/ca0132 - Add alt_functions unsolicited response
ALSA: hda/ca0132 - Clean up ca0132_init function.
ALSA: hda/ca0132 - Create mmio gpio function to make code clearer
ASoC: wm_adsp: Make DSP name configurable by codec driver
ASoC: wm_adsp: Declare firmware controls from codec driver
ASoC: max98373: Added software reset register to readable registers
ASoC: wm_adsp: Correct DSP pointer for preloader control
...
This commit is contained in:
+194
-5
@@ -67,6 +67,7 @@ struct clk_core {
|
||||
unsigned long max_rate;
|
||||
unsigned long accuracy;
|
||||
int phase;
|
||||
struct clk_duty duty;
|
||||
struct hlist_head children;
|
||||
struct hlist_node child_node;
|
||||
struct hlist_head clks;
|
||||
@@ -2401,6 +2402,172 @@ int clk_get_phase(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_phase);
|
||||
|
||||
static void clk_core_reset_duty_cycle_nolock(struct clk_core *core)
|
||||
{
|
||||
/* Assume a default value of 50% */
|
||||
core->duty.num = 1;
|
||||
core->duty.den = 2;
|
||||
}
|
||||
|
||||
static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core);
|
||||
|
||||
static int clk_core_update_duty_cycle_nolock(struct clk_core *core)
|
||||
{
|
||||
struct clk_duty *duty = &core->duty;
|
||||
int ret = 0;
|
||||
|
||||
if (!core->ops->get_duty_cycle)
|
||||
return clk_core_update_duty_cycle_parent_nolock(core);
|
||||
|
||||
ret = core->ops->get_duty_cycle(core->hw, duty);
|
||||
if (ret)
|
||||
goto reset;
|
||||
|
||||
/* Don't trust the clock provider too much */
|
||||
if (duty->den == 0 || duty->num > duty->den) {
|
||||
ret = -EINVAL;
|
||||
goto reset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
reset:
|
||||
clk_core_reset_duty_cycle_nolock(core);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_core_update_duty_cycle_parent_nolock(struct clk_core *core)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (core->parent &&
|
||||
core->flags & CLK_DUTY_CYCLE_PARENT) {
|
||||
ret = clk_core_update_duty_cycle_nolock(core->parent);
|
||||
memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));
|
||||
} else {
|
||||
clk_core_reset_duty_cycle_nolock(core);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core,
|
||||
struct clk_duty *duty);
|
||||
|
||||
static int clk_core_set_duty_cycle_nolock(struct clk_core *core,
|
||||
struct clk_duty *duty)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
if (clk_core_rate_is_protected(core))
|
||||
return -EBUSY;
|
||||
|
||||
trace_clk_set_duty_cycle(core, duty);
|
||||
|
||||
if (!core->ops->set_duty_cycle)
|
||||
return clk_core_set_duty_cycle_parent_nolock(core, duty);
|
||||
|
||||
ret = core->ops->set_duty_cycle(core->hw, duty);
|
||||
if (!ret)
|
||||
memcpy(&core->duty, duty, sizeof(*duty));
|
||||
|
||||
trace_clk_set_duty_cycle_complete(core, duty);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_core_set_duty_cycle_parent_nolock(struct clk_core *core,
|
||||
struct clk_duty *duty)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (core->parent &&
|
||||
core->flags & (CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)) {
|
||||
ret = clk_core_set_duty_cycle_nolock(core->parent, duty);
|
||||
memcpy(&core->duty, &core->parent->duty, sizeof(core->duty));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal
|
||||
* @clk: clock signal source
|
||||
* @num: numerator of the duty cycle ratio to be applied
|
||||
* @den: denominator of the duty cycle ratio to be applied
|
||||
*
|
||||
* Apply the duty cycle ratio if the ratio is valid and the clock can
|
||||
* perform this operation
|
||||
*
|
||||
* Returns (0) on success, a negative errno otherwise.
|
||||
*/
|
||||
int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den)
|
||||
{
|
||||
int ret;
|
||||
struct clk_duty duty;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
/* sanity check the ratio */
|
||||
if (den == 0 || num > den)
|
||||
return -EINVAL;
|
||||
|
||||
duty.num = num;
|
||||
duty.den = den;
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
if (clk->exclusive_count)
|
||||
clk_core_rate_unprotect(clk->core);
|
||||
|
||||
ret = clk_core_set_duty_cycle_nolock(clk->core, &duty);
|
||||
|
||||
if (clk->exclusive_count)
|
||||
clk_core_rate_protect(clk->core);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_set_duty_cycle);
|
||||
|
||||
static int clk_core_get_scaled_duty_cycle(struct clk_core *core,
|
||||
unsigned int scale)
|
||||
{
|
||||
struct clk_duty *duty = &core->duty;
|
||||
int ret;
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
ret = clk_core_update_duty_cycle_nolock(core);
|
||||
if (!ret)
|
||||
ret = mult_frac(scale, duty->num, duty->den);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal
|
||||
* @clk: clock signal source
|
||||
* @scale: scaling factor to be applied to represent the ratio as an integer
|
||||
*
|
||||
* Returns the duty cycle ratio of a clock node multiplied by the provided
|
||||
* scaling factor, or negative errno on error.
|
||||
*/
|
||||
int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale)
|
||||
{
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
return clk_core_get_scaled_duty_cycle(clk->core, scale);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_scaled_duty_cycle);
|
||||
|
||||
/**
|
||||
* clk_is_match - check if two clk's point to the same hardware clock
|
||||
* @p: clk compared against q
|
||||
@@ -2454,12 +2621,13 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %-3d\n",
|
||||
seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
|
||||
level * 3 + 1, "",
|
||||
30 - level * 3, c->name,
|
||||
c->enable_count, c->prepare_count, c->protect_count,
|
||||
clk_core_get_rate(c), clk_core_get_accuracy(c),
|
||||
clk_core_get_phase(c));
|
||||
clk_core_get_phase(c),
|
||||
clk_core_get_scaled_duty_cycle(c, 100000));
|
||||
}
|
||||
|
||||
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
|
||||
@@ -2481,9 +2649,9 @@ static int clk_summary_show(struct seq_file *s, void *data)
|
||||
struct clk_core *c;
|
||||
struct hlist_head **lists = (struct hlist_head **)s->private;
|
||||
|
||||
seq_puts(s, " enable prepare protect \n");
|
||||
seq_puts(s, " clock count count count rate accuracy phase\n");
|
||||
seq_puts(s, "----------------------------------------------------------------------------------------\n");
|
||||
seq_puts(s, " enable prepare protect duty\n");
|
||||
seq_puts(s, " clock count count count rate accuracy phase cycle\n");
|
||||
seq_puts(s, "---------------------------------------------------------------------------------------------\n");
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
@@ -2510,6 +2678,8 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
|
||||
seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
|
||||
seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
|
||||
seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
|
||||
seq_printf(s, "\"duty_cycle\": %u",
|
||||
clk_core_get_scaled_duty_cycle(c, 100000));
|
||||
}
|
||||
|
||||
static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
|
||||
@@ -2571,6 +2741,7 @@ static const struct {
|
||||
ENTRY(CLK_SET_RATE_UNGATE),
|
||||
ENTRY(CLK_IS_CRITICAL),
|
||||
ENTRY(CLK_OPS_PARENT_ENABLE),
|
||||
ENTRY(CLK_DUTY_CYCLE_PARENT),
|
||||
#undef ENTRY
|
||||
};
|
||||
|
||||
@@ -2609,6 +2780,17 @@ static int possible_parents_show(struct seq_file *s, void *data)
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(possible_parents);
|
||||
|
||||
static int clk_duty_cycle_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct clk_core *core = s->private;
|
||||
struct clk_duty *duty = &core->duty;
|
||||
|
||||
seq_printf(s, "%u/%u\n", duty->num, duty->den);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
|
||||
|
||||
static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
|
||||
{
|
||||
struct dentry *root;
|
||||
@@ -2627,6 +2809,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
|
||||
debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count);
|
||||
debugfs_create_u32("clk_protect_count", 0444, root, &core->protect_count);
|
||||
debugfs_create_u32("clk_notifier_count", 0444, root, &core->notifier_count);
|
||||
debugfs_create_file("clk_duty_cycle", 0444, root, core,
|
||||
&clk_duty_cycle_fops);
|
||||
|
||||
if (core->num_parents > 1)
|
||||
debugfs_create_file("clk_possible_parents", 0444, root, core,
|
||||
@@ -2844,6 +3028,11 @@ static int __clk_core_init(struct clk_core *core)
|
||||
else
|
||||
core->phase = 0;
|
||||
|
||||
/*
|
||||
* Set clk's duty cycle.
|
||||
*/
|
||||
clk_core_update_duty_cycle_nolock(core);
|
||||
|
||||
/*
|
||||
* Set clk's rate. The preferred method is to use .recalc_rate. For
|
||||
* simple clocks and lazy developers the default fallback is to use the
|
||||
|
||||
Reference in New Issue
Block a user