···21602160 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);21612161 int val;2162216221632163- val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);21632163+ if (rt5640->jd_gpio)21642164+ val = gpiod_get_value(rt5640->jd_gpio) ? RT5640_JD_STATUS : 0;21652165+ else21662166+ val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);21672167+21642168 dev_dbg(component->dev, "irq status %#04x\n", val);2165216921662170 if (rt5640->jd_inverted)···23022298static void rt5640_jack_work(struct work_struct *work)23032299{23042300 struct rt5640_priv *rt5640 =23052305- container_of(work, struct rt5640_priv, jack_work);23012301+ container_of(work, struct rt5640_priv, jack_work.work);23062302 struct snd_soc_component *component = rt5640->component;23072303 int status;23082304···23852381 * disabled the OVCD IRQ, the IRQ pin will stay high and as23862382 * we react to edges, we miss the unplug event -> recheck.23872383 */23882388- queue_work(system_long_wq, &rt5640->jack_work);23842384+ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);23892385 }23902386}23912387···23942390 struct rt5640_priv *rt5640 = data;2395239123962392 if (rt5640->jack)23972397- queue_work(system_long_wq, &rt5640->jack_work);23932393+ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);23942394+23952395+ return IRQ_HANDLED;23962396+}23972397+23982398+static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data)23992399+{24002400+ struct rt5640_priv *rt5640 = data;24012401+24022402+ queue_delayed_work(system_long_wq, &rt5640->jack_work,24032403+ msecs_to_jiffies(JACK_SETTLE_TIME));2398240423992405 return IRQ_HANDLED;24002406}···24132399{24142400 struct rt5640_priv *rt5640 = data;2415240124162416- cancel_work_sync(&rt5640->jack_work);24022402+ cancel_delayed_work_sync(&rt5640->jack_work);24172403 cancel_delayed_work_sync(&rt5640->bp_work);24182404}24192405···24532439 if (!rt5640->jack)24542440 return;2455244124562456- free_irq(rt5640->irq, rt5640);24422442+ if (rt5640->jd_gpio_irq_requested)24432443+ free_irq(rt5640->jd_gpio_irq, rt5640);24442444+24452445+ if (rt5640->irq_requested)24462446+ free_irq(rt5640->irq, rt5640);24472447+24572448 rt5640_cancel_work(rt5640);2458244924592450 if (rt5640->jack->status & SND_JACK_MICROPHONE) {···24672448 snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);24682449 }2469245024512451+ rt5640->jd_gpio_irq_requested = false;24522452+ rt5640->irq_requested = false;24532453+ rt5640->jd_gpio = NULL;24702454 rt5640->jack = NULL;24712455}2472245624732457static void rt5640_enable_jack_detect(struct snd_soc_component *component,24742474- struct snd_soc_jack *jack)24582458+ struct snd_soc_jack *jack,24592459+ struct rt5640_set_jack_data *jack_data)24752460{24762461 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);24772462 int ret;···25192496 rt5640_enable_micbias1_ovcd_irq(component);25202497 }2521249824992499+ if (jack_data && jack_data->codec_irq_override)25002500+ rt5640->irq = jack_data->codec_irq_override;25012501+25022502+ if (jack_data && jack_data->jd_gpio) {25032503+ rt5640->jd_gpio = jack_data->jd_gpio;25042504+ rt5640->jd_gpio_irq = gpiod_to_irq(rt5640->jd_gpio);25052505+25062506+ ret = request_irq(rt5640->jd_gpio_irq, rt5640_jd_gpio_irq,25072507+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,25082508+ "rt5640-jd-gpio", rt5640);25092509+ if (ret) {25102510+ dev_warn(component->dev, "Failed to request jd GPIO IRQ %d: %d\n",25112511+ rt5640->jd_gpio_irq, ret);25122512+ rt5640_disable_jack_detect(component);25132513+ return;25142514+ }25152515+ rt5640->jd_gpio_irq_requested = true;25162516+ }25172517+25222518 ret = request_irq(rt5640->irq, rt5640_irq,25232519 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,25242520 "rt5640", rt5640);25252521 if (ret) {25262522 dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);25272527- rt5640->irq = -ENXIO;25282528- /* Undo above settings */25292523 rt5640_disable_jack_detect(component);25302524 return;25312525 }25262526+ rt5640->irq_requested = true;2532252725332528 /* sync initial jack state */25342534- queue_work(system_long_wq, &rt5640->jack_work);25292529+ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);25352530}2536253125372532static void rt5640_enable_hda_jack_detect(···25872546 }2588254725892548 /* sync initial jack state */25902590- queue_work(system_long_wq, &rt5640->jack_work);25492549+ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);25912550}2592255125932552static int rt5640_set_jack(struct snd_soc_component *component,···25992558 if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)26002559 rt5640_enable_hda_jack_detect(component, jack);26012560 else26022602- rt5640_enable_jack_detect(component, jack);25612561+ rt5640_enable_jack_detect(component, jack, data);26032562 } else {26042563 rt5640_disable_jack_detect(component);26052564 }···27782737 regcache_cache_only(rt5640->regmap, false);27792738 regcache_sync(rt5640->regmap);2780273927812781- if (rt5640->jd_src) {27402740+ if (rt5640->jack) {27822741 if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)27832742 snd_soc_component_update_bits(component,27842743 RT5640_DUMMY2, 0x1100, 0x1100);···27862745 snd_soc_component_write(component, RT5640_DUMMY2,27872746 0x4001);2788274727892789- queue_work(system_long_wq, &rt5640->jack_work);27482748+ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);27902749 }2791275027922751 return 0;···29912950 rt5640->hp_mute = true;29922951 rt5640->irq = i2c->irq;29932952 INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work);29942994- INIT_WORK(&rt5640->jack_work, rt5640_jack_work);29532953+ INIT_DELAYED_WORK(&rt5640->jack_work, rt5640_jack_work);2995295429962955 /* Make sure work is stopped on probe-error / remove */29972956 ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
+10-1
sound/soc/codecs/rt5640.h
···2124212421252125 int ldo1_en; /* GPIO for LDO1_EN */21262126 int irq;21272127+ int jd_gpio_irq;21272128 int sysclk;21282129 int sysclk_src;21292130 int lrck[RT5640_AIFS];···2137213621382137 bool hp_mute;21392138 bool asrc_en;21392139+ bool irq_requested;21402140+ bool jd_gpio_irq_requested;2140214121412142 /* Jack and button detect data */21422143 bool ovcd_irq_enabled;···21482145 int release_count;21492146 int poll_count;21502147 struct delayed_work bp_work;21512151- struct work_struct jack_work;21482148+ struct delayed_work jack_work;21522149 struct snd_soc_jack *jack;21502150+ struct gpio_desc *jd_gpio;21532151 unsigned int jd_src;21542152 bool jd_inverted;21552153 unsigned int ovcd_th;21562154 unsigned int ovcd_sf;21552155+};21562156+21572157+struct rt5640_set_jack_data {21582158+ int codec_irq_override;21592159+ struct gpio_desc *jd_gpio;21572160};2158216121592162int rt5640_dmic_enable(struct snd_soc_component *component,
···41414242 struct list_head compr_list;4343 struct list_head buffer_list;4444+4545+ /*4646+ * Flag indicating the preloader widget only needs power toggled4747+ * on state change rather than held on for the duration of the4848+ * preload, useful for devices that can retain firmware memory4949+ * across power down.5050+ */5151+ bool toggle_preload;4452};45534654#define WM_ADSP1(wname, num) \
+58-11
sound/soc/fsl/fsl_asrc.c
···1919#include "fsl_asrc.h"20202121#define IDEAL_RATIO_DECIMAL_DEPTH 262222+#define DIVIDER_NUM 6422232324#define pair_err(fmt, ...) \2425 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)···101100 0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,102101 },103102};103103+104104+/*105105+ * According to RM, the divider range is 1 ~ 8,106106+ * prescaler is power of 2 from 1 ~ 128.107107+ */108108+static int asrc_clk_divider[DIVIDER_NUM] = {109109+ 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */110110+ 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */111111+ 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */112112+ 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */113113+ 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */114114+ 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */115115+ 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */116116+ 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */117117+};118118+119119+/*120120+ * Check if the divider is available for internal ratio mode121121+ */122122+static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)123123+{124124+ u32 rem, i;125125+ u64 n;126126+127127+ if (div)128128+ *div = 0;129129+130130+ if (clk_rate == 0 || rate == 0)131131+ return false;132132+133133+ n = clk_rate;134134+ rem = do_div(n, rate);135135+136136+ if (div)137137+ *div = n;138138+139139+ if (rem != 0)140140+ return false;141141+142142+ for (i = 0; i < DIVIDER_NUM; i++) {143143+ if (n == asrc_clk_divider[i])144144+ break;145145+ }146146+147147+ if (i == DIVIDER_NUM)148148+ return false;149149+150150+ return true;151151+}104152105153/**106154 * fsl_asrc_sel_proc - Select the pre-processing and post-processing options···380330 enum asrc_word_width input_word_width;381331 enum asrc_word_width output_word_width;382332 u32 inrate, outrate, indiv, outdiv;383383- u32 clk_index[2], div[2], rem[2];333333+ u32 clk_index[2], div[2];384334 u64 clk_rate;385335 int in, out, channels;386336 int pre_proc, post_proc;387337 struct clk *clk;388388- bool ideal;338338+ bool ideal, div_avail;389339390340 if (!config) {391341 pair_err("invalid pair config\n");···465415 clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];466416467417 clk_rate = clk_get_rate(clk);468468- rem[IN] = do_div(clk_rate, inrate);469469- div[IN] = (u32)clk_rate;418418+ div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);470419471420 /*472421 * The divider range is [1, 1024], defined by the hardware. For non-···474425 * only result in different converting speeds. So remainder does not475426 * matter, as long as we keep the divider within its valid range.476427 */477477- if (div[IN] == 0 || (!ideal && (div[IN] > 1024 || rem[IN] != 0))) {428428+ if (div[IN] == 0 || (!ideal && !div_avail)) {478429 pair_err("failed to support input sample rate %dHz by asrck_%x\n",479430 inrate, clk_index[ideal ? OUT : IN]);480431 return -EINVAL;···485436 clk = asrc_priv->asrck_clk[clk_index[OUT]];486437 clk_rate = clk_get_rate(clk);487438 if (ideal && use_ideal_rate)488488- rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE);439439+ div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);489440 else490490- rem[OUT] = do_div(clk_rate, outrate);491491- div[OUT] = clk_rate;441441+ div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);492442493443 /* Output divider has the same limitation as the input one */494494- if (div[OUT] == 0 || (!ideal && (div[OUT] > 1024 || rem[OUT] != 0))) {444444+ if (div[OUT] == 0 || (!ideal && !div_avail)) {495445 pair_err("failed to support output sample rate %dHz by asrck_%x\n",496446 outrate, clk_index[OUT]);497447 return -EINVAL;···669621 clk_index = asrc_priv->clk_map[j][i];670622 clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);671623 /* Only match a perfect clock source with no remainder */672672- if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&673673- (clk_rate % rate[j]) == 0)624624+ if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))674625 break;675626 }676627