Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions sound/soc/sof/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ config SND_SOC_SOF
select SND_SOC_TOPOLOGY
select SND_SOC_COMPRESS
help
This adds support for SOF
Say Y if you have such a device.
This adds support for Sound Open Firmware (SOF). SOF is a free and
generic open source audio DSP firmware for multiple devices.
Say Y if you have such a device that is supported by SOF.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Y or m?

If unsure select "N".

config SND_SOC_SOF_NOCODEC
Expand Down
37 changes: 29 additions & 8 deletions sound/soc/sof/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,20 +157,31 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
(struct soc_bytes_ext *)kcontrol->private_value;
struct snd_sof_control *scontrol = be->dobj.private;
struct snd_sof_dev *sdev = scontrol->sdev;
//struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
//unsigned int i, channels = scontrol->num_channels;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data;
size_t size;
int ret = 0;

pm_runtime_get_sync(sdev->dev);

/* get all the mixer data from DSP */
snd_sof_ipc_get_comp_data(sdev->ipc, scontrol, SOF_IPC_COMP_GET_DATA,
SOF_CTRL_TYPE_DATA_GET, scontrol->cmd);
size = data->size + sizeof(*data);
if (size > be->max) {
dev_err(sdev->dev, "error: DSP sent %ld bytes max is %d\n",
size, be->max);
ret = -EINVAL;
goto out;
}

/* TODO: copy back to userspace */
/* copy back to kcontrol */
memcpy(ucontrol->value.bytes.data, data, size);

out:
pm_runtime_mark_last_busy(sdev->dev);
pm_runtime_put_autosuspend(sdev->dev);
return 0;
return ret;
}

int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
Expand All @@ -180,18 +191,28 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
(struct soc_bytes_ext *)kcontrol->private_value;
struct snd_sof_control *scontrol = be->dobj.private;
struct snd_sof_dev *sdev = scontrol->sdev;
//struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
//unsigned int i, channels = scontrol->num_channels;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data;
int ret = 0;

pm_runtime_get_sync(sdev->dev);

/* TODO: copy from userspace */
if (data->size > be->max) {
dev_err(sdev->dev, "error: size too big %d bytes max is %d\n",
data->size, be->max);
ret = -EINVAL;
goto out;
}

/* copy from kcontrol */
memcpy(data, ucontrol->value.bytes.data, data->size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still looks asymmetrical between put() and get().

put: memcpy(data, ucontrol->value.bytes.data, data->size);
get: memcpy(ucontrol->value.bytes.data, data, data->size + sizeof(*data);


/* notify DSP of mixer updates */
snd_sof_ipc_set_comp_data(sdev->ipc, scontrol, SOF_IPC_COMP_SET_DATA,
SOF_CTRL_TYPE_DATA_SET, scontrol->cmd);

out:
pm_runtime_mark_last_busy(sdev->dev);
pm_runtime_put_autosuspend(sdev->dev);
return 0;
return ret;
}
4 changes: 1 addition & 3 deletions sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ static int sof_probe(struct platform_device *pdev)
}

ret = snd_soc_register_component(&pdev->dev, sdev->cmpnt_drv,
sdev->ops->dai_drv->drv,
sdev->ops->dai_drv->num_drv);
sdev->ops->drv, sdev->ops->num_drv);
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to register DSP DAI driver %d\n", ret);
Expand Down Expand Up @@ -367,7 +366,6 @@ void snd_sof_shutdown(struct device *dev)
}
EXPORT_SYMBOL(snd_sof_shutdown);


static struct platform_driver sof_driver = {
.driver = {
.name = "sof-audio",
Expand Down
13 changes: 11 additions & 2 deletions sound/soc/sof/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Yan Wang <yan.wan@linux.intel.com>
*
* Generic debug routines used to export DSP MMIO and memories to userspace
* for firmware debugging.
*/

#include <linux/delay.h>
Expand Down Expand Up @@ -41,25 +44,30 @@ static ssize_t sof_dfsentry_read(struct file *file, char __user *buffer,

size = dfse->size;

/* validate position & count */
if (pos < 0)
return -EINVAL;
if (pos >= size || !count)
return 0;
if (count > size - pos)
count = size - pos;

/* intermediate buffer size must be u32 multiple */
size = (count + 3) & ~3;
buf = kzalloc(size, GFP_KERNEL);
if (!buf)
return -ENOMEM;

/* copy from DSP MMIO */
pm_runtime_get(sdev->dev);
memcpy_fromio(buf, dfse->buf + pos, size);
pm_runtime_put(sdev->dev);

/* copy to userspace */
ret = copy_to_user(buffer, buf, count);
kfree(buf);

/* update count & position if copy succeeded */
if (ret == count)
return -EFAULT;
count -= ret;
Expand Down Expand Up @@ -109,17 +117,18 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev)
const struct snd_sof_debugfs_map *map;
int err = 0, i;

/* use "sof" as top level debugFS dir */
sdev->debugfs_root = debugfs_create_dir("sof", NULL);
if (IS_ERR_OR_NULL(sdev->debugfs_root)) {
dev_err(sdev->dev, "error: failed to create debugfs directory\n");
return -EINVAL;
}

/* create debugFS files for platform specific MMIO/DSP memories */
for (i = 0; i < ops->debug_map_count; i++) {
map = &ops->debug_map[i];

err = snd_sof_debugfs_create_item(sdev,
sdev->bar[map->bar] +
err = snd_sof_debugfs_create_item(sdev, sdev->bar[map->bar] +
map->offset, map->size,
map->name);
if (err < 0)
Expand Down
3 changes: 2 additions & 1 deletion sound/soc/sof/intel/apl.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct snd_sof_dsp_ops sof_apl_ops = {
.trace_trigger = hda_dsp_trace_trigger,

/* DAI drivers */
.dai_drv = &hda_dai_drv,
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
};
EXPORT_SYMBOL(sof_apl_ops);
8 changes: 2 additions & 6 deletions sound/soc/sof/intel/bdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,6 @@ static struct snd_soc_dai_driver bdw_dai[] = {
},
};

static struct snd_sof_dai_drv bdw_dai_drv = {
.drv = bdw_dai,
.num_drv = ARRAY_SIZE(bdw_dai)
};

/* broadwell ops */
struct snd_sof_dsp_ops sof_bdw_ops = {
/*Device init */
Expand Down Expand Up @@ -791,7 +786,8 @@ struct snd_sof_dsp_ops sof_bdw_ops = {
.load_firmware = snd_sof_load_firmware_memcpy,

/* DAI drivers */
.dai_drv = &bdw_dai_drv,
.drv = bdw_dai,
.num_drv = ARRAY_SIZE(bdw_dai)
};
EXPORT_SYMBOL(sof_bdw_ops);

Expand Down
18 changes: 5 additions & 13 deletions sound/soc/sof/intel/byt.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,17 +811,6 @@ static struct snd_soc_dai_driver byt_dai[] = {
},
};

static struct snd_sof_dai_drv byt_dai_drv = {
.drv = byt_dai,
.num_drv = 3, /* we have only 3 SSPs on byt*/
};

static struct snd_sof_dai_drv cht_dai_drv = {
.drv = byt_dai,
/* all 6 SSPs may be available for cherrytrail */
.num_drv = ARRAY_SIZE(byt_dai),
};

/* baytrail ops */
struct snd_sof_dsp_ops sof_byt_ops = {
/* device init */
Expand Down Expand Up @@ -869,7 +858,8 @@ struct snd_sof_dsp_ops sof_byt_ops = {
.load_firmware = snd_sof_load_firmware_memcpy,

/* DAI drivers */
.dai_drv = &byt_dai_drv,
.drv = byt_dai,
.num_drv = 3, /* we have only 3 SSPs on byt*/
};
EXPORT_SYMBOL(sof_byt_ops);

Expand Down Expand Up @@ -920,7 +910,9 @@ struct snd_sof_dsp_ops sof_cht_ops = {
.load_firmware = snd_sof_load_firmware_memcpy,

/* DAI drivers */
.dai_drv = &cht_dai_drv,
.drv = byt_dai,
/* all 6 SSPs may be available for cherrytrail */
.num_drv = ARRAY_SIZE(byt_dai),
};
EXPORT_SYMBOL(sof_cht_ops);

Expand Down
3 changes: 2 additions & 1 deletion sound/soc/sof/intel/cnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ struct snd_sof_dsp_ops sof_cnl_ops = {
.trace_trigger = hda_dsp_trace_trigger,

/* DAI drivers */
.dai_drv = &hda_dai_drv,
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this define? ARRAY_SIZE(skl_dai) would do, no?

};
EXPORT_SYMBOL(sof_cnl_ops);
7 changes: 1 addition & 6 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* some products who use this DAI array only physically have a subset of
* the DAIs, but no harm is done here by adding the whole set.
*/
static struct snd_soc_dai_driver skl_dai[] = {
struct snd_soc_dai_driver skl_dai[] = {
{
.name = "SSP0 Pin",
.playback = SOF_DAI_STREAM("ssp0 Tx", 1, 8,
Expand Down Expand Up @@ -111,9 +111,4 @@ static struct snd_soc_dai_driver skl_dai[] = {
},
};

struct snd_sof_dai_drv hda_dai_drv = {
.drv = skl_dai,
.num_drv = ARRAY_SIZE(skl_dai)
};
EXPORT_SYMBOL(hda_dai_drv);

5 changes: 4 additions & 1 deletion sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@
#define HDA_DSP_MAX_BDL_ENTRIES \
(HDA_DSP_BDL_SIZE / sizeof(struct sof_intel_dsp_bdl))

/* Number of DAIs */
#define SOF_SKL_NUM_DAIS 14

struct sof_intel_dsp_bdl {
u32 addr_l;
u32 addr_h;
Expand Down Expand Up @@ -495,7 +498,7 @@ int hda_dsp_trace_release(struct snd_sof_dev *sdev);
int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);

/* common dai driver */
extern struct snd_sof_dai_drv hda_dai_drv;
extern struct snd_soc_dai_driver skl_dai[];

/*
* Platform Specific HW abstraction Ops.
Expand Down
8 changes: 2 additions & 6 deletions sound/soc/sof/intel/hsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,6 @@ static struct snd_soc_dai_driver hsw_dai[] = {
},
};

static struct snd_sof_dai_drv hsw_dai_drv = {
.drv = hsw_dai,
.num_drv = ARRAY_SIZE(hsw_dai)
};

/* haswell ops */
struct snd_sof_dsp_ops sof_hsw_ops = {
/*Device init */
Expand Down Expand Up @@ -791,7 +786,8 @@ struct snd_sof_dsp_ops sof_hsw_ops = {
.load_firmware = snd_sof_load_firmware_memcpy,

/* DAI drivers */
.dai_drv = &hsw_dai_drv,
.drv = hsw_dai,
.num_drv = ARRAY_SIZE(hsw_dai)

};
EXPORT_SYMBOL(sof_hsw_ops);
Expand Down
3 changes: 2 additions & 1 deletion sound/soc/sof/intel/skl.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct snd_sof_dsp_ops sof_skl_ops = {
.trace_trigger = hda_dsp_trace_trigger,

/* DAI drivers */
.dai_drv = &hda_dai_drv,
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
};
EXPORT_SYMBOL(sof_skl_ops);
4 changes: 2 additions & 2 deletions sound/soc/sof/nocodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ int sof_nocodec_setup(struct device *dev,

/* create dummy BE dai_links */
links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
ops->dai_drv->num_drv, GFP_KERNEL);
ops->num_drv, GFP_KERNEL);
if (!links)
return -ENOMEM;

ret = sof_bes_setup(dev, ops, links, ops->dai_drv->num_drv,
ret = sof_bes_setup(dev, ops, links, ops->num_drv,
&sof_nocodec_card);
if (ret) {
kfree(links);
Expand Down
2 changes: 0 additions & 2 deletions sound/soc/sof/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream,
params);
dev_dbg(sdev->dev, "stream_tag %d", pcm.params.stream_tag);


/* send IPC to the DSP */
ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
&ipc_params_reply, sizeof(ipc_params_reply));
Expand Down Expand Up @@ -233,7 +232,6 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return -EINVAL;
}

/* set RUN firstly per the sequence suggested by firmware team */
snd_sof_pcm_platform_trigger(sdev, substream, cmd);

/* send IPC to the DSP */
Expand Down
15 changes: 6 additions & 9 deletions sound/soc/sof/sof-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ struct snd_soc_component;
struct sof_intel_hda_dev;
struct snd_sof_pdata;

struct snd_sof_dai_drv {
struct snd_soc_dai_driver *drv;
int num_drv;
};

/*
* SOF DSP HW abstraction operations.
* Used to abstract DSP HW architecture and any IO busses between host CPU
Expand Down Expand Up @@ -156,7 +151,8 @@ struct snd_sof_dsp_ops {
int (*trace_trigger)(struct snd_sof_dev *sdev, int cmd);

/* DAI ops */
struct snd_sof_dai_drv *dai_drv;
struct snd_soc_dai_driver *drv;
int num_drv;
};

/* DSP architecture specific callbacks for oops and stack dumps */
Expand Down Expand Up @@ -231,7 +227,7 @@ struct snd_sof_pcm {
struct snd_soc_tplg_pcm pcm;
struct snd_sof_pcm_stream stream[2];
u32 posn_offset[2];
struct mutex mutex;
struct mutex mutex; /* access mutex */
struct list_head list; /* list in sdev pcm list */
};

Expand All @@ -246,7 +242,7 @@ struct snd_sof_control {
enum sof_ipc_ctrl_cmd cmd;
u32 *volume_table; /* volume table computed from tlv data*/

struct mutex mutex;
struct mutex mutex; /* access mutex */
struct list_head list; /* list in sdev control list */
};

Expand All @@ -259,7 +255,7 @@ struct snd_sof_widget {
int id;

struct snd_soc_dapm_widget *widget;
struct mutex mutex;
struct mutex mutex; /* access mutex */
struct list_head list; /* list in sdev widget list */

void *private; /* core does not touch this */
Expand Down Expand Up @@ -349,6 +345,7 @@ struct snd_sof_dev {
wait_queue_head_t trace_sleep;
u32 host_offset;
bool dtrace_is_enabled;
bool dtrace_error;

void *private; /* core does not touch this */
};
Expand Down
Loading