Intel SST driver update
cover Intel SST driver update
This is a forward port of various further Intel work on the SST driver in staging. This keeps the staging driver up to date while the ALSA driver development continues.
Alan
---
Andy CH Lin (1):
intel_sst: intelmid_v2_control: correct jack event type
Chandramouli Narayanan (1):
intel_sst: fix runtime pm issue
Dharageswari R (1):
intel_sst: Line out support
Feng Tang (1):
intel_sst: make sure the sst_drop_stream() get called when needed
Lu Guanqun (9):
intel_sst: fix output noises when it's not in playback
sst: internal speaker needs setting a GPIO line
intel_sst: add Master Volume
sst: set default output and input device
sst: return correct output/input device id
intel_sst: move jack detection related configs to init time
intel_sst: Enable recording via DMIC
intel_sst: Enable recording via HS_MIC
intel_sst: Set de-bounce time
Ramesh Babu K V (1):
intel_sst: rework jack implementation
Sitanshu Nanavati (1):
intel_sst: DMIC routing
Vinod Koul (5):
intel_sst: parameter tuning ioctl
intel_sst: ignore IRQ when suspended
intel_sst: fix unload bugs
intel_sst: MSIC codec power optimisation
intel_sst: Save audio state across D3 on Medfield
Wu Fengguang (2):
intel_sst: MRST can only do 16bit recording
intel_sst: MRST can only do mono recording
xingchao (1):
intel_sst: Headphone Automute support
drivers/staging/intel_sst/intel_sst.c | 129 +++ drivers/staging/intel_sst/intel_sst.h | 33 + .../staging/intel_sst/intel_sst_app_interface.c | 37 + drivers/staging/intel_sst/intel_sst_common.h | 9 .../staging/intel_sst/intel_sst_drv_interface.c | 23 - drivers/staging/intel_sst/intel_sst_dsp.c | 14 drivers/staging/intel_sst/intel_sst_fw_ipc.h | 7 drivers/staging/intel_sst/intel_sst_ioctl.h | 8 drivers/staging/intel_sst/intel_sst_ipc.c | 74 ++ drivers/staging/intel_sst/intel_sst_stream.c | 15 .../staging/intel_sst/intel_sst_stream_encoded.c | 8 drivers/staging/intel_sst/intelmid.c | 473 +++-------- drivers/staging/intel_sst/intelmid.h | 38 + drivers/staging/intel_sst/intelmid_adc_control.h | 193 +++++ drivers/staging/intel_sst/intelmid_ctrl.c | 304 +++++++ drivers/staging/intel_sst/intelmid_msic_control.c | 833 ++++++++++++++++++-- drivers/staging/intel_sst/intelmid_pvt.c | 1 drivers/staging/intel_sst/intelmid_snd_control.h | 9 drivers/staging/intel_sst/intelmid_v0_control.c | 109 ++- drivers/staging/intel_sst/intelmid_v1_control.c | 141 +++ drivers/staging/intel_sst/intelmid_v2_control.c | 219 ++++- drivers/staging/intel_sst/jack.h | 10 22 files changed, 2125 insertions(+), 562 deletions(-) create mode 100644 drivers/staging/intel_sst/intelmid_adc_control.h delete mode 100644 drivers/staging/intel_sst/jack.h
Signature · 2 lines
"Policy is a poor man's substitute for common sense." -- David Woodhouse
PATCH 1/23 intel_sst: Save audio state across D3 on Medfield
From: Vinod Koul <[email protected]>
During suspend and runtime_suspend audio dsp will be in D3 state and will loose its context.
This patch adds support in driver to save the dsp context and restore this context during resume
---
drivers/staging/intel_sst/intel_sst.c | 67 +++++++++++++++++++- drivers/staging/intel_sst/intel_sst_common.h | 9 ++- .../staging/intel_sst/intel_sst_drv_interface.c | 2 + drivers/staging/intel_sst/intel_sst_dsp.c | 14 +++- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 6 ++ drivers/staging/intel_sst/intel_sst_ipc.c | 56 ++++++++++++++++- drivers/staging/intel_sst/intel_sst_stream.c | 11 ++- .../staging/intel_sst/intel_sst_stream_encoded.c | 8 +- drivers/staging/intel_sst/intelmid.c | 2 - 9 files changed, 148 insertions(+), 27 deletions(-)
drivers/staging/intel_sst/intel_sst.c +63 -4
@@ -316,9 +316,25 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,if (sst_drv_ctx->pci_id ==SST_MRST_PCI_ID ) { ret =misc_register (&lpe_dev);if (ret) { -pr_err ("couldn't register misc driver\n" ); +pr_err ("couldn't register LPE device\n" ); goto do_free_misc; } + }else if (sst_drv_ctx->pci_id ==SST_MFLD_PCI_ID ) { +u32 csr; + +/*allocate mem for fw context save during suspend*/ + sst_drv_ctx->fw_cntx =kzalloc (FW_CONTEXT_MEM ,GFP_KERNEL ); +if (!sst_drv_ctx->fw_cntx) { + ret = -ENOMEM ; + goto do_free_misc; + } +/*setting zero as that is valid mem to restore*/ + sst_drv_ctx->fw_cntx_size =0 ; + +/*set lpe start clock and ram size*/ + csr =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr |=0x30060 ;/*remove the clock ratio after fw fix*/ +sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr); } sst_drv_ctx->lpe_stalled =0 ;pm_runtime_set_active (&pci->dev);
@@ -374,16 +390,17 @@ static void __devexit intel_sst_remove(struct pci_dev *pci) sst_drv_ctx->sst_state =SST_UN_INIT ;mutex_unlock (&sst_drv_ctx->sst_lock);misc_deregister (&lpe_ctrl); -if (sst_drv_ctx->pci_id ==SST_MRST_PCI_ID ) -misc_deregister (&lpe_dev);free_irq (pci->irq, sst_drv_ctx);iounmap (sst_drv_ctx->dram);iounmap (sst_drv_ctx->iram);iounmap (sst_drv_ctx->mailbox);iounmap (sst_drv_ctx->shim); sst_drv_ctx->pmic_state =SND_MAD_UN_INIT ; -if (sst_drv_ctx->pci_id ==SST_MRST_PCI_ID ) +if (sst_drv_ctx->pci_id ==SST_MRST_PCI_ID ) { +misc_deregister (&lpe_dev);kfree (sst_drv_ctx->mmap_mem); + }else +kfree (sst_drv_ctx->fw_cntx);flush_scheduled_work ();destroy_workqueue (sst_drv_ctx->process_reply_wq);destroy_workqueue (sst_drv_ctx->process_msg_wq);
@@ -398,6 +415,46 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)pci_set_drvdata (pci,NULL ); } +void sst_save_dsp_context (void ) +{ +struct snd_sst_ctxt_params fw_context; +unsigned int pvt_id, i; +struct ipc_post *msg =NULL ; + +/*check cpu type*/ +if (sst_drv_ctx->pci_id !=SST_MFLD_PCI_ID ) +return ; +/*not supported for rest*/ +if (sst_drv_ctx->sst_state !=SST_FW_RUNNING ) { +pr_debug ("fw not running no context save ...\n" ); +return ; + } + +/*send msg to fw*/ +if (sst_create_large_msg (&msg)) +return ; + pvt_id =sst_assign_pvt_id (sst_drv_ctx); + i =sst_get_block_stream (sst_drv_ctx); + sst_drv_ctx->alloc_block[i].sst_id = pvt_id; +sst_fill_header (&msg->header,IPC_IA_GET_FW_CTXT ,1 , pvt_id); + msg->header.part.data =sizeof (fw_context) +sizeof (u32); + fw_context.address =virt_to_phys ((void *)sst_drv_ctx->fw_cntx); + fw_context.size =FW_CONTEXT_MEM ; +memcpy (msg->mailbox_data, &msg->header,sizeof (u32)); +memcpy (msg->mailbox_data +sizeof (u32), + &fw_context,sizeof (fw_context)); +spin_lock (&sst_drv_ctx->list_spin_lock); +list_add_tail (&msg->node, &sst_drv_ctx->ipc_dispatch_list); +spin_unlock (&sst_drv_ctx->list_spin_lock); +sst_post_message (&sst_drv_ctx->ipc_post_msg_wq); +/*wait for reply*/ +if (sst_wait_timeout (sst_drv_ctx, &sst_drv_ctx->alloc_block[i])) +pr_debug ("err fw context save timeout ...\n" ); + sst_drv_ctx->alloc_block[i].sst_id =BLOCK_UNINIT ; +pr_debug ("fw context saved ...\n" ); +return ; +} +/* Power Management */ /* * intel_sst_suspend - PCI suspend function
@@ -417,6 +474,8 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state)pr_err ("active streams,not able to suspend\n" );return -EBUSY ; } +/*save fw context*/ +sst_save_dsp_context ();/*Assert RESET on LPE Processor*/ csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); csr.full = csr.full |0x2 ;
drivers/staging/intel_sst/intel_sst_common.h +6 -3
@@ -28,8 +28,8 @@* Common private declarations for SST */ -#define SST_DRIVER_VERSION "1.2.09" -#define SST_VERSION_NUM 0x1209 +#define SST_DRIVER_VERSION "1.2.11" +#define SST_VERSION_NUM 0x1211/* driver names */ #define SST_DRV_NAME "intel_sst_driver"
@@ -37,6 +37,7 @@#define SST_MFLD_PCI_ID 0x082F#define PCI_ID_LENGTH 4#define SST_SUSPEND_DELAY 2000 +#define FW_CONTEXT_MEM (64*1024)enum sst_states {SST_FW_LOADED =1 ,
@@ -94,7 +95,7 @@ enum sst_ram_type {/* SST shim registers to structure mapping */ union config_status_reg {struct { -u32 rsvd0:1 ; +u32 mfld_strb:1 ;u32 sst_reset:1 ;u32 hw_rsvd:3 ;u32 sst_clk:2 ;
@@ -417,6 +418,8 @@ struct intel_sst_drv {unsigned int audio_start;dev_t devt_d, devt_c;unsigned int max_streams; +unsigned int *fw_cntx; +unsigned int fw_cntx_size; };extern struct intel_sst_drv *sst_drv_ctx;
drivers/staging/intel_sst/intel_sst_drv_interface.c +2 -0
@@ -508,6 +508,7 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_drv_ctx->pmic_state =SND_MAD_INIT_DONE ; sst_drv_ctx->rx_time_slot_status =0 ;/*default AMIC*/ card->pcm_control = sst_pmic_ops.pcm_control; + sst_drv_ctx->scard_ops->card_status =SND_CARD_UN_INIT ;return 0 ; }else {pr_err ("strcmp fail %s\n" , card->module_name);
@@ -519,6 +520,7 @@ int register_sst_card(struct intel_sst_card_ops *card)pr_err ("Repeat for registration..denied\n" );return -EBADRQC ; } + sst_drv_ctx->scard_ops->card_status =SND_CARD_UN_INIT ;return 0 ; }EXPORT_SYMBOL_GPL (register_sst_card);
drivers/staging/intel_sst/intel_sst_dsp.c +10 -4
@@ -73,7 +73,8 @@ static int intel_sst_reset_dsp_medfield(void)union config_status_reg csr;pr_debug ("Resetting the DSP in medfield\n" ); - csr.full =0x048303E2 ; + csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr.full |=0x382 ;sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr.full);return 0 ;
@@ -109,11 +110,16 @@ static int sst_start_medfield(void) {union config_status_reg csr; - csr.full =0x04830062 ; + csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr.part.bypass =0 ;sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr.full); - csr.full =0x04830063 ; + csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr.part.mfld_strb =1 ;sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr.full); - csr.full =0x04830061 ; + csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr.part.run_stall =0 ; + csr.part.sst_reset =0 ; +pr_debug ("Starting the DSP_medfld %x\n" , csr.full);sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr.full);pr_debug ("Starting the DSP_medfld\n" );
drivers/staging/intel_sst/intel_sst_fw_ipc.h +6 -0
@@ -56,6 +56,8 @@#define IPC_IA_GET_FW_VERSION 0x04#define IPC_IA_GET_FW_BUILD_INF 0x05#define IPC_IA_GET_FW_INFO 0x06 +#define IPC_IA_GET_FW_CTXT 0x07 +#define IPC_IA_SET_FW_CTXT 0x08/* I2L Codec Config/control msgs */ #define IPC_IA_SET_CODEC_PARAMS 0x10
@@ -406,4 +408,8 @@ struct ipc_post { char *mailbox_data; }; +struct snd_sst_ctxt_params { +u32 address;/* Physical Address in DDR where the context is stored */ +u32 size;/* size of the context */ +};#endif /* __INTEL_SST_FW_IPC_H__ */
drivers/staging/intel_sst/intel_sst_ipc.c +52 -4
89 lines not on this page · raw message
drivers/staging/intel_sst/intel_sst_stream.c +7 -4
@@ -31,6 +31,7 @@#include <linux/pci.h> #include <linux/firmware.h> #include <linux/sched.h> +#include <linux/delay.h> #include "intel_sst_ioctl.h" #include "intel_sst.h" #include "intel_sst_fw_ipc.h"
@@ -519,10 +520,6 @@ int sst_drain_stream(int str_id) str_info->data_blk.on = true; retval =sst_wait_interruptible (sst_drv_ctx, &str_info->data_blk); str_info->need_draining = false; -if (retval == -SST_ERR_INVALID_STREAM_ID ) { - retval = -EINVAL ; -sst_clean_stream (str_info); - }return retval; }
@@ -563,6 +560,12 @@ int sst_free_stream(int str_id) str_info->data_blk.ret_code =0 ;wake_up (&sst_drv_ctx->wait_queue); } + str_info->data_blk.on = true; + str_info->data_blk.condition = false; + retval =sst_wait_interruptible_timeout (sst_drv_ctx, + &str_info->ctrl_blk,SST_BLOCK_TIMEOUT ); +pr_debug ("wait for free returned %d\n" , retval); +msleep (100 );mutex_lock (&sst_drv_ctx->stream_lock);sst_clean_stream (str_info);mutex_unlock (&sst_drv_ctx->stream_lock);
drivers/staging/intel_sst/intel_sst_stream_encoded.c +2 -6
@@ -363,7 +363,6 @@ int sst_parse_target(struct snd_sst_slot_info *slot)pr_err ("SST_Activate_target_fail\n" ); else pr_err("SST_Activate_target_pass\n"); -return retval; }else if (slot->action ==SND_SST_PORT_PREPARE && slot->device_type ==SND_SST_DEVICE_PCM ) { retval =sst_prepare_target (slot);
@@ -371,12 +370,11 @@ int sst_parse_target(struct snd_sst_slot_info *slot)pr_err ("SST_prepare_target_fail\n" ); else pr_err("SST_prepare_target_pass\n"); -return retval; }else {pr_err ("slot_action : %d, device_type: %d\n" , slot->action, slot->device_type); -return retval; } +return retval; }int sst_send_target (struct snd_sst_target_device *target)
@@ -886,8 +884,7 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info, int *input_index, int *in_copied, int *input_index_valid_size, int *new_entry_flag) { - int retval = 0; -int i; + int retval = 0, i;if (str_info->ops ==STREAM_OPS_PLAYBACK_DRM ) {struct RAR_buffer rar_buffers;
@@ -924,7 +921,6 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info,return retval; }#endif -/*This function is used to prepare the kernel input buffers with contents before sending for decode*/ static int sst_prepare_input_buffers(struct stream_info *str_info,
drivers/staging/intel_sst/intelmid.c +0 -2
@@ -805,8 +805,6 @@ static int __devinit snd_intelmad_sst_register(pr_err ("sst card registration failed\n" );return ret_val; } - sst_drv_ctx->scard_ops->card_status =SND_CARD_UN_INIT ; - sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id; intelmaddata->pmic_status =PMIC_UNINIT ;return ret_val;
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 11 lines · Alan Cox
From: Vinod Koul <[email protected]>
During suspend and
runtime_suspendaudio dsp will be in D3 state and will loose its context.This patch adds support in driver to save the dsp context and restore this context during resume
Signed-off-by Vinod Koul <[email protected]>Signed-off-by Ramesh Babu K V <[email protected]>Signed-off-by Alan Cox <[email protected]>
Something is messed up here as:
drivers/staging/intel_sst/intel_sst_drv_interface.c int register_sst_card(struct intel_sst_card_ops *card) · line 514
Quoted 10 lines
drivers/staging/intel_sst/intel_sst_drv_interface.c +1
-0@@ -508,6 +508,7 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_drv_ctx->pmic_state =SND_MAD_INIT_DONE ; sst_drv_ctx->rx_time_slot_status =0 ;/*default AMIC*/ card->pcm_control = sst_pmic_ops.pcm_control; + sst_drv_ctx->scard_ops->card_status =SND_CARD_UN_INIT ;return 0 ; }else {pr_err ("strcmp fail %s\n" , card->module_name);
This line is in the original patch from Vinod in this function that added the driver to the tree (git commit id fffa1cca), so the patch doesn't apply at all. Do you see this too?
If I comment out this chunk, the patch fails later on as well:
patching file drivers/staging/intel_sst/intelmid.c
Hunk #1 FAILED at 805.
1 out of 1 hunk FAILED -- saving rejects to file drivers/staging/intel_sst/intelmid.c.rej
Which is odd.
What tree did you generate this series against? I don't have any outstanding sst patches in my "to-apply" queue, did I miss some that you previously sent that I should have applied first?
confused,
greg k-h
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 6 lines
Quoted 3 lines
Signed-off-by Vinod Koul <[email protected]>Signed-off-by Ramesh Babu K V <[email protected]>Signed-off-by Alan Cox <[email protected]>Something is messed up here as:
Quoted 14 lines
drivers/staging/intel_sst/intel_sst_drv_interface.c int register_sst_card(struct intel_sst_card_ops *card) · line 514
Quoted 10 lines
drivers/staging/intel_sst/intel_sst_drv_interface.c +1
-0@@ -508,6 +508,7 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_drv_ctx->pmic_state =SND_MAD_INIT_DONE ; sst_drv_ctx->rx_time_slot_status =0 ;/*default AMIC*/ card->pcm_control = sst_pmic_ops.pcm_control; + sst_drv_ctx->scard_ops->card_status =SND_CARD_UN_INIT ;return 0 ; }else {pr_err ("strcmp fail %s\n" , card->module_name);This line is in the original patch from Vinod in this function that added the driver to the tree (git commit id
fffa1cca), so the patch doesn't apply at all. Do you see this too?
I see it present in ffa1cca then removed then added back
I see the problem - Mark Brown took a patch in staging via the ASoC tree which clashes with this.
fa880004682cf0d10e7a7c71dc8d56bbd67ac3d5
which is not only a staging patch but also breaks compilation of the code because the sst_drv_ctx symbol isn't even exported or visible to the intelmid module, which suggests it wasn't even compile tested.
Best plan seems to be for the patch Mark took to go into the staging tree as well, and I'll then rebuild the patch stack on top of it and fix the fact it didn't even build.
In general we have a bigger problem here, the ASoC driver appears to be violating rule #1 of staging - nothing outside of staging should be using or depending upon staging code in the first place.
Alan
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 8 lines · Alan Cox
I see the problem - Mark Brown took a patch in staging via the ASoC tree which clashes with this.
fa880004682cf0d10e7a7c71dc8d56bbd67ac3d5which is not only a staging patch but also breaks compilation of the code because the
sst_drv_ctxsymbol isn't even exported or visible to the intelmid module, which suggests it wasn't even compile tested.
I am assured that this patch is essential to build with the Intel drivers that are currently upstream in ASoC, though I've not personally verified that. I'd not be surprised if the tests whoever submitted it did had only been done with the module built in, though I'd have expected whatever tests people do on -next to pick that up since x86 seems to be a popular target there.
Quoted 3 lines
In general we have a bigger problem here, the ASoC driver appears to be violating rule #1 of staging - nothing outside of staging should be using or depending upon staging code in the first place.
To recap the previous discussion: staging is just not in the slightest bit viable for ASoC stuff, code that does anything non-trivial is going to get broken between releases. Especially with something like this where the drivers are for unreleased hardware that has no current end users it's just not a problem for the core if drivers do stuff like this so long as they don't do anything visibly bad or cause problems for the people who do build test whatever architecture is affected.
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 2 lines
To recap the previous discussion: staging is just not in the slightest bit viable for ASoC stuff, code that does anything non-trivial is going
Yes I know that - and its active development of a nice clean driver going on upstream so doesn't belong there anyway. The ASoC driver should probably have its own copy of the bits of the staging driver that it needs however.
I can fix this collision up easily enough and if doing it not via the rules is best fine by me. I think it might be wiser however if the ASoC driver took its own copy of the bits it actually needed.
Alan
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 11 lines · Alan Cox
Quoted 2 lines
To recap the previous discussion: staging is just not in the slightest bit viable for ASoC stuff, code that does anything non-trivial is going
Yes I know that - and its active development of a nice clean driver going on upstream so doesn't belong there anyway. The ASoC driver should probably have its own copy of the bits of the staging driver that it needs however.
I can fix this collision up easily enough and if doing it not via the rules is best fine by me. I think it might be wiser however if the ASoC driver took its own copy of the bits it actually needed.
That sounds like a good idea.
Mark, can you try to let me know if you are patching staging code? If you want to "own" a driver in the staging tree, that's fine, just let me konw and I'll funnel patches to you for it (we do that for other staging drivers).
It's just that for times like this, when I have no idea that someone else modified it in linux-next, and then patches fail to apply, that it gets messy.
thanks,
greg k-h
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 4 lines · Greg KH
Mark, can you try to let me know if you are patching staging code? If you want to "own" a driver in the staging tree, that's fine, just let me konw and I'll funnel patches to you for it (we do that for other staging drivers).
I CCed you in on the thread where the patch was applied. Probably you forgot about it as it was described as a build fix for my tree.
I'm not really that interested in the Intel patches in staging, the bulk of them require a from scratch rewrite to go upstream as they're so far from following the Linux driver model for these things.
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 9 lines · Mark Brown
Quoted 4 lines · Greg KH
Mark, can you try to let me know if you are patching staging code? If you want to "own" a driver in the staging tree, that's fine, just let me konw and I'll funnel patches to you for it (we do that for other staging drivers).
I CCed you in on the thread where the patch was applied. Probably you forgot about it as it was described as a build fix for my tree.
I must have, sorry about that.
Quoted 3 lines
I'm not really that interested in the Intel patches in staging, the bulk of them require a from scratch rewrite to go upstream as they're so far from following the Linux driver model for these things.
Ok, then I guess I can handle them.
Alan, how do you want to go about sending patches that we can apply somehow?
thanks,
greg k-h
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 8 lines
Quoted 3 lines
I'm not really that interested in the Intel patches in staging, the bulk of them require a from scratch rewrite to go upstream as they're so far from following the Linux driver model for these things.
Ok, then I guess I can handle them.
Alan, how do you want to go about sending patches that we can apply somehow?
Best bet is to apply Mark's patch into your git tree then apply mine on top I think. Git will see the same patch in both trees and resolve it all nicely for -next.
Alan
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 4 lines · Alan Cox
Quoted 4 lines
Quoted 3 lines
I'm not really that interested in the Intel patches in staging, the bulk of them require a from scratch rewrite to go upstream as they're so far from following the Linux driver model for these things.
Quoted 8 lines
Quoted 4 lines
Ok, then I guess I can handle them.
Alan, how do you want to go about sending patches that we can apply somehow?
Best bet is to apply Mark's patch into your git tree then apply mine on top I think. Git will see the same patch in both trees and resolve it all nicely for -next.
Have a pointer to which patch that was?
thanks,
greg k-h
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 7 lines · Greg KH
Quoted 3 lines · Alan Cox
Best bet is to apply Mark's patch into your git tree then apply mine on top I think. Git will see the same patch in both trees and resolve it all nicely for -next.
Have a pointer to which patch that was?
It's 774fd7 (sst: fix compile error) which is in -next.
Re: [PATCH 01/23] intel_sst: Save audio state across D3 on Medfield
Quoted 10 lines · Mark Brown
Quoted 7 lines · Greg KH
Quoted 3 lines · Alan Cox
Best bet is to apply Mark's patch into your git tree then apply mine on top I think. Git will see the same patch in both trees and resolve it all nicely for -next.
Have a pointer to which patch that was?
It's 774fd7 (sst: fix compile error) which is in -next.
That's one of the, I needed another as well :)
Anyway, I've queued all of these up now so hopefully we should all be in sync correctly.
thanks,
greg k-h
PATCH 2/23 intel_sst: MSIC codec power optimisation
In reply to Alan CoxFrom: Vinod Koul <[email protected]>
This patch adds power optimization for the msic codec and ensure codec is completely powered off when codec is idle.
---
drivers/staging/intel_sst/intel_sst.h | 4 .../staging/intel_sst/intel_sst_drv_interface.c | 10 - drivers/staging/intel_sst/intelmid_msic_control.c | 275 ++++++++++++++------ drivers/staging/intel_sst/intelmid_v0_control.c | 4 drivers/staging/intel_sst/intelmid_v1_control.c | 4 drivers/staging/intel_sst/intelmid_v2_control.c | 4 6 files changed, 201 insertions(+), 100 deletions(-)
drivers/staging/intel_sst/intel_sst.h +2 -2
@@ -103,8 +103,8 @@ struct snd_pmic_ops {int (*power_up_pmic_pb) (unsigned int port);int (*power_up_pmic_cp) (unsigned int port); -int (*power_down_pmic_pb) (void ); -int (*power_down_pmic_cp) (void ); +int (*power_down_pmic_pb) (unsigned int device); +int (*power_down_pmic_cp) (unsigned int device);int (*power_down_pmic) (void ); };
drivers/staging/intel_sst/intel_sst_drv_interface.c +6 -4
@@ -105,21 +105,23 @@ void free_stream_context(unsigned int str_id)if (!sst_validate_strid (str_id)) {/* str_id is valid, so stream is alloacted */ stream = &sst_drv_ctx->streams[str_id]; +if (sst_free_stream (str_id)) +sst_clean_stream (&sst_drv_ctx->streams[str_id]);if (stream->ops ==STREAM_OPS_PLAYBACK || stream->ops ==STREAM_OPS_PLAYBACK_DRM ) { sst_drv_ctx->pb_streams--;if (sst_drv_ctx->pb_streams ==0 ) - sst_drv_ctx->scard_ops->power_down_pmic_pb (); + sst_drv_ctx->scard_ops->power_down_pmic_pb ( + stream->device); }else if (stream->ops ==STREAM_OPS_CAPTURE ) { sst_drv_ctx->cp_streams--;if (sst_drv_ctx->cp_streams ==0 ) - sst_drv_ctx->scard_ops->power_down_pmic_cp (); + sst_drv_ctx->scard_ops->power_down_pmic_cp ( + stream->device); }if (sst_drv_ctx->pb_streams ==0 && sst_drv_ctx->cp_streams ==0 ) sst_drv_ctx->scard_ops->power_down_pmic (); -if (sst_free_stream (str_id)) -sst_clean_stream (&sst_drv_ctx->streams[str_id]); } }
drivers/staging/intel_sst/intelmid_msic_control.c +187 -88
422 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_v0_control.c +2 -2
@@ -157,7 +157,7 @@ static int fs_power_up_pb(unsigned int port)return fs_enable_audiodac (UNMUTE ); } -static int fs_power_down_pb (void ) +static int fs_power_down_pb (unsigned int device) {struct sc_reg_access sc_access[] = { {POWERCTRL1 ,0x00 ,0xC6 },
@@ -195,7 +195,7 @@ static int fs_power_up_cp(unsigned int port)return sst_sc_reg_access (sc_access,PMIC_READ_MODIFY ,2 ); } -static int fs_power_down_cp (void ) +static int fs_power_down_cp (unsigned int device) {struct sc_reg_access sc_access[] = { {POWERCTRL2 ,0x00 ,0x03 },
drivers/staging/intel_sst/intelmid_v1_control.c +2 -2
@@ -212,7 +212,7 @@ static int mx_power_up_pb(unsigned int port)return mx_enable_audiodac (UNMUTE ); } -static int mx_power_down_pb (void ) +static int mx_power_down_pb (unsigned int device) {struct sc_reg_access sc_access[3 ];int retval =0 ;
@@ -255,7 +255,7 @@ static int mx_power_up_cp(unsigned int port)return sst_sc_reg_access (sc_access,PMIC_READ_MODIFY ,2 ); } -static int mx_power_down_cp (void ) +static int mx_power_down_cp (unsigned int device) {struct sc_reg_access sc_access[] = { {ENABLE_OPDEV_CTRL ,0x00 ,MASK1 |MASK0 },
drivers/staging/intel_sst/intelmid_v2_control.c +2 -2
@@ -316,7 +316,7 @@ static int nc_power_down(void)return nc_enable_audiodac (UNMUTE ); } -static int nc_power_down_pb (void ) +static int nc_power_down_pb (unsigned int device) {int retval =0 ;
@@ -360,7 +360,7 @@ static int nc_power_down_pb(void) } -static int nc_power_down_cp (void ) +static int nc_power_down_cp (unsigned int device) {struct sc_reg_access sc_access[] = { {POWERCTRL1 ,0x00 ,0xBE },
Re: [PATCH 02/23] intel_sst: MSIC codec power optimisation
Quoted 4 lines · Alan Cox
From: Vinod Koul <[email protected]>
This patch adds power optimization for the msic codec and ensure codec is completely powered off when codec is idle.
Once you move over to proper CODEC drivers the core will take care of this stuff for you.
Re: [PATCH 02/23] intel_sst: MSIC codec power optimisation
Quoted 9 lines · On Tue, 3 May 2011 17:58:38 +0100 Mark Brown…
Quoted 4 lines · Alan Cox
From: Vinod Koul <[email protected]>
This patch adds power optimization for the msic codec and ensure codec is completely powered off when codec is idle.
Once you move over to proper CODEC drivers the core will take care of this stuff for you.
Please see 00/23
"This is a forward port of various further Intel work on the SST driver in staging. This keeps the staging driver up to date while the ALSA driver development continues."
Alan
Re: [PATCH 02/23] intel_sst: MSIC codec power optimisation
Quoted 10 lines · Alan Cox
Quoted 2 lines · Mark Brown
Once you move over to proper CODEC drivers the core will take care of this stuff for you.
Please see 00/23
"This is a forward port of various further Intel work on the SST driver in staging. This keeps the staging driver up to date while the ALSA driver development continues."
I did see that; I don't see any contradiction here?
PATCH 3/23 intel_sst: fix unload bugs
In reply to Alan CoxFrom: Vinod Koul <[email protected]>
The current driver remove was erroneous and causes errors when unloading or loading second time
This patch fixes both of these issues
---
drivers/staging/intel_sst/intel_sst.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/staging/intel_sst/intel_sst.c +6 -6
@@ -371,7 +371,8 @@ free_mad_wq:destroy_workqueue (sst_drv_ctx->mad_wq); do_free_drv_ctx:kfree (sst_drv_ctx); -pr_err ("Probe failed with 0x%x\n" , ret); + sst_drv_ctx =NULL ; +pr_err ("Probe failed with %d\n" , ret);return ret; }
@@ -407,11 +408,9 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)destroy_workqueue (sst_drv_ctx->post_msg_wq);destroy_workqueue (sst_drv_ctx->mad_wq);kfree (sst_drv_ctx); -pci_release_region (pci,1 ); -pci_release_region (pci,2 ); -pci_release_region (pci,3 ); -pci_release_region (pci,4 ); -pci_release_region (pci,5 ); + sst_drv_ctx =NULL ; +pci_release_regions (pci); +pci_disable_device (pci);pci_set_drvdata (pci,NULL ); }
@@ -604,6 +603,7 @@ static void __exit intel_sst_exit(void)pci_unregister_driver (&driver);pr_debug ("driver unloaded\n" ); + sst_drv_ctx =NULL ;return ; }
PATCH 4/23 intel_sst: ignore IRQ when suspended
In reply to Alan CoxFrom: Vinod Koul <[email protected]>
The irq for audio is shared, so when device is supended driver should not the read register and ignore the interrupt.
This patch ignores interrupts when device is suspended.
---
drivers/staging/intel_sst/intel_sst.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/staging/intel_sst/intel_sst.c +3 -0
@@ -107,6 +107,9 @@ static irqreturn_t intel_sst_interrupt(int irq, void *context)unsigned int size =0 , str_id;struct stream_info *stream ; +/* Do not handle interrupt in suspended state */ +if (drv->sst_state ==SST_SUSPENDED ) +return IRQ_NONE ;/* Interrupt arrived, check src */ isr.full =sst_shim_read (drv->shim,SST_ISRX );
PATCH 5/23 intel_sst: Line out support
In reply to Alan CoxFrom: Dharageswari R <[email protected]>
This patch adds the support for lineout. The lineout input can be selected as any input channel by using a new alsa mixer kcontrol.
---
drivers/staging/intel_sst/intel_sst.h | 6 drivers/staging/intel_sst/intel_sst_common.h | 4 .../staging/intel_sst/intel_sst_drv_interface.c | 7 - drivers/staging/intel_sst/intel_sst_stream.c | 2 drivers/staging/intel_sst/intelmid.c | 3 drivers/staging/intel_sst/intelmid.h | 8 - drivers/staging/intel_sst/intelmid_ctrl.c | 46 +++- drivers/staging/intel_sst/intelmid_msic_control.c | 254 +++++++++++++++++++- drivers/staging/intel_sst/intelmid_snd_control.h | 7 + drivers/staging/intel_sst/intelmid_v0_control.c | 6 drivers/staging/intel_sst/intelmid_v1_control.c | 5 drivers/staging/intel_sst/intelmid_v2_control.c | 6 12 files changed, 330 insertions(+), 24 deletions(-)
drivers/staging/intel_sst/intel_sst.h +4 -2
@@ -82,12 +82,14 @@ struct snd_pmic_ops {int num_channel;int input_dev_id;int mute_status; -int pb_on; +int pb_on, pbhs_on;int cap_on;int output_dev_id; +int lineout_dev_id, line_out_names_cnt; +int prev_lineout_dev_id;int (*set_input_dev) (u8 value);int (*set_output_dev) (u8 value); - +int (*set_lineout_dev) (u8 value);int (*set_mute) (int dev_id,u8 value);int (*get_mute) (int dev_id,u8 *value);
drivers/staging/intel_sst/intel_sst_common.h +2 -2
@@ -28,8 +28,8 @@* Common private declarations for SST */ -#define SST_DRIVER_VERSION "1.2.11" -#define SST_VERSION_NUM 0x1211 +#define SST_DRIVER_VERSION "1.2.14" +#define SST_VERSION_NUM 0x1214/* driver names */ #define SST_DRV_NAME "intel_sst_driver"
drivers/staging/intel_sst/intel_sst_drv_interface.c +6 -1
@@ -110,9 +110,14 @@ void free_stream_context(unsigned int str_id)if (stream->ops ==STREAM_OPS_PLAYBACK || stream->ops ==STREAM_OPS_PLAYBACK_DRM ) { sst_drv_ctx->pb_streams--; -if (sst_drv_ctx->pb_streams ==0 ) +if (sst_drv_ctx->pci_id ==SST_MFLD_PCI_ID ) sst_drv_ctx->scard_ops->power_down_pmic_pb ( stream->device); +else { +if (sst_drv_ctx->pb_streams ==0 ) + sst_drv_ctx->scard_ops-> +power_down_pmic_pb (stream->device); + } }else if (stream->ops ==STREAM_OPS_CAPTURE ) { sst_drv_ctx->cp_streams--;if (sst_drv_ctx->cp_streams ==0 )
drivers/staging/intel_sst/intel_sst_stream.c +2 -0
@@ -73,6 +73,8 @@ int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot) *pcm_slot =0x07 ; else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4) *pcm_slot = 0x0F; + else if (device == SND_SST_DEVICE_CAPTURE && num_chan > 4) + *pcm_slot = 0x1F; else {pr_debug ("No condition satisfied.. ret err\n" );return -EINVAL ;
drivers/staging/intel_sst/intelmid.c +2 -1
@@ -187,7 +187,7 @@ static int snd_intelmad_pcm_prepare(struct snd_pcm_substream *substream)return ret_val; } - ret_val =snd_intelmad_alloc_stream (substream); + ret_val =snd_intelmad_alloc_stream (substream);if (ret_val <0 )return ret_val; stream->dbg_cum_bytes =0 ;
@@ -797,6 +797,7 @@ static int __devinit snd_intelmad_sst_register( intelmaddata->sstdrv_ops->scard_ops->input_dev_id =DMIC ; intelmaddata->sstdrv_ops->scard_ops->output_dev_id =STEREO_HEADPHONE ; + intelmaddata->sstdrv_ops->scard_ops->lineout_dev_id =NONE ; }/* registering with SST driver to get access to SST APIs to use */
drivers/staging/intel_sst/intelmid.h +6 -2
@@ -53,11 +53,11 @@#define STEREO_CNTL 2#define MIN_CHANNEL 1#define MAX_CHANNEL_AMIC 2 -#define MAX_CHANNEL_DMIC 4 +#define MAX_CHANNEL_DMIC 5#define FIFO_SIZE 0/* fifo not being used */ #define INTEL_MAD "Intel MAD"#define MAX_CTRL_MRST 7 -#define MAX_CTRL_MFLD 2 +#define MAX_CTRL_MFLD 3#define MAX_CTRL 7#define MAX_VENDORS 4/* TODO +6 db */
@@ -116,6 +116,7 @@ struct snd_intelmad {void __iomem *int_base;int output_sel;int input_sel; +int lineout_sel;int master_mute;struct mad_jack jack[4 ];int playback_cnt;
@@ -163,6 +164,9 @@ enum _widget_ctrl {CAPTURE_MUTE , MASTER_MUTE }; +enum _widget_ctrl_mfld { +LINEOUT_SEL_MFLD =3 , +};void period_elapsed (void *mad_substream);int snd_intelmad_alloc_stream (struct snd_pcm_substream *substream);
drivers/staging/intel_sst/intelmid_ctrl.c +44 -2
90 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_msic_control.c +242 -12
359 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_snd_control.h +7 -0
@@ -80,6 +80,13 @@ enum SND_INPUT_DEVICE {HS_MIC ,IN_UNDEFINED }; +enum SND_LINE_OUT_DEVICE { +HEADSET , +IHF , +VIBRA1 , +VIBRA2 , +NONE , +};enum SND_OUTPUT_DEVICE { STEREO_HEADPHONE,
drivers/staging/intel_sst/intelmid_v0_control.c +5 -1
@@ -494,7 +494,10 @@ static int fs_set_selected_output_dev(u8 value) } } - +static int fs_set_selected_lineout_dev (u8 value) +{ +return 0 ; +}static int fs_set_mute (int dev_id,u8 value) {struct sc_reg_access sc_access[6 ] = {{0 ,},};
@@ -756,6 +759,7 @@ static int fs_get_vol(int dev_id, int *value)struct snd_pmic_ops snd_pmic_ops_fs = { .set_input_dev = fs_set_selected_input_dev, .set_output_dev = fs_set_selected_output_dev, + .set_lineout_dev = fs_set_selected_lineout_dev, .set_mute = fs_set_mute, .get_mute = fs_get_mute, .set_vol = fs_set_vol,
drivers/staging/intel_sst/intelmid_v1_control.c +5 -0
@@ -585,6 +585,10 @@ static int mx_set_selected_input_dev(u8 dev_id) }return sst_sc_reg_access (sc_access,PMIC_WRITE , num_reg); } +static int mx_set_selected_lineout_dev (u8 dev_id) +{ +return 0 ; +}static int mx_set_mute (int dev_id,u8 value) {
@@ -835,6 +839,7 @@ static int mx_get_vol(int dev_id, int *value)struct snd_pmic_ops snd_pmic_ops_mx = { .set_input_dev = mx_set_selected_input_dev, .set_output_dev = mx_set_selected_output_dev, + .set_lineout_dev = mx_set_selected_lineout_dev, .set_mute = mx_set_mute, .get_mute = mx_get_mute, .set_vol = mx_set_vol,
drivers/staging/intel_sst/intelmid_v2_control.c +5 -1
@@ -885,7 +885,10 @@ static int nc_set_selected_input_dev(u8 value) }return sst_sc_reg_access (sc_access,PMIC_READ_MODIFY , num_val); } - +static int nc_set_selected_lineout_dev (u8 dev_id) +{ +return 0 ; +}static int nc_get_mute (int dev_id,u8 *value) {int retval =0 , mask =0 ;
@@ -990,6 +993,7 @@ static int nc_get_vol(int dev_id, int *value)struct snd_pmic_ops snd_pmic_ops_nc = { .set_input_dev = nc_set_selected_input_dev, .set_output_dev = nc_set_selected_output_dev, + .set_lineout_dev = nc_set_selected_lineout_dev, .set_mute = nc_set_mute, .get_mute = nc_get_mute, .set_vol = nc_set_vol,
PATCH 6/23 intel_sst: parameter tuning ioctl
In reply to Alan CoxFrom: Vinod Koul <[email protected]>
This patch adds new IOCTL for application interface.
Using parameter tuning IOCTL, application can fine tune the audio firmware for it's requirement.
---
.../staging/intel_sst/intel_sst_app_interface.c | 37 ++++++++++++++++++++ drivers/staging/intel_sst/intel_sst_common.h | 4 +- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 1 + drivers/staging/intel_sst/intel_sst_ioctl.h | 8 ++++ drivers/staging/intel_sst/intel_sst_ipc.c | 18 ++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-)
drivers/staging/intel_sst/intel_sst_app_interface.c +37 -0
@@ -961,6 +961,34 @@ free_mem:return retval; } + +int sst_ioctl_tuning_params (unsigned long arg) +{ +struct snd_sst_tuning_params params; +struct ipc_post *msg; + +if (copy_from_user (¶ms, (void __user *)arg,sizeof (params))) +return -EFAULT ; +if (params.size >SST_MAILBOX_SIZE ) +return -ENOMEM ; +pr_debug ("Parameter %d, Stream %d, Size %d\n" , params.type, + params.str_id, params.size); +if (sst_create_large_msg (&msg)) +return -ENOMEM ; + +sst_fill_header (&msg->header,IPC_IA_TUNING_PARAMS ,1 , params.str_id); + msg->header.part.data =sizeof (u32) +sizeof (params) + params.size; +memcpy (msg->mailbox_data, &msg->header.full,sizeof (u32)); +memcpy (msg->mailbox_data +sizeof (u32), ¶ms,sizeof (params)); +if (copy_from_user (msg->mailbox_data +sizeof (params), + (void __user *)(unsigned long )params.addr, + params.size)) { +kfree (msg->mailbox_data); +kfree (msg); +return -EFAULT ; + } +return sst_send_algo_ipc (&msg); +}/** * intel_sst_ioctl - receives the device ioctl's * @file_ptr:pointer to file
@@ -1412,6 +1440,15 @@ free_iobufs: } retval =intel_sst_ioctl_dsp (cmd, arg);break ; + +case _IOC_NR (SNDRV_SST_TUNING_PARAMS ): +if (minor !=AM_MODULE ) { + retval = -EBADRQC ; +break ; + } + retval =sst_ioctl_tuning_params (arg); +break ; +default : retval = -EINVAL ; }
drivers/staging/intel_sst/intel_sst_common.h +2 -2
@@ -28,8 +28,8 @@* Common private declarations for SST */ -#define SST_DRIVER_VERSION "1.2.14" -#define SST_VERSION_NUM 0x1214 +#define SST_DRIVER_VERSION "1.2.15" +#define SST_VERSION_NUM 0x1215/* driver names */ #define SST_DRV_NAME "intel_sst_driver"
drivers/staging/intel_sst/intel_sst_fw_ipc.h +1 -0
@@ -71,6 +71,7 @@#define IPC_IA_DECODE_FRAMES 0x18#define IPC_IA_ALG_PARAMS 0x1A +#define IPC_IA_TUNING_PARAMS 0x1B/* I2L Stream config/control msgs */ #define IPC_IA_ALLOC_STREAM 0x20/* Allocate a stream ID */
drivers/staging/intel_sst/intel_sst_ioctl.h +8 -0
@@ -400,6 +400,13 @@ struct snd_sst_dbufs {struct snd_sst_buffs *obufs; }; +struct snd_sst_tuning_params { +__u8 type; +__u8 str_id; +__u8 size; +__u8 rsvd; +__aligned_u64 addr; +} __attribute__ ((packed));/*IOCTL defined here */ /*SST MMF IOCTLS only */ #define SNDRV_SST_STREAM_SET_PARAMS _IOR('L', 0x00, \
@@ -428,5 +435,6 @@ struct snd_sst_dbufs {/*DSP Ioctls on /dev/intel_sst_ctrl only*/ #define SNDRV_SST_SET_ALGO _IOW('L', 0x30, struct snd_ppp_params *)#define SNDRV_SST_GET_ALGO _IOWR('L', 0x31, struct snd_ppp_params *) +#define SNDRV_SST_TUNING_PARAMS _IOW('L', 0x32, struct snd_sst_tuning_params *)#endif /* __INTEL_SST_IOCTL_H__ */
drivers/staging/intel_sst/intel_sst_ipc.c +18 -0
@@ -416,6 +416,24 @@ void sst_process_reply(struct work_struct *work) }break ; } + +case IPC_IA_TUNING_PARAMS : { +pr_debug ("sst:IPC_TUNING_PARAMS resp: %x\n" , msg->header.full); +pr_debug ("data value %x\n" , msg->header.part.data); +if (msg->header.part.large) { +pr_debug ("alg set failed\n" ); + sst_drv_ctx->ppp_params_blk.ret_code = + -msg->header.part.data; + }else { +pr_debug ("alg set success\n" ); + sst_drv_ctx->ppp_params_blk.ret_code =0 ; + } +if (sst_drv_ctx->ppp_params_blk.on == true) { + sst_drv_ctx->ppp_params_blk.condition = true; +wake_up (&sst_drv_ctx->wait_queue); + } + } +case IPC_IA_GET_FW_INFO : {struct snd_sst_fw_info *fw_info = (struct snd_sst_fw_info *)msg->mailbox;
PATCH 7/23 intel_sst: DMIC routing
In reply to Alan CoxFrom: Sitanshu Nanavati <[email protected]>
This patch adds support for configuring and routing the DMICs (assigned HW route to DMICs)
---
drivers/staging/intel_sst/intel_sst.h | 4 drivers/staging/intel_sst/intel_sst_stream.c | 2 drivers/staging/intel_sst/intelmid.h | 11 + drivers/staging/intel_sst/intelmid_ctrl.c | 198 +++++++++++++++++++++ drivers/staging/intel_sst/intelmid_msic_control.c | 58 ++++++ 5 files changed, 270 insertions(+), 3 deletions(-)
drivers/staging/intel_sst/intel_sst.h +4 -0
@@ -33,6 +33,7 @@#define SST_CARD_NAMES "intel_mid_card" +#define MFLD_MAX_HW_CH 4/* control list Pmic & Lpe */ /* Input controls */ enum port_status {
@@ -108,6 +109,9 @@ struct snd_pmic_ops {int (*power_down_pmic_pb) (unsigned int device);int (*power_down_pmic_cp) (unsigned int device);int (*power_down_pmic) (void ); +unsigned int hw_dmic_map[MFLD_MAX_HW_CH ]; +unsigned int available_dmics; +int (*set_hw_dmic_route) (u8 index); };struct intel_sst_pcm_control {
drivers/staging/intel_sst/intel_sst_stream.c +1 -1
@@ -48,7 +48,7 @@*/ int sst_check_device_type (u32 device,u32 num_chan,u32 *pcm_slot) { -if (device >MAX_NUM_STREAMS_MFLD ) { +if (device >=MAX_NUM_STREAMS_MFLD ) {pr_debug ("device type invalid %d\n" , device);return -EINVAL ; }
drivers/staging/intel_sst/intelmid.h +9 -2
@@ -28,6 +28,7 @@#define __INTELMID_H#include <linux/time.h> +#include <sound/jack.h> #define DRIVER_NAME_MFLD "msic_audio"#define DRIVER_NAME_MRST "pmic_audio"
@@ -43,7 +44,7 @@#define MAX_BUFFER (800*1024)/* for PCM */ #define MIN_BUFFER (800*1024)#define MAX_PERIODS (1024*2) -#define MIN_PERIODS 1 +#define MIN_PERIODS 2#define MAX_PERIOD_BYTES MAX_BUFFER#define MIN_PERIOD_BYTES 32/*#define MIN_PERIOD_BYTES 160*/
@@ -57,7 +58,7 @@#define FIFO_SIZE 0/* fifo not being used */ #define INTEL_MAD "Intel MAD"#define MAX_CTRL_MRST 7 -#define MAX_CTRL_MFLD 3 +#define MAX_CTRL_MFLD 7#define MAX_CTRL 7#define MAX_VENDORS 4/* TODO +6 db */
@@ -167,6 +168,12 @@ enum _widget_ctrl {enum _widget_ctrl_mfld {LINEOUT_SEL_MFLD =3 , }; +enum hw_chs { +HW_CH0 =0 , +HW_CH1 , +HW_CH2 , +HW_CH3 +};void period_elapsed (void *mad_substream);int snd_intelmad_alloc_stream (struct snd_pcm_substream *substream);
drivers/staging/intel_sst/intelmid_ctrl.c +198 -0
215 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_msic_control.c +58 -0
78 lines not on this page · raw message
PATCH 8/23 intel_sst: rework jack implementation
In reply to Alan CoxFrom: Ramesh Babu K V <[email protected]>
This patch fixes the below issues w.r.t jack implementation
a) The current jack implementation in driver is implemented in intelmid.c. It has moved to vendor files for better managebility
b) Cleaned up jack reporting per upstream comments
c) Implemented jack for msic, added code to read adc and deduce jack type based on mic bias
d) Support detection of american headset
---
drivers/staging/intel_sst/intel_sst.h | 16 + drivers/staging/intel_sst/intel_sst_common.h | 4 drivers/staging/intel_sst/intelmid.c | 449 +++++---------------- drivers/staging/intel_sst/intelmid.h | 14 + drivers/staging/intel_sst/intelmid_adc_control.h | 193 +++++++++ drivers/staging/intel_sst/intelmid_ctrl.c | 1 drivers/staging/intel_sst/intelmid_msic_control.c | 258 ++++++++++++ drivers/staging/intel_sst/intelmid_pvt.c | 1 drivers/staging/intel_sst/intelmid_v0_control.c | 111 +++++ drivers/staging/intel_sst/intelmid_v1_control.c | 142 ++++++- drivers/staging/intel_sst/intelmid_v2_control.c | 69 +++ drivers/staging/intel_sst/jack.h | 10 12 files changed, 887 insertions(+), 381 deletions(-) create mode 100644 drivers/staging/intel_sst/intelmid_adc_control.h delete mode 100644 drivers/staging/intel_sst/jack.h
drivers/staging/intel_sst/intel_sst.h +16 -0
@@ -30,6 +30,7 @@* This file is shared between the SST and MAD drivers */ #include "intel_sst_ioctl.h" +#include <sound/jack.h> #define SST_CARD_NAMES "intel_mid_card"
@@ -88,6 +89,7 @@ struct snd_pmic_ops {int output_dev_id;int lineout_dev_id, line_out_names_cnt;int prev_lineout_dev_id; +bool jack_interrupt_status;int (*set_input_dev) (u8 value);int (*set_output_dev) (u8 value);int (*set_lineout_dev) (u8 value);
@@ -109,11 +111,25 @@ struct snd_pmic_ops {int (*power_down_pmic_pb) (unsigned int device);int (*power_down_pmic_cp) (unsigned int device);int (*power_down_pmic) (void ); +void (*pmic_irq_cb) (void *cb_data,u8 value); +void (*pmic_irq_enable)(void *data); +int (*pmic_jack_enable) (void ); +int (*pmic_get_mic_bias)(void *intelmaddata); +int (*pmic_set_headset_state)(int state); +unsigned int hw_dmic_map[MFLD_MAX_HW_CH ];unsigned int available_dmics;int (*set_hw_dmic_route) (u8 index); }; +extern void sst_mad_send_jack_report (struct snd_jack *jack, +int buttonpressevent, +int status); + + +int intemad_set_headset_state (int state); +int intelmad_get_mic_bias (void ); +struct intel_sst_pcm_control {int (*open) (struct snd_sst_params *str_param);int (*device_control) (int cmd,void *arg);
drivers/staging/intel_sst/intel_sst_common.h +2 -2
@@ -28,8 +28,8 @@* Common private declarations for SST */ -#define SST_DRIVER_VERSION "1.2.15" -#define SST_VERSION_NUM 0x1215 +#define SST_DRIVER_VERSION "1.2.17" +#define SST_VERSION_NUM 0x1217/* driver names */ #define SST_DRV_NAME "intel_sst_driver"
drivers/staging/intel_sst/intelmid.c +115 -334
630 lines not on this page · raw message
drivers/staging/intel_sst/intelmid.h +14 -0
@@ -67,12 +67,17 @@#define MIN_VOL 0#define PLAYBACK_COUNT 1#define CAPTURE_COUNT 1 +#define ADC_ONE_LSB_MULTIPLIER 2346 + +#define MID_JACK_HS_LONG_PRESS SND_JACK_BTN_0 +#define MID_JACK_HS_SHORT_PRESS SND_JACK_BTN_1extern int sst_card_vendor_id;struct mad_jack {struct snd_jack jack;int jack_status; +int jack_dev_state;struct timeval buttonpressed;struct timeval buttonreleased; };
@@ -84,6 +89,12 @@ struct mad_jack_msg_wq { }; +struct snd_intelmad_probe_info { +unsigned int cpu_id; +unsigned int irq_cache; +unsigned int size; +}; +/** * struct snd_intelmad - intelmad driver structure *
@@ -122,6 +133,7 @@ struct snd_intelmad {struct mad_jack jack[4 ];int playback_cnt;int capture_cnt; +u16 adc_address;struct mad_jack_msg_wq mad_jack_msg;struct workqueue_struct *mad_jack_wq;u8 jack_prev_state;
@@ -188,5 +200,7 @@ extern struct snd_control_val intelmad_ctrl_val[];extern struct snd_kcontrol_new snd_intelmad_controls_mrst[];extern struct snd_kcontrol_new snd_intelmad_controls_mfld[];extern struct snd_pmic_ops *intelmad_vendor_ops[]; +void sst_mad_send_jack_report (struct snd_jack *jack, +int buttonpressevent ,int status);#endif /* __INTELMID_H */
drivers/staging/intel_sst/intelmid_adc_control.h new file +193 -0
193 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_ctrl.c +0 -1
@@ -29,7 +29,6 @@#include <sound/core.h> #include <sound/control.h> -#include "jack.h" #include "intel_sst.h" #include "intel_sst_ioctl.h" #include "intelmid_snd_control.h"
drivers/staging/intel_sst/intelmid_msic_control.c +253 -5
362 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_pvt.c +0 -1
@@ -31,7 +31,6 @@#include <sound/core.h> #include <sound/control.h> #include <sound/pcm.h> -#include "jack.h" #include "intel_sst.h" #include "intel_sst_ioctl.h" #include "intelmid_snd_control.h"
drivers/staging/intel_sst/intelmid_v0_control.c +100 -11
144 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_v1_control.c +131 -11
168 lines not on this page · raw message
drivers/staging/intel_sst/intelmid_v2_control.c +63 -6
96 lines not on this page · raw message
drivers/staging/intel_sst/jack.h deleted +0 -10
@@ -1,10 +0,0 @@ -/* Temporary staging glue */ - -#include <sound/jack.h> - -/* These want adding to jack.h as enum entries once approved */ - -#define SND_JACK_HS_SHORT_PRESS (SND_JACK_HEADSET | 0x0020) -#define SND_JACK_HS_LONG_PRESS (SND_JACK_HEADSET | 0x0040) - -
PATCH 9/23 intel_sst: Set de-bounce time
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
In order to make jack detection behave properly, we have to set the de-bounce time, otherwise, some weird events happens:
e.g. no plug-out event seen.
---
drivers/staging/intel_sst/intelmid_v2_control.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +5 -1
@@ -84,6 +84,7 @@ enum reg_v3 {HPLMIXSEL =0x12b ,HPRMIXSEL =0x12c ,LOANTIPOP =0x12d , + AUXDBNC = 0x12f, };/****
@@ -860,7 +861,10 @@ static int nc_set_selected_input_dev(u8 value) sc_access[3 ].reg_addr =0x105 ; sc_access[3 ].value =0x40 ; sc_access[3 ].mask =MASK6 ; - num_val =4 ; + sc_access[4 ].reg_addr =AUXDBNC ; + sc_access[4 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 |MASK2 |MASK1 |MASK0 ; + sc_access[4 ].value =0xff ; + num_val =5 ;break ;case DMIC :
PATCH 10/23 intel_sst: Enable recording via HS_MIC
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
We may need to make some of this board specific eventually.
---
drivers/staging/intel_sst/intelmid_v2_control.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +4 -1
@@ -864,7 +864,10 @@ static int nc_set_selected_input_dev(u8 value) sc_access[4 ].reg_addr =AUXDBNC ; sc_access[4 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 |MASK2 |MASK1 |MASK0 ; sc_access[4 ].value =0xff ; - num_val =5 ; + sc_access[5 ].reg_addr =ADCSAMPLERATE ; + sc_access[5 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 ; + sc_access[5 ].value =0xc8 ; + num_val =6 ;break ;case DMIC :
PATCH 11/23 intel_sst: Enable recording via DMIC
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
We may need to make some of this board specific eventually
---
drivers/staging/intel_sst/intelmid_v2_control.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +4 -4
@@ -881,12 +881,12 @@ static int nc_set_selected_input_dev(u8 value) sc_access[2 ].reg_addr =0x10a ; sc_access[2 ].value =0x40 ; sc_access[2 ].mask =MASK6 ; - sc_access[3 ].reg_addr =0x109 ; + sc_access[3 ].reg_addr =LILSEL ; sc_access[3 ].mask =MASK6 ; sc_access[3 ].value =0x00 ; - sc_access[4 ].reg_addr =0x104 ; - sc_access[4 ].value =0x3C ; - sc_access[4 ].mask =0xff ; + sc_access[4 ].reg_addr =ADCSAMPLERATE ; + sc_access[4 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 ; + sc_access[4 ].value =0x33 ; num_val =5 ;break ;default :
PATCH 12/23 intel_sst: Headphone Automute support
In reply to Alan CoxFrom: xingchao <[email protected]>
When detected a Jack event, Audio sound routes between internal speaker and headphone/headset automatically.
---
drivers/staging/intel_sst/intelmid_v2_control.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +15 -0
@@ -996,6 +996,19 @@ static int nc_get_vol(int dev_id, int *value)return retval; } +static void hp_automute (enum snd_jack_types type,int present) +{ +u8 in =DMIC ; +u8 out =INTERNAL_SPKR ; +if (present) { +if (type ==SND_JACK_HEADSET ) + in =HS_MIC ; + out =STEREO_HEADPHONE ; + } +nc_set_selected_input_dev (in); +nc_set_selected_output_dev (out); +} +static void nc_pmic_irq_cb (void *cb_data,u8 intsts) {u8 value =0 ;
@@ -1016,6 +1029,7 @@ static void nc_pmic_irq_cb(void *cb_data, u8 intsts) present = (value ==0x1 ) ?1 :0 ; jack_event_flag =1 ; mjack->jack.type =SND_JACK_HEADSET ; +hp_automute (SND_JACK_HEADSET , present); }if (intsts &0x2 ) {
@@ -1024,6 +1038,7 @@ static void nc_pmic_irq_cb(void *cb_data, u8 intsts) present = (value ==0x2 ) ?1 :0 ; jack_event_flag =1 ; mjack->jack.type =SND_JACK_HEADPHONE ; +hp_automute (SND_JACK_HEADPHONE , present); }if (intsts &0x4 ) {
PATCH 13/23 intel_sst: move jack detection related configs to init time
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
The old policy will not enable MIC2BIAS on Moorstown platform by default, it's only enabled when the user selects HS_MIC as input source. Therefore when user selects DMIC and then inserts the jack,
no interrupt will be generated to notify the driver about the jack insertion event and to take action to auto mute the speaker.
The new policy will enable this bit by default,
then no matter what the output device is, an interrupt will be generated.
This behaviour is more likely what a user expects.
---
drivers/staging/intel_sst/intelmid_v2_control.c | 28 +++++++++++------------ 1 files changed, 13 insertions(+), 15 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +13 -15
@@ -114,18 +114,19 @@ static int nc_init_card(void) {VOICEVOL, 0x0e, 0}, {HPLVOL, 0x06, 0}, {HPRVOL, 0x06, 0}, - {MICCTRL, 0x41, 0x00}, + {MICCTRL, 0x51, 0x00}, {ADCSAMPLERATE, 0x8B, 0x00}, {MICSELVOL, 0x5B, 0x00}, {LILSEL, 0x06, 0}, {LIRSEL, 0x46, 0}, {LOANTIPOP, 0x00, 0}, {DMICCTRL1, 0x40, 0}, + {AUXDBNC, 0xff, 0}, }; snd_pmic_ops_nc.card_status =SND_CARD_INIT_DONE ; snd_pmic_ops_nc.master_mute =UNMUTE ; snd_pmic_ops_nc.mute_status =UNMUTE ; -sst_sc_reg_access (sc_access,PMIC_WRITE ,26 ); +sst_sc_reg_access (sc_access,PMIC_WRITE ,27 );pr_debug ("init complete!!\n" );return 0 ; }
@@ -834,7 +835,7 @@ static int nc_set_selected_input_dev(u8 value)pr_debug ("Selecting AMIC\n" ); sc_access[0 ].reg_addr =0x107 ; sc_access[0 ].value =0x40 ; - sc_access[0 ].mask =MASK6 |MASK4 |MASK3 |MASK1 |MASK0 ; + sc_access[0 ].mask =MASK6 |MASK3 |MASK1 |MASK0 ; sc_access[1 ].reg_addr =0x10a ; sc_access[1 ].value =0x40 ; sc_access[1 ].mask =MASK6 ;
@@ -849,9 +850,9 @@ static int nc_set_selected_input_dev(u8 value)case HS_MIC :pr_debug ("Selecting HS_MIC\n" ); - sc_access[0 ].reg_addr =0x107 ; - sc_access[0 ].mask =MASK6 |MASK4 |MASK3 |MASK1 |MASK0 ; - sc_access[0 ].value =0x10 ; + sc_access[0 ].reg_addr =MICCTRL ; + sc_access[0 ].mask =MASK6 |MASK3 |MASK1 |MASK0 ; + sc_access[0 ].value =0x00 ; sc_access[1 ].reg_addr =0x109 ; sc_access[1 ].mask =MASK6 ; sc_access[1 ].value =0x40 ;
@@ -861,19 +862,16 @@ static int nc_set_selected_input_dev(u8 value) sc_access[3 ].reg_addr =0x105 ; sc_access[3 ].value =0x40 ; sc_access[3 ].mask =MASK6 ; - sc_access[4 ].reg_addr =AUXDBNC ; - sc_access[4 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 |MASK2 |MASK1 |MASK0 ; - sc_access[4 ].value =0xff ; - sc_access[5 ].reg_addr =ADCSAMPLERATE ; - sc_access[5 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 ; - sc_access[5 ].value =0xc8 ; - num_val =6 ; + sc_access[4 ].reg_addr =ADCSAMPLERATE ; + sc_access[4 ].mask =MASK7 |MASK6 |MASK5 |MASK4 |MASK3 ; + sc_access[4 ].value =0xc8 ; + num_val =5 ;break ;case DMIC :pr_debug ("DMIC\n" ); - sc_access[0 ].reg_addr =0x107 ; - sc_access[0 ].mask =MASK6 |MASK4 |MASK3 |MASK1 |MASK0 ; + sc_access[0 ].reg_addr =MICCTRL ; + sc_access[0 ].mask =MASK6 |MASK3 |MASK1 |MASK0 ; sc_access[0 ].value =0x0B ; sc_access[1 ].reg_addr =0x105 ; sc_access[1 ].value =0x80 ;
PATCH 14/23 sst: return correct output/input device id
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
Without this patch, the change of output/input device can't be reflected correctly. The mismatch reflects insane design, and should be fixed when switching to the ASoC framework.
---
drivers/staging/intel_sst/intelmid_ctrl.c | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletions(-)
drivers/staging/intel_sst/intelmid_ctrl.c +20 -1
@@ -504,8 +504,8 @@ static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol,WARN_ON (!kcontrol); intelmaddata = kcontrol->private_data; + scard_ops = intelmaddata->sstdrv_ops->scard_ops;if (intelmaddata->cpu_id ==CPU_CHIP_PENWELL ) { - scard_ops = intelmaddata->sstdrv_ops->scard_ops;if (kcontrol->id.numid ==OUTPUT_SEL ) uval->value.enumerated.item[0 ] = scard_ops->output_dev_id;
@@ -517,6 +517,25 @@ static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol, scard_ops->lineout_dev_id; else return -EINVAL; + }else if (intelmaddata->cpu_id ==CPU_CHIP_LINCROFT ) { +if (kcontrol->id.numid ==OUTPUT_SEL ) +/* There is a mismatch here. +* ALSA expects 1 for internal speaker. +* But internally, we may give 2 for internal speaker. +*/ +if (scard_ops->output_dev_id ==MONO_EARPIECE || + scard_ops->output_dev_id ==INTERNAL_SPKR ) + uval->value.enumerated.item[0 ] =MONO_EARPIECE ; +else if (scard_ops->output_dev_id ==STEREO_HEADPHONE ) + uval->value.enumerated.item[0 ] = +STEREO_HEADPHONE ; +else +return -EINVAL ; +else if (kcontrol->id.numid ==INPUT_SEL ) + uval->value.enumerated.item[0 ] = + scard_ops->input_dev_id; +else +return -EINVAL ; }else uval->value.enumerated.item[0 ] = kcontrol->private_value;return 0 ;
Quoted 3 lines · Alan Cox
This is a forward port of various further Intel work on the SST driver in staging. This keeps the staging driver up to date while the ALSA driver development continues.
What's the plan for moving these out of staging? Quite a few of these patches feel like moves in the wrong direction, adding more code that's going to have problems with mainline rather than addressing the issues that prevent merges.
Quoted 9 lines · On Tue, 3 May 2011 18:15:38 +0100 Mark Brown…
Quoted 3 lines · Alan Cox
This is a forward port of various further Intel work on the SST driver in staging. This keeps the staging driver up to date while the ALSA driver development continues.
What's the plan for moving these out of staging? Quite a few of these patches feel like moves in the wrong direction, adding more code that's going to have problems with mainline rather than addressing the issues that prevent merges.
There is a separate driver being written. In the meantime this driver is getting updated and maintained because in the real world people have customers and products to deliver.
It might as well therefore be maintained in tree as out. That seems to serve Linux users rather better.
Alan
Quoted 10 lines · Alan Cox
Quoted 4 lines · Mark Brown
What's the plan for moving these out of staging? Quite a few of these patches feel like moves in the wrong direction, adding more code that's going to have problems with mainline rather than addressing the issues that prevent merges.
There is a separate driver being written. In the meantime this driver is getting updated and maintained because in the real world people have customers and products to deliver.
Sure, I was just asking if there was a plan to work on this properly - the normal expectation in staging is that we'll see in place refactoring and this series clearly isn't that. You seem a little defensive here...
Quoted 2 lines
It might as well therefore be maintained in tree as out. That seems to serve Linux users rather better.
Of course, as do most of us, I was mostly making sure that there was a plan here.
Quoted 3 lines
Sure, I was just asking if there was a plan to work on this properly - the normal expectation in staging is that we'll see in place refactoring and this series clearly isn't that. You seem a little defensive here...
There I disagree (on both points). We have a collection of drivers in staging some of which are in the 'refactor and move' category (eg SEP) others of which are in the 'until the nice one is done' category - eg much of the wireless stuff, rim4 and a few other drivers.
Quoted 5 lines
Quoted 2 lines
It might as well therefore be maintained in tree as out. That seems to serve Linux users rather better.
Of course, as do most of us, I was mostly making sure that there was a plan here.
Yes there is a plan. SST essentially gets updated to fix stuff that needs to work (eg runtime PM for Moorestown) but isn't the future. My favourite sst patch is going to be the one which reads 'added 0 lines, removed bazillions' because at that point it ceases to be my problem ;)
Alan
PATCH 15/23 intel_sst: make sure the sst_drop_stream() get called when needed
In reply to Alan CoxFrom: Feng Tang <[email protected]>
When "aplay test.wav", if we "ctrl+z" to suspend it, the last piece of sound will be played endlessly. So we need make sure the drop_stream is called in such a case.
---
.../staging/intel_sst/intel_sst_drv_interface.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/staging/intel_sst/intel_sst_drv_interface.c +2 -2
@@ -283,8 +283,8 @@ void sst_process_mad_ops(struct work_struct *work) retval =sst_resume_stream (mad_ops->stream_id);break ;case SST_SND_DROP : -/* retval = sst_drop_stream(mad_ops->stream_id); -*/ break ; + retval =sst_drop_stream (mad_ops->stream_id); +break ;case SST_SND_START :pr_debug ("SST Debug: start stream\n" ); retval =sst_start_stream (mad_ops->stream_id);
PATCH 16/23 intel_sst: MRST can only do mono recording
In reply to Alan CoxFrom: Wu Fengguang <[email protected]>
Fix bug
$ arecord -Dplughw -c2 Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Stereo arecord: set_params:1116: Unable to install hw params: ACCESS: RW_INTERLEAVED FORMAT: U8 SUBFORMAT: STD SAMPLE_BITS: 8 FRAME_BITS: 16 CHANNELS: 2 [...]
Root cause is, the driver is reporting 2-channel capture capability that is not supported by the MRST hardware. So the plughw plugin end up requesting 2-channel capture which fails.
---
drivers/staging/intel_sst/intelmid.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/staging/intel_sst/intelmid.c +7 -0
@@ -335,6 +335,13 @@ static int snd_intelmad_open(struct snd_pcm_substream *substream, runtime = substream->runtime;/* set the runtime hw parameter with local snd_pcm_hardware struct */ runtime->hw = snd_intelmad_stream; +if (intelmaddata->cpu_id ==CPU_CHIP_LINCROFT ) { +/* +* MRST firmware currently denies stereo recording requests. +*/ +if (substream->stream ==SNDRV_PCM_STREAM_CAPTURE ) + runtime->hw.channels_max =1 ; + }if (intelmaddata->cpu_id ==CPU_CHIP_PENWELL ) { runtime->hw = snd_intelmad_stream; runtime->hw.rates =SNDRV_PCM_RATE_48000 ;
PATCH 17/23 intel_sst: MRST can only do 16bit recording
In reply to Alan CoxFrom: Wu Fengguang <[email protected]>
Fix bug
$ arecord -D dsnoop -r 48000 -f S16_LE 1.wav ALSA lib pcm_direct.c:980:(snd1_pcm_direct_initialize_slave) unable to install hw params ALSA lib pcm_dsnoop.c:604:(snd_pcm_dsnoop_open) unable to initialize slave arecord: main:654: audio open error: Interrupted system call
Root cause is, the driver is reporting 32-bit capture capability that is not supported by the MRST hardware. So the dsnoop plugin end up requesting 32-bit capture which fails.
---
drivers/staging/intel_sst/intelmid.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/staging/intel_sst/intelmid.c +4 -1
@@ -339,8 +339,11 @@ static int snd_intelmad_open(struct snd_pcm_substream *substream,/* * MRST firmware currently denies stereo recording requests. */ -if (substream->stream ==SNDRV_PCM_STREAM_CAPTURE ) +if (substream->stream ==SNDRV_PCM_STREAM_CAPTURE ) { + runtime->hw.formats = (SNDRV_PCM_FMTBIT_S16 | +SNDRV_PCM_FMTBIT_U16 ); runtime->hw.channels_max =1 ; + } }if (intelmaddata->cpu_id ==CPU_CHIP_PENWELL ) { runtime->hw = snd_intelmad_stream;
PATCH 18/23 intel_sst: intelmid_v2_control: correct jack event type
In reply to Alan CoxFrom: Andy CH Lin <[email protected]>
Correct event type of audio jack while receiving long press event.
---
drivers/staging/intel_sst/intelmid_v2_control.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +1 -1
@@ -1054,7 +1054,7 @@ static void nc_pmic_irq_cb(void *cb_data, u8 intsts) present =1 ; jack_event_flag =1 ; buttonpressflag =1 ; - mjack->jack.type =MID_JACK_HS_SHORT_PRESS ; + mjack->jack.type =MID_JACK_HS_LONG_PRESS ; }if (jack_event_flag)
PATCH 19/23 intel_sst: fix runtime pm issue
In reply to Alan CoxFrom: Chandramouli Narayanan <[email protected]>
Use correct api for enabling/disabling runtime pm. Additionally, fix runtime suspend/resume to not duplicate pci core functions
---
drivers/staging/intel_sst/intel_sst.c | 47 +++++++++++++++++++++++++++------ 1 files changed, 38 insertions(+), 9 deletions(-)
drivers/staging/intel_sst/intel_sst.c +38 -9
@@ -340,9 +340,9 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr); } sst_drv_ctx->lpe_stalled =0 ; -pm_runtime_set_active (&pci->dev); -pm_runtime_enable (&pci->dev); +pci_set_drvdata (pci, sst_drv_ctx);pm_runtime_allow (&pci->dev); +pm_runtime_put_noidle (&pci->dev);pr_debug ("...successfully done!!!\n" );return ret;
@@ -389,6 +389,8 @@ do_free_drv_ctx:*/ static void __devexit intel_sst_remove(struct pci_dev *pci) { +pm_runtime_get_noresume (&pci->dev); +pm_runtime_forbid (&pci->dev);pci_dev_put (sst_drv_ctx->pci);mutex_lock (&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state =SST_UN_INIT ;
@@ -410,7 +412,7 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)destroy_workqueue (sst_drv_ctx->process_msg_wq);destroy_workqueue (sst_drv_ctx->post_msg_wq);destroy_workqueue (sst_drv_ctx->mad_wq); -kfree (sst_drv_ctx); +kfree (pci_get_drvdata (pci)); sst_drv_ctx =NULL ;pci_release_regions (pci);pci_disable_device (pci);
@@ -522,18 +524,45 @@ int intel_sst_resume(struct pci_dev *pci)return 0 ; } +/* The runtime_suspend/resume is pretty much similar to the legacy suspend/resume with the noted exception below: +* The PCI core takes care of taking the system through D3hot and restoring it back to D0 and so there is +* no need to duplicate that here. +*/ static int intel_sst_runtime_suspend (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev); -pr_debug ("runtime_suspend called\n" ); -return intel_sst_suspend (pci_dev,PMSG_SUSPEND ); +union config_status_reg csr; + +pr_debug ("intel_sst_runtime_suspend called\n" ); +if (sst_drv_ctx->stream_cnt) { +pr_err ("active streams,not able to suspend\n" ); +return -EBUSY ; + } +/*save fw context*/ +sst_save_dsp_context (); +/*Assert RESET on LPE Processor*/ + csr.full =sst_shim_read (sst_drv_ctx->shim,SST_CSR ); + csr.full = csr.full |0x2 ; +/* Move the SST state to Suspended */ +mutex_lock (&sst_drv_ctx->sst_lock); + sst_drv_ctx->sst_state =SST_SUSPENDED ; +sst_shim_write (sst_drv_ctx->shim,SST_CSR , csr.full); +mutex_unlock (&sst_drv_ctx->sst_lock); +return 0 ; }static int intel_sst_runtime_resume (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev); -pr_debug ("runtime_resume called\n" ); -return intel_sst_resume (pci_dev); + +pr_debug ("intel_sst_runtime_resume called\n" ); +if (sst_drv_ctx->sst_state !=SST_SUSPENDED ) { +pr_err ("SST is not in suspended state\n" ); +return 0 ; + } + +mutex_lock (&sst_drv_ctx->sst_lock); + sst_drv_ctx->sst_state =SST_UN_INIT ; +mutex_unlock (&sst_drv_ctx->sst_lock); +return 0 ; }static int intel_sst_runtime_idle (struct device *dev)
PATCH 20/23 sst: set default output and input device
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
---
drivers/staging/intel_sst/intelmid_v2_control.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/staging/intel_sst/intelmid_v2_control.c +2 -0
@@ -1067,6 +1067,8 @@ static int nc_jack_enable(void) }struct snd_pmic_ops snd_pmic_ops_nc = { + .input_dev_id =DMIC , + .output_dev_id =INTERNAL_SPKR , .set_input_dev = nc_set_selected_input_dev, .set_output_dev = nc_set_selected_output_dev, .set_mute = nc_set_mute,
PATCH 21/23 intel_sst: add Master Volume
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
With this patch, Master Volume will control AUDIOLVOL(0x10c) and AUDIORVOL(0x10d); while PCM Volume will control HPLVOL(0x123) and HPRVOL(0x124).
---
drivers/staging/intel_sst/intelmid.h | 7 ++- drivers/staging/intel_sst/intelmid_ctrl.c | 40 +++++++++++++++++- drivers/staging/intel_sst/intelmid_snd_control.h | 2 + drivers/staging/intel_sst/intelmid_v2_control.c | 48 +++++++++++++++++----- 4 files changed, 81 insertions(+), 16 deletions(-)
drivers/staging/intel_sst/intelmid.h +5 -2
@@ -57,9 +57,9 @@#define MAX_CHANNEL_DMIC 5#define FIFO_SIZE 0/* fifo not being used */ #define INTEL_MAD "Intel MAD" -#define MAX_CTRL_MRST 7 +#define MAX_CTRL_MRST 8#define MAX_CTRL_MFLD 7 -#define MAX_CTRL 7 +#define MAX_CTRL 8#define MAX_VENDORS 4/* TODO +6 db */ #define MAX_VOL 64
@@ -145,6 +145,8 @@ struct snd_control_val {int playback_vol_min;int capture_vol_max;int capture_vol_min; +int master_vol_max; +int master_vol_min; };struct mad_stream_pvt {
@@ -175,6 +177,7 @@ enum _widget_ctrl {PLAYBACK_MUTE ,CAPTURE_VOL ,CAPTURE_MUTE , +MASTER_VOL ,MASTER_MUTE }; enum _widget_ctrl_mfld {
drivers/staging/intel_sst/intelmid_ctrl.c +36 -4
@@ -80,9 +80,11 @@ struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = { }, { .playback_vol_max = 0, - .playback_vol_min = -126, + .playback_vol_min = -31, .capture_vol_max = 0, .capture_vol_min = -31, + .master_vol_max = 0, + .master_vol_min = -126, }, };
@@ -159,6 +161,15 @@ static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,return 0 ; } +static int snd_intelmad_master_volume_info (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ +snd_intelmad_volume_info (uinfo,STEREO_CNTL , + intelmad_ctrl_val[sst_card_vendor_id].master_vol_max, + intelmad_ctrl_val[sst_card_vendor_id].master_vol_min); +return 0 ; +} +/** * snd_intelmad_device_info_mrst - provides information about the devices available *
@@ -281,6 +292,11 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,case CAPTURE_VOL : cntl_list[0 ] =PMIC_SND_CAPTURE_VOL ;break ; + +case MASTER_VOL : + cntl_list[0 ] =PMIC_SND_RIGHT_MASTER_VOL ; + cntl_list[1 ] =PMIC_SND_LEFT_MASTER_VOL ; +break ;default :return -EINVAL ; }
@@ -291,7 +307,8 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,if (ret_val)return ret_val; -if (kcontrol->id.numid ==PLAYBACK_VOL ) { +if (kcontrol->id.numid ==PLAYBACK_VOL || + kcontrol->id.numid ==MASTER_VOL ) { ret_val = scard_ops->get_vol (cntl_list[1 ], &value); uval->value.integer.value[1 ] = value; }
@@ -399,6 +416,12 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,case CAPTURE_VOL : cntl_list[0 ] =PMIC_SND_CAPTURE_VOL ;break ; + +case MASTER_VOL : + cntl_list[0 ] =PMIC_SND_LEFT_MASTER_VOL ; + cntl_list[1 ] =PMIC_SND_RIGHT_MASTER_VOL ; +break ; +default :return -EINVAL ; }
@@ -408,7 +431,8 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,if (ret_val)return ret_val; -if (kcontrol->id.numid ==PLAYBACK_VOL ) +if (kcontrol->id.numid ==PLAYBACK_VOL || + kcontrol->id.numid ==MASTER_VOL ) ret_val = scard_ops->set_vol (cntl_list[1 ], uval->value.integer.value[1 ]);return ret_val;
@@ -753,7 +777,6 @@ static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol,return 0 ; } -struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL ]__devinitdata = { { .iface =SNDRV_CTL_ELEM_IFACE_MIXER ,
@@ -811,6 +834,15 @@ struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_intelmad_master_volume_info, + .get = snd_intelmad_volume_get, + .put = snd_intelmad_volume_set, + .private_value = 0, +}, +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = snd_intelmad_mute_info,
drivers/staging/intel_sst/intelmid_snd_control.h +2 -0
@@ -111,6 +111,8 @@ enum pmic_controls {PMIC_SND_RIGHT_SPEAKER_MUTE =0x0015 ,PMIC_SND_RECEIVER_VOL =0x0016 ,PMIC_SND_RECEIVER_MUTE =0x0017 , +PMIC_SND_LEFT_MASTER_VOL =0x0018 , +PMIC_SND_RIGHT_MASTER_VOL =0x0019 ,/* Other controls */ PMIC_SND_MUTE_ALL =0x0020 , PMIC_MAX_CONTROLS = 0x0020,
drivers/staging/intel_sst/intelmid_v2_control.c +38 -10
80 lines not on this page · raw message
PATCH 22/23 sst: internal speaker needs setting a GPIO line
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
On Moorestown platform, internal speaker's power line is connected to a GPIO line, so we need to enable or disable it properly.
---
drivers/staging/intel_sst/intel_sst.h | 2 ++ drivers/staging/intel_sst/intelmid.c | 13 ++++++++++-- drivers/staging/intel_sst/intelmid_v2_control.c | 25 ++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-)
drivers/staging/intel_sst/intel_sst.h +2 -0
@@ -120,6 +120,8 @@ struct snd_pmic_ops {unsigned int hw_dmic_map[MFLD_MAX_HW_CH ];unsigned int available_dmics;int (*set_hw_dmic_route) (u8 index); + +int gpio_amp; }; extern void sst_mad_send_jack_report(struct snd_jack *jack,
drivers/staging/intel_sst/intelmid.c +11 -2
@@ -40,6 +40,7 @@#include <sound/jack.h> #include <sound/pcm_params.h> #include <sound/initval.h> +#include <linux/gpio.h> #include "intel_sst.h" #include "intel_sst_ioctl.h" #include "intel_sst_fw_ipc.h"
@@ -920,14 +921,20 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) ret_val =snd_intelmad_create (intelmaddata, card);if (ret_val) {pr_err ("snd_intelmad_create failed\n" ); - goto set_pvt_data;; + goto set_pvt_data; } card->private_data = &intelmaddata;snd_card_set_dev (card, &pdev->dev); ret_val =snd_card_register (card);if (ret_val) {pr_err ("snd_card_register failed\n" ); - goto set_pvt_data;; + goto set_pvt_data; + } +if (pdev->dev.platform_data) { +int gpio_amp = *(int *)pdev->dev.platform_data; +if (gpio_request_one (gpio_amp,GPIOF_OUT_INIT_LOW ,"amp power" )) + gpio_amp =0 ; + intelmaddata->sstdrv_ops->scard_ops->gpio_amp = gpio_amp; }pr_debug ("snd_intelmad_probe complete\n" );
@@ -957,6 +964,8 @@ static int snd_intelmad_remove(struct platform_device *pdev)struct snd_intelmad *intelmaddata =platform_get_drvdata (pdev);if (intelmaddata) { +if (intelmaddata->sstdrv_ops->scard_ops->gpio_amp) +gpio_free (intelmaddata->sstdrv_ops->scard_ops->gpio_amp);free_irq (intelmaddata->irq, intelmaddata);snd_card_free (intelmaddata->card); }
drivers/staging/intel_sst/intelmid_v2_control.c +24 -1
@@ -28,6 +28,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <linux/gpio.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/file.h>
@@ -87,6 +88,12 @@ enum reg_v3 { AUXDBNC = 0x12f, }; +static void nc_set_amp_power (int power) +{ +if (snd_pmic_ops_nc.gpio_amp) +gpio_set_value (snd_pmic_ops_nc.gpio_amp, power); +} +/**** * nc_init_card - initialize the sound card *
@@ -213,6 +220,16 @@ static int nc_power_up_pb(unsigned int port)msleep (30 ); +/* +* There is a mismatch between Playback Sources and the enumerated +* values of output sources. This mismatch causes ALSA upper to send +* Item 1 for Internal Speaker, but the expected enumeration is 2! For +* now, treat MONO_EARPIECE and INTERNAL_SPKR identically and power up +* the needed resources +*/ +if (snd_pmic_ops_nc.output_dev_id ==MONO_EARPIECE || + snd_pmic_ops_nc.output_dev_id ==INTERNAL_SPKR ) +nc_set_amp_power (1 );return nc_enable_audiodac (UNMUTE ); }
@@ -274,7 +291,6 @@ static int nc_power_down(void)int retval =0 ;struct sc_reg_access sc_access[5 ]; -if (snd_pmic_ops_nc.card_status ==SND_CARD_UN_INIT ) retval =nc_init_card ();if (retval)
@@ -284,6 +300,10 @@ static int nc_power_down(void)pr_debug ("powering dn nc_power_down ....\n" ); +if (snd_pmic_ops_nc.output_dev_id ==MONO_EARPIECE || + snd_pmic_ops_nc.output_dev_id ==INTERNAL_SPKR ) +nc_set_amp_power (0 ); +msleep (30 ); sc_access[0 ].reg_addr =DRVPOWERCTRL ;
@@ -519,9 +539,12 @@ static int nc_set_selected_output_dev(u8 value)switch (value) {case STEREO_HEADPHONE : retval =sst_sc_reg_access (sc_access_HP,PMIC_WRITE ,2 ); +nc_set_amp_power (0 );break ; +case MONO_EARPIECE :case INTERNAL_SPKR : retval =sst_sc_reg_access (sc_access_IS,PMIC_WRITE ,2 ); +nc_set_amp_power (1 );break ;default :pr_err ("rcvd illegal request: %d\n" , value);
PATCH 23/23 intel_sst: fix output noises when it's not in playback
In reply to Alan CoxFrom: Lu Guanqun <[email protected]>
When the corresponding output device is not in playback, we can hear a little noises.
Fix it by powering on the device only when it's in playback.
---
drivers/staging/intel_sst/intel_sst.h | 1 + drivers/staging/intel_sst/intelmid_v2_control.c | 33 +++++++++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-)
drivers/staging/intel_sst/intel_sst.h +1 -0
@@ -84,6 +84,7 @@ struct snd_pmic_ops {int num_channel;int input_dev_id;int mute_status; +struct mutex lock;int pb_on, pbhs_on;int cap_on;int output_dev_id;
drivers/staging/intel_sst/intelmid_v2_control.c +24 -9
@@ -134,6 +134,7 @@ static int nc_init_card(void) snd_pmic_ops_nc.master_mute =UNMUTE ; snd_pmic_ops_nc.mute_status =UNMUTE ;sst_sc_reg_access (sc_access,PMIC_WRITE ,27 ); +mutex_init (&snd_pmic_ops_nc.lock);pr_debug ("init complete!!\n" );return 0 ; }
@@ -180,6 +181,7 @@ static int nc_power_up_pb(unsigned int port)return retval;if (port ==0xFF )return 0 ; +mutex_lock (&snd_pmic_ops_nc.lock);nc_enable_audiodac (MUTE );msleep (30 );
@@ -220,6 +222,8 @@ static int nc_power_up_pb(unsigned int port)msleep (30 ); + snd_pmic_ops_nc.pb_on =1 ; +/* * There is a mismatch between Playback Sources and the enumerated * values of output sources. This mismatch causes ALSA upper to send
@@ -230,8 +234,9 @@ static int nc_power_up_pb(unsigned int port)if (snd_pmic_ops_nc.output_dev_id ==MONO_EARPIECE || snd_pmic_ops_nc.output_dev_id ==INTERNAL_SPKR )nc_set_amp_power (1 ); -return nc_enable_audiodac (UNMUTE ); - +nc_enable_audiodac (UNMUTE ); +mutex_unlock (&snd_pmic_ops_nc.lock); +return 0 ; }static int nc_power_up_cp (unsigned int port)
@@ -352,7 +357,7 @@ static int nc_power_down_pb(unsigned int device)return retval;pr_debug ("powering dn pb....\n" ); - +mutex_lock (&snd_pmic_ops_nc.lock);nc_enable_audiodac (MUTE );
@@ -379,9 +384,11 @@ static int nc_power_down_pb(unsigned int device)msleep (30 ); -return nc_enable_audiodac (UNMUTE ); - + snd_pmic_ops_nc.pb_on =0 ; +nc_enable_audiodac (UNMUTE ); +mutex_unlock (&snd_pmic_ops_nc.lock); +return 0 ; }static int nc_power_down_cp (unsigned int device)
@@ -522,11 +529,13 @@ static int nc_set_selected_output_dev(u8 value) {struct sc_reg_access sc_access_HP[] = { {LMUTE ,0x02 ,0x06 }, - {RMUTE ,0x02 ,0x06 } + {RMUTE ,0x02 ,0x06 }, + {DRVPOWERCTRL ,0x06 ,0x06 }, };struct sc_reg_access sc_access_IS[] = { {LMUTE ,0x04 ,0x06 }, - {RMUTE ,0x04 ,0x06 } + {RMUTE ,0x04 ,0x06 }, + {DRVPOWERCTRL ,0x00 ,0x06 }, };int retval =0 ;
@@ -536,20 +545,26 @@ static int nc_set_selected_output_dev(u8 value)if (retval)return retval;pr_debug ("nc set selected output:%d\n" , value); +mutex_lock (&snd_pmic_ops_nc.lock);switch (value) {case STEREO_HEADPHONE : +if (snd_pmic_ops_nc.pb_on) +sst_sc_reg_access (sc_access_HP+2 ,PMIC_WRITE ,1 ); retval =sst_sc_reg_access (sc_access_HP,PMIC_WRITE ,2 );nc_set_amp_power (0 );break ;case MONO_EARPIECE :case INTERNAL_SPKR : - retval =sst_sc_reg_access (sc_access_IS,PMIC_WRITE ,2 ); -nc_set_amp_power (1 ); + retval =sst_sc_reg_access (sc_access_IS,PMIC_WRITE ,3 ); +if (snd_pmic_ops_nc.pb_on) +nc_set_amp_power (1 );break ;default :pr_err ("rcvd illegal request: %d\n" , value); +mutex_unlock (&snd_pmic_ops_nc.lock);return -EINVAL ; } +mutex_unlock (&snd_pmic_ops_nc.lock);return retval; }