[alsa-devel] [PATCH 0/3] ALSA: Add DSP firmware loader
From: Ian Minett ian_minett@creativelabs.com
Hi Takashi, Thanks for the recent code samples, they were very useful. We've built on them to produce this latest patchset, incorporating the updates you provided to add the loader functions, and doing a minimal update to the CA0132 codec to use the new ops to perform the firmware transfer. Please let us know if any tweaks are needed to the update.
Thanks, - Ian
Signed-off-by: Ian Minett ian_minett@creativelabs.com
--- 1: - memalloc.h - pcm.h - pcm_memory.c - sgbuf.c Include Takashi's updates: Make snd_sgbuf_get_{ptr|addr}() available for non-SG cases. Passing struct snd_dma_buffer pointer instead, so that they work no matter whether real SG buffer is used or not.
2: - hda_intel.c - hda_codec.h Include Takashi's updates: Pass DMA buffer pointers in calls to setup_bdle(). Add new callback routines to controller to handle loading firmware binaries. Add new switch to Kconfig to enable DSP firmware loader.
3: - patch_ca0132.c - ca0132_regs.h Add support for DSP firmware transfer to CA0132 codec: Add transfer handler functions. Call the new snd_hda_codec_load_dsp_xxx loader ops to control download. Add chip access routines.
From: Ian Minett ian_minett@creativelabs.com
Signed-off-by: Ian Minett ian_minett@creativelabs.com
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h index c425062..9201520 100644 --- a/include/sound/memalloc.h +++ b/include/sound/memalloc.h @@ -98,8 +98,10 @@ static inline unsigned int snd_sgbuf_aligned_pages(size_t size) /* * return the physical address at the corresponding offset */ -static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset) +static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, + size_t offset) { + struct snd_sg_buf *sgbuf = dmab->private_data; dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr; addr &= PAGE_MASK; return addr + offset % PAGE_SIZE; @@ -108,10 +110,31 @@ static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t off /* * return the virtual address at the corresponding offset */ -static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset) +static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab, + size_t offset) { + struct snd_sg_buf *sgbuf = dmab->private_data; return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE; } + +unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab, + unsigned int ofs, unsigned int size); +#else +/* non-SG versions */ +static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, + size_t offset) +{ + return dmab->addr + offset; +} + +static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab, + size_t offset) +{ + return dmab->area + offset; +} + +#define snd_sgbuf_get_chunk_size(dmab, ofs, size) (size) + #endif /* CONFIG_SND_DMA_SGBUF */
/* allocate/release a buffer */ diff --git a/include/sound/pcm.h b/include/sound/pcm.h index cdca2ab..0c054b9 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -982,53 +982,42 @@ static int snd_pcm_lib_alloc_vmalloc_32_buffer _snd_pcm_lib_alloc_vmalloc_buffer \ (subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
+#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) + #ifdef CONFIG_SND_DMA_SGBUF /* * SG-buffer handling */ #define snd_pcm_substream_sgbuf(substream) \ - ((substream)->runtime->dma_buffer_p->private_data) - -static inline dma_addr_t -snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) -{ - struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream); - return snd_sgbuf_get_addr(sg, ofs); -} - -static inline void * -snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) -{ - struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream); - return snd_sgbuf_get_ptr(sg, ofs); -} + snd_pcm_get_dma_buf(substream)->private_data
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset); -unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, - unsigned int ofs, unsigned int size); - #else /* !SND_DMA_SGBUF */ /* * fake using a continuous buffer */ +#define snd_pcm_sgbuf_ops_page NULL +#endif /* SND_DMA_SGBUF */ + static inline dma_addr_t snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) { - return substream->runtime->dma_addr + ofs; + return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs); }
static inline void * snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) { - return substream->runtime->dma_area + ofs; + return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs); }
-#define snd_pcm_sgbuf_ops_page NULL - -#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size) (size) - -#endif /* SND_DMA_SGBUF */ +static inline unsigned int +snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, + unsigned int ofs, unsigned int size) +{ + return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size); +}
/* handle mmap counter - PCM mmap callback should handle this counter properly */ static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 9571313..69e01c4 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -327,32 +327,6 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne }
EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); - -/* - * compute the max chunk size with continuous pages on sg-buffer - */ -unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, - unsigned int ofs, unsigned int size) -{ - struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream); - unsigned int start, end, pg; - - start = ofs >> PAGE_SHIFT; - end = (ofs + size - 1) >> PAGE_SHIFT; - /* check page continuity */ - pg = sg->table[start].addr >> PAGE_SHIFT; - for (;;) { - start++; - if (start > end) - break; - pg++; - if ((sg->table[start].addr >> PAGE_SHIFT) != pg) - return (start << PAGE_SHIFT) - ofs; - } - /* ok, all on continuous pages */ - return size; -} -EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size); #endif /* CONFIG_SND_DMA_SGBUF */
/** diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index d0f0035..da3c619 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/mm.h> #include <linux/vmalloc.h> +#include <linux/export.h> #include <sound/memalloc.h>
@@ -136,3 +137,30 @@ void *snd_malloc_sgbuf_pages(struct device *device, snd_free_sgbuf_pages(dmab); /* free the table */ return NULL; } + + +/* + * compute the max chunk size with continuous pages on sg-buffer + */ +unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab, + unsigned int ofs, unsigned int size) +{ + struct snd_sg_buf *sg = dmab->private_data; + unsigned int start, end, pg; + + start = ofs >> PAGE_SHIFT; + end = (ofs + size - 1) >> PAGE_SHIFT; + /* check page continuity */ + pg = sg->table[start].addr >> PAGE_SHIFT; + for (;;) { + start++; + if (start > end) + break; + pg++; + if ((sg->table[start].addr >> PAGE_SHIFT) != pg) + return (start << PAGE_SHIFT) - ofs; + } + /* ok, all on continuous pages */ + return size; +} +EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
From: Ian Minett ian_minett@creativelabs.com
Signed-off-by: Ian Minett ian_minett@creativelabs.com
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 194d625..a7ff2c4 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -244,4 +244,12 @@ config SND_HDA_POWER_SAVE_DEFAULT The default time-out value in seconds for HD-audio automatic power-save mode. 0 means to disable the power-save mode.
+config SND_HDA_DSP_LOADER + bool "Enable DSP firmware loader" + depends on FW_LOADER + default y + help + Say Y here to enable the DSP firmware loader, used by certain + codecs (e.g. CA0132) to transfer their DSP binaries to the hardware. + endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1b35115..d90e1b3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2390,7 +2390,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
/* apply the function to all matching slave ctls in the mixer list */ static int map_slaves(struct hda_codec *codec, const char * const *slaves, - const char *suffix, map_slave_func_t func, void *data) + const char *suffix, map_slave_func_t func, void *data) { struct hda_nid_item *items; const char * const *s; diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 72477cc..faa3067 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -337,15 +337,15 @@ enum { #define AC_KNBCAP_DELTA (1<<7)
/* HDMI LPCM capabilities */ -#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */ +#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */ #define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */ #define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */ #define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */ -#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */ +#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */ #define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */ #define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */ #define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */ -#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */ +#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */ #define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */ #define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */ #define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */ @@ -618,6 +618,17 @@ struct hda_bus_ops { /* notify power-up/down from codec to controller */ void (*pm_notify)(struct hda_bus *bus, struct hda_codec *codec); #endif +#ifdef CONFIG_SND_HDA_DSP_LOADER + /* prepare DSP transfer */ + int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format, + unsigned int byte_size, + struct snd_dma_buffer *bufp); + /* start/stop DSP transfer */ + void (*load_dsp_trigger)(struct hda_bus *bus, bool start); + /* clean up DSP transfer */ + void (*load_dsp_cleanup)(struct hda_bus *bus, + struct snd_dma_buffer *dmab); +#endif };
/* template to pass to the bus constructor */ @@ -689,7 +700,7 @@ struct hda_codec_preset { const char *name; int (*patch)(struct hda_codec *codec); }; - + struct hda_codec_preset_list { const struct hda_codec_preset *preset; struct module *owner; @@ -1132,6 +1143,40 @@ static inline void snd_hda_power_sync(struct hda_codec *codec) int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf); #endif
+#ifdef CONFIG_SND_HDA_DSP_LOADER +static inline int +snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format, + unsigned int size, + struct snd_dma_buffer *bufp) +{ + return codec->bus->ops.load_dsp_prepare(codec->bus, format, size, bufp); +} +static inline void +snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) +{ + return codec->bus->ops.load_dsp_trigger(codec->bus, start); +} +static inline void +snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, + struct snd_dma_buffer *dmab) +{ + return codec->bus->ops.load_dsp_cleanup(codec->bus, dmab); +} +#else +static inline int +snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format, + unsigned int size, + struct snd_dma_buffer *bufp) +{ + return 0; +} +static inline void +snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {} +static inline void +snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, + struct snd_dma_buffer *dmab) {} +#endif + /* * Codec modularization */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1c9c779..248d70a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -31,7 +31,7 @@ * CHANGES: * * 2004.12.01 Major rewrite by tiwai, merged the work of pshou - * + * */
#include <linux/delay.h> @@ -600,8 +600,8 @@ static char *driver_short_names[] DELAYED_INITDATA_MARK = { [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", - [AZX_DRIVER_TERA] = "HDA Teradici", - [AZX_DRIVER_CTX] = "HDA Creative", + [AZX_DRIVER_TERA] = "HDA Teradici", + [AZX_DRIVER_CTX] = "HDA Creative", [AZX_DRIVER_CTHDA] = "HDA Creative", [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; @@ -1036,6 +1036,15 @@ static unsigned int azx_get_response(struct hda_bus *bus, static void azx_power_notify(struct hda_bus *bus, struct hda_codec *codec); #endif
+#ifdef CONFIG_SND_HDA_DSP_LOADER +static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, + unsigned int byte_size, + struct snd_dma_buffer *bufp); +static void azx_load_dsp_trigger(struct hda_bus *bus, bool start); +static void azx_load_dsp_cleanup(struct hda_bus *bus, + struct snd_dma_buffer *dmab); +#endif + /* reset codec link */ static int azx_reset(struct azx *chip, int full_reset) { @@ -1093,7 +1102,7 @@ static int azx_reset(struct azx *chip, int full_reset)
/* * Lowlevel interface - */ + */
/* enable interrupts */ static void azx_int_enable(struct azx *chip) @@ -1306,7 +1315,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) spin_unlock(&chip->reg_lock); return IRQ_NONE; } - + for (i = 0; i < chip->num_streams; i++) { azx_dev = &chip->azx_dev[i]; if (status & azx_dev->sd_int_sta_mask) { @@ -1348,7 +1357,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) azx_writeb(chip, STATESTS, 0x04); #endif spin_unlock(&chip->reg_lock); - + return IRQ_HANDLED; }
@@ -1357,7 +1366,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) * set up a BDL entry */ static int setup_bdle(struct azx *chip, - struct snd_pcm_substream *substream, + struct snd_dma_buffer *dmab, struct azx_dev *azx_dev, u32 **bdlp, int ofs, int size, int with_ioc) { @@ -1370,12 +1379,12 @@ static int setup_bdle(struct azx *chip, if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) return -EINVAL;
- addr = snd_pcm_sgbuf_get_addr(substream, ofs); + addr = snd_sgbuf_get_addr(dmab, ofs); /* program the address field of the BDL entry */ bdl[0] = cpu_to_le32((u32)addr); bdl[1] = cpu_to_le32(upper_32_bits(addr)); /* program the size field of the BDL entry */ - chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); + chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size); /* one BDLE cannot cross 4K boundary on CTHDA chips */ if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { u32 remain = 0x1000 - (ofs & 0xfff); @@ -1434,9 +1443,9 @@ static int azx_setup_periods(struct azx *chip, bdl_pos_adj[chip->dev_index]); pos_adj = 0; } else { - ofs = setup_bdle(chip, substream, azx_dev, - &bdl, ofs, pos_adj, - !substream->runtime->no_period_wakeup); + ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), + azx_dev, &bdl, ofs, pos_adj, + !substream->runtime->no_period_wakeup); if (ofs < 0) goto error; } @@ -1444,10 +1453,12 @@ static int azx_setup_periods(struct azx *chip, pos_adj = 0; for (i = 0; i < periods; i++) { if (i == periods - 1 && pos_adj) - ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, + ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), + azx_dev, &bdl, ofs, period_bytes - pos_adj, 0); else - ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, + ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), + azx_dev, &bdl, ofs, period_bytes, !substream->runtime->no_period_wakeup); if (ofs < 0) @@ -1609,6 +1620,11 @@ static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *mode bus_temp.power_save = &power_save; bus_temp.ops.pm_notify = azx_power_notify; #endif +#ifdef CONFIG_SND_HDA_DSP_LOADER + bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare; + bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger; + bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup; +#endif
err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); if (err < 0) @@ -2462,6 +2478,93 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_SND_HDA_POWER_SAVE */
+#ifdef CONFIG_SND_HDA_DSP_LOADER +/* + * DSP loading code (e.g. for CA0132) + */ + +/*use the first stream for loading DSP*/ +static struct azx_dev* +azx_get_dsp_loader_dev(struct azx *chip) +{ + return &chip->azx_dev[chip->playback_index_offset]; +} + +static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, + unsigned int byte_size, + struct snd_dma_buffer *bufp) +{ + u32 *bdl; + struct azx *chip = bus->private_data; + struct azx_dev *azx_dev; + int err; + + if (snd_hda_lock_devices(bus)) + return -EBUSY; + + err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + byte_size, bufp); + if (err < 0) + goto error; + + azx_dev = azx_get_dsp_loader_dev(chip); + azx_dev->bufsize = byte_size; + azx_dev->period_bytes = byte_size; + azx_dev->format_val = format; + + azx_stream_reset(chip, azx_dev); + + /* reset BDL address */ + azx_sd_writel(azx_dev, SD_BDLPL, 0); + azx_sd_writel(azx_dev, SD_BDLPU, 0); + + azx_dev->frags = 0; + bdl = (u32 *)azx_dev->bdl.area; + err = setup_bdle(chip, bufp, azx_dev, &bdl, 0, byte_size, 0); + if (err < 0) + goto error; + + azx_setup_controller(chip, azx_dev); + return azx_dev->stream_tag; + +error: + snd_hda_unlock_devices(bus); + return err; +} + +static void azx_load_dsp_trigger(struct hda_bus *bus, bool start) +{ + struct azx *chip = bus->private_data; + struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip); + + if (start) + azx_stream_start(chip, azx_dev); + else + azx_stream_stop(chip, azx_dev); + azx_dev->running = start; +} + +static void azx_load_dsp_cleanup(struct hda_bus *bus, + struct snd_dma_buffer *dmab) +{ + struct azx *chip = bus->private_data; + struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip); + + /* reset BDL address */ + azx_sd_writel(azx_dev, SD_BDLPL, 0); + azx_sd_writel(azx_dev, SD_BDLPU, 0); + azx_sd_writel(azx_dev, SD_CTL, 0); + azx_dev->bufsize = 0; + azx_dev->period_bytes = 0; + azx_dev->format_val = 0; + + snd_dma_free_pages(dmab); + + snd_hda_unlock_devices(bus); +} +#endif /* CONFIG_SND_HDA_DSP_LOADER */ + #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management
At Thu, 30 Aug 2012 13:21:03 -0700, Ian Minett wrote:
From: Ian Minett ian_minett@creativelabs.com
Hi Takashi, Thanks for the recent code samples, they were very useful. We've built on them to produce this latest patchset, incorporating the updates you provided to add the loader functions, and doing a minimal update to the CA0132 codec to use the new ops to perform the firmware transfer. Please let us know if any tweaks are needed to the update.
Thanks for the patches, and sorry for the late response, as I was traveling for KS and Plumbers.
Looking at the new codes now... well, the first two patches are almost what I wrote. In such a case, you must not change the authorship. Keep the git commit author as me.
The third one, the most essential part in the whole patch series, is still fairly difficult to read. Basically a few things are missing:
- No comment to functions. Most of functions look obvious, but still better to describe the fundamental mechanism of the DSP loading on CA0132. And give descriptions to arguments that aren't pretty intuitive (e.g. how router_chans, reloc or ovly influence on behavior.)
- No comment is given to registers. Hard to guess what's XRAM, YRAM, UC or whatever. Brief and concise descriptions are appreciated.
- Home-baked debug macros like SUCCEEDED(), CTASSERT(), CA0132_LOG() or FAIL_MSG() should be avoided. You might think a hack like FAIL_MSG() is great, but it isn't -- even though it saves lines, it hinders the code reading unless readers learn this new code flow condition.
- Because of the big code shuffling (likely too many lines have been inserted in the middle), the patch generation wasn't optimal. For example, you can see chipio_send() is completely added and then deleted in the patch although the function itself isn't changed at all. You can avoided this by carefully putting the new codes in the file. Or some git option might give a better result...
- Why hda_stream_format is defined?
- You need proper ifdefs in patch_ca0132.c for the case without CONFIG_SND_HDA_DSP_LOADER.
- The firmware data must be cached and reloaded upon PM resume.
Also, you fixed some space issues in the patch. If a clean-up is really needed, do it in a separate patch, and don't mix it in this patch.
thanks,
Takashi
participants (2)
-
Ian Minett
-
Takashi Iwai