Commit 055fb9ce authored by Vaibhav Agarwal's avatar Vaibhav Agarwal Committed by Greg Kroah-Hartman

staging: greybus: audio: Ensure proper byte order

Proper byte order was completely disregarded for multi byte data shared
between AP and module (and APB1). Fix this.
Signed-off-by: default avatarVaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: default avatarVaibhav Agarwal <vaibhav.sr@gmail.com>
Acked-by: default avatarMark Greer <mgreer@animalcreek.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 96249da9
...@@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module, ...@@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module,
struct gb_audio_streaming_event_request *req) struct gb_audio_streaming_event_request *req)
{ {
dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n", dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n",
req->data_cport, req->event); le16_to_cpu(req->data_cport), req->event);
return 0; return 0;
} }
......
...@@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, ...@@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
{ {
const char **strings; const char **strings;
int i; int i;
unsigned int items;
__u8 *data; __u8 *data;
strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items, items = le32_to_cpu(gbenum->items);
GFP_KERNEL); strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL);
data = gbenum->names; data = gbenum->names;
for (i = 0; i < gbenum->items; i++) { for (i = 0; i < items; i++) {
strings[i] = (const char *)data; strings[i] = (const char *)data;
while (*data != '\0') while (*data != '\0')
data++; data++;
...@@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, ...@@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
switch (info->type) { switch (info->type) {
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
uinfo->value.integer.min = info->value.integer.min; uinfo->value.integer.min = le32_to_cpu(info->value.integer.min);
uinfo->value.integer.max = info->value.integer.max; uinfo->value.integer.max = le32_to_cpu(info->value.integer.max);
break; break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
max = info->value.enumerated.items; max = le32_to_cpu(info->value.enumerated.items);
uinfo->value.enumerated.items = max; uinfo->value.enumerated.items = max;
if (uinfo->value.enumerated.item > max - 1) if (uinfo->value.enumerated.item > max - 1)
uinfo->value.enumerated.item = max - 1; uinfo->value.enumerated.item = max - 1;
...@@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol, ...@@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] =
gbvalue.value.integer_value[0]; le32_to_cpu(gbvalue.value.integer_value[0]);
if (data->vcount == 2) if (data->vcount == 2)
ucontrol->value.integer.value[1] = ucontrol->value.integer.value[1] =
gbvalue.value.integer_value[1]; le32_to_cpu(gbvalue.value.integer_value[1]);
break; break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
ucontrol->value.enumerated.item[0] = ucontrol->value.enumerated.item[0] =
gbvalue.value.enumerated_item[0]; le32_to_cpu(gbvalue.value.enumerated_item[0]);
if (data->vcount == 2) if (data->vcount == 2)
ucontrol->value.enumerated.item[1] = ucontrol->value.enumerated.item[1] =
gbvalue.value.enumerated_item[1]; le32_to_cpu(gbvalue.value.enumerated_item[1]);
break; break;
default: default:
dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
...@@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, ...@@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
gbvalue.value.integer_value[0] = gbvalue.value.integer_value[0] =
ucontrol->value.integer.value[0]; cpu_to_le32(ucontrol->value.integer.value[0]);
if (data->vcount == 2) if (data->vcount == 2)
gbvalue.value.integer_value[1] = gbvalue.value.integer_value[1] =
ucontrol->value.integer.value[1]; cpu_to_le32(ucontrol->value.integer.value[1]);
break; break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
gbvalue.value.enumerated_item[0] = gbvalue.value.enumerated_item[0] =
ucontrol->value.enumerated.item[0]; cpu_to_le32(ucontrol->value.enumerated.item[0]);
if (data->vcount == 2) if (data->vcount == 2)
gbvalue.value.enumerated_item[1] = gbvalue.value.enumerated_item[1] =
ucontrol->value.enumerated.item[1]; cpu_to_le32(ucontrol->value.enumerated.item[1]);
break; break;
default: default:
dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
...@@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol, ...@@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
info = (struct gb_audio_ctl_elem_info *)data->info; info = (struct gb_audio_ctl_elem_info *)data->info;
/* update uinfo */ /* update uinfo */
platform_max = info->value.integer.max; platform_max = le32_to_cpu(info->value.integer.max);
platform_min = info->value.integer.min; platform_min = le32_to_cpu(info->value.integer.min);
if (platform_max == 1 && if (platform_max == 1 &&
!strnstr(kcontrol->id.name, " Volume", NAME_SIZE)) !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
...@@ -420,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, ...@@ -420,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
return ret; return ret;
} }
/* update ucontrol */ /* update ucontrol */
ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0]; ucontrol->value.integer.value[0] =
le32_to_cpu(gbvalue.value.integer_value[0]);
return ret; return ret;
} }
...@@ -454,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, ...@@ -454,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
"GB: Control '%s' is stereo, which is not supported\n", "GB: Control '%s' is stereo, which is not supported\n",
kcontrol->id.name); kcontrol->id.name);
max = info->value.integer.max; max = le32_to_cpu(info->value.integer.max);
mask = (1 << fls(max)) - 1; mask = (1 << fls(max)) - 1;
val = ucontrol->value.integer.value[0] & mask; val = ucontrol->value.integer.value[0] & mask;
connect = !!val; connect = !!val;
...@@ -470,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, ...@@ -470,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
connect); connect);
} }
gbvalue.value.integer_value[0] = gbvalue.value.integer_value[0] =
ucontrol->value.integer.value[0]; cpu_to_le32(ucontrol->value.integer.value[0]);
ret = gb_pm_runtime_get_sync(bundle); ret = gb_pm_runtime_get_sync(bundle);
if (ret) if (ret)
...@@ -584,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol, ...@@ -584,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
return ret; return ret;
} }
ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; ucontrol->value.enumerated.item[0] =
le32_to_cpu(gbvalue.value.enumerated_item[0]);
if (e->shift_l != e->shift_r) if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] = ucontrol->value.enumerated.item[1] =
gbvalue.value.enumerated_item[1]; le32_to_cpu(gbvalue.value.enumerated_item[1]);
return 0; return 0;
} }
...@@ -613,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol, ...@@ -613,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.enumerated.item[0] > e->max - 1) if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL; return -EINVAL;
gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0]; gbvalue.value.enumerated_item[0] =
cpu_to_le32(ucontrol->value.enumerated.item[0]);
if (e->shift_l != e->shift_r) { if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1) if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL; return -EINVAL;
gbvalue.value.enumerated_item[1] = gbvalue.value.enumerated_item[1] =
ucontrol->value.enumerated.item[1]; cpu_to_le32(ucontrol->value.enumerated.item[1]);
} }
bundle = to_gb_bundle(module->dev); bundle = to_gb_bundle(module->dev);
...@@ -656,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb, ...@@ -656,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
gb_enum = &ctl->info.value.enumerated; gb_enum = &ctl->info.value.enumerated;
/* since count=1, and reg is dummy */ /* since count=1, and reg is dummy */
gbe->max = gb_enum->items; gbe->max = le32_to_cpu(gb_enum->items);
gbe->texts = gb_generate_enum_strings(gb, gb_enum); gbe->texts = gb_generate_enum_strings(gb, gb_enum);
/* debug enum info */ /* debug enum info */
dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
gb_enum->names_length); le16_to_cpu(gb_enum->names_length));
for (i = 0; i < gb_enum->items; i++) for (i = 0; i < gbe->max; i++)
dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new) *kctl = (struct snd_kcontrol_new)
...@@ -691,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, ...@@ -691,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
if (!ctldata) if (!ctldata)
return -ENOMEM; return -ENOMEM;
ctldata->ctl_id = ctl->id; ctldata->ctl_id = ctl->id;
ctldata->data_cport = ctl->data_cport; ctldata->data_cport = le16_to_cpu(ctl->data_cport);
ctldata->access = ctl->access; ctldata->access = ctl->access;
ctldata->vcount = ctl->count_values; ctldata->vcount = ctl->count_values;
ctldata->info = &ctl->info; ctldata->info = &ctl->info;
...@@ -865,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb, ...@@ -865,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
gb_enum = &ctl->info.value.enumerated; gb_enum = &ctl->info.value.enumerated;
/* since count=1, and reg is dummy */ /* since count=1, and reg is dummy */
gbe->max = gb_enum->items; gbe->max = le32_to_cpu(gb_enum->items);
gbe->texts = gb_generate_enum_strings(gb, gb_enum); gbe->texts = gb_generate_enum_strings(gb, gb_enum);
/* debug enum info */ /* debug enum info */
dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
gb_enum->names_length); le16_to_cpu(gb_enum->names_length));
for (i = 0; i < gb_enum->items; i++) for (i = 0; i < gbe->max; i++)
dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]); dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new) *kctl = (struct snd_kcontrol_new)
...@@ -891,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, ...@@ -891,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
if (!ctldata) if (!ctldata)
return -ENOMEM; return -ENOMEM;
ctldata->ctl_id = ctl->id; ctldata->ctl_id = ctl->id;
ctldata->data_cport = ctl->data_cport; ctldata->data_cport = le16_to_cpu(ctl->data_cport);
ctldata->access = ctl->access; ctldata->access = ctl->access;
ctldata->vcount = ctl->count_values; ctldata->vcount = ctl->count_values;
ctldata->info = &ctl->info; ctldata->info = &ctl->info;
...@@ -1037,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module, ...@@ -1037,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
csize = offsetof(struct gb_audio_control, info); csize = offsetof(struct gb_audio_control, info);
csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_ctl_elem_info, value);
csize += offsetof(struct gb_audio_enumerated, names); csize += offsetof(struct gb_audio_enumerated, names);
csize += gbenum->names_length; csize += le16_to_cpu(gbenum->names_length);
control->texts = (const char * const *) control->texts = (const char * const *)
gb_generate_enum_strings(module, gbenum); gb_generate_enum_strings(module, gbenum);
control->items = gbenum->items; control->items = le32_to_cpu(gbenum->items);
} else { } else {
csize = sizeof(struct gb_audio_control); csize = sizeof(struct gb_audio_control);
} }
...@@ -1185,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module, ...@@ -1185,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
csize = offsetof(struct gb_audio_control, info); csize = offsetof(struct gb_audio_control, info);
csize += offsetof(struct gb_audio_ctl_elem_info, value); csize += offsetof(struct gb_audio_ctl_elem_info, value);
csize += offsetof(struct gb_audio_enumerated, names); csize += offsetof(struct gb_audio_enumerated, names);
csize += gbenum->names_length; csize += le16_to_cpu(gbenum->names_length);
control->texts = (const char * const *) control->texts = (const char * const *)
gb_generate_enum_strings(module, gbenum); gb_generate_enum_strings(module, gbenum);
control->items = gbenum->items; control->items = le32_to_cpu(gbenum->items);
} else { } else {
csize = sizeof(struct gb_audio_control); csize = sizeof(struct gb_audio_control);
} }
...@@ -1331,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module, ...@@ -1331,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
/* update block offset */ /* update block offset */
module->dai_offset = (unsigned long)&tplg_data->data; module->dai_offset = (unsigned long)&tplg_data->data;
module->control_offset = module->dai_offset + tplg_data->size_dais; module->control_offset = module->dai_offset +
le32_to_cpu(tplg_data->size_dais);
module->widget_offset = module->control_offset + module->widget_offset = module->control_offset +
tplg_data->size_controls; le32_to_cpu(tplg_data->size_controls);
module->route_offset = module->widget_offset + module->route_offset = module->widget_offset +
tplg_data->size_widgets; le32_to_cpu(tplg_data->size_widgets);
dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset); dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
dev_dbg(module->dev, "control offset is %lx\n", dev_dbg(module->dev, "control offset is %lx\n",
...@@ -1353,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, ...@@ -1353,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
struct gb_audio_control *controls; struct gb_audio_control *controls;
struct gb_audio_widget *widgets; struct gb_audio_widget *widgets;
struct gb_audio_route *routes; struct gb_audio_route *routes;
unsigned int jack_type;
if (!tplg_data) if (!tplg_data)
return -EINVAL; return -EINVAL;
...@@ -1395,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, ...@@ -1395,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
dev_dbg(module->dev, "Route parsing finished\n"); dev_dbg(module->dev, "Route parsing finished\n");
/* parse jack capabilities */ /* parse jack capabilities */
if (tplg_data->jack_type) { jack_type = le32_to_cpu(tplg_data->jack_type);
module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK; if (jack_type) {
module->button_mask = tplg_data->jack_type & module->jack_mask = jack_type & GBCODEC_JACK_MASK;
GBCODEC_JACK_BUTTON_MASK; module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK;
} }
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment