From: Vaibhav Agarwal vaibhav.agarwal@linaro.org
Proper byte order was completely disregarded for multi byte data shared between AP and module (and APB1). Fix this.
Signed-off-by: Vaibhav Agarwal vaibhav.agarwal@linaro.org --- drivers/staging/greybus/audio_module.c | 2 +- drivers/staging/greybus/audio_topology.c | 88 +++++++++++++++++--------------- 2 files changed, 48 insertions(+), 42 deletions(-)
diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 17a9948b1ba1..094c3be79b33 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module, struct gb_audio_streaming_event_request *req) { 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; } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index a8b63a8b2bb0..4002a57977bd 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, { const char **strings; int i; + unsigned int items; __u8 *data;
- strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items, - GFP_KERNEL); + items = le32_to_cpu(gbenum->items); + strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL); data = gbenum->names;
- for (i = 0; i < gbenum->items; i++) { + for (i = 0; i < items; i++) { strings[i] = (const char *)data; while (*data != '\0') data++; @@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: - uinfo->value.integer.min = info->value.integer.min; - uinfo->value.integer.max = info->value.integer.max; + uinfo->value.integer.min = le32_to_cpu(info->value.integer.min); + uinfo->value.integer.max = le32_to_cpu(info->value.integer.max); break; 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; if (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, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: ucontrol->value.integer.value[0] = - gbvalue.value.integer_value[0]; + le32_to_cpu(gbvalue.value.integer_value[0]); if (data->vcount == 2) ucontrol->value.integer.value[1] = - gbvalue.value.integer_value[1]; + le32_to_cpu(gbvalue.value.integer_value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: ucontrol->value.enumerated.item[0] = - gbvalue.value.enumerated_item[0]; + le32_to_cpu(gbvalue.value.enumerated_item[0]); if (data->vcount == 2) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); break; default: 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, case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: case GB_AUDIO_CTL_ELEM_TYPE_INTEGER: gbvalue.value.integer_value[0] = - ucontrol->value.integer.value[0]; + cpu_to_le32(ucontrol->value.integer.value[0]); if (data->vcount == 2) gbvalue.value.integer_value[1] = - ucontrol->value.integer.value[1]; + cpu_to_le32(ucontrol->value.integer.value[1]); break; case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED: gbvalue.value.enumerated_item[0] = - ucontrol->value.enumerated.item[0]; + cpu_to_le32(ucontrol->value.enumerated.item[0]); if (data->vcount == 2) gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); break; default: dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n", @@ -420,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, return ret; } /* 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; } @@ -470,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, connect); } 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); if (ret) @@ -584,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol, 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) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]);
return 0; } @@ -613,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.enumerated.item[0] > e->max - 1) 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 (ucontrol->value.enumerated.item[1] > e->max - 1) return -EINVAL; gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); }
bundle = to_gb_bundle(module->dev); @@ -656,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated;
/* 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);
/* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new) @@ -691,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; 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->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -865,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb, gb_enum = &ctl->info.value.enumerated;
/* 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);
/* debug enum info */ - dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items, - gb_enum->names_length); - for (i = 0; i < gb_enum->items; i++) + dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max, + le16_to_cpu(gb_enum->names_length)); + for (i = 0; i < gbe->max; i++) dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new) @@ -891,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, if (!ctldata) return -ENOMEM; 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->vcount = ctl->count_values; ctldata->info = &ctl->info; @@ -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_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -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_ctl_elem_info, value); csize += offsetof(struct gb_audio_enumerated, names); - csize += gbenum->names_length; + csize += le16_to_cpu(gbenum->names_length); control->texts = (const char * const *) gb_generate_enum_strings(module, gbenum); - control->items = gbenum->items; + control->items = le32_to_cpu(gbenum->items); } else { csize = sizeof(struct gb_audio_control); } @@ -1331,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
/* update block offset */ 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 + - tplg_data->size_controls; + le32_to_cpu(tplg_data->size_controls); 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, "control offset is %lx\n", @@ -1353,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, struct gb_audio_control *controls; struct gb_audio_widget *widgets; struct gb_audio_route *routes; + unsigned int jack_type;
if (!tplg_data) return -EINVAL; @@ -1395,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, dev_dbg(module->dev, "Route parsing finished\n");
/* parse jack capabilities */ - if (tplg_data->jack_type) { - module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK; - module->button_mask = tplg_data->jack_type & - GBCODEC_JACK_BUTTON_MASK; + jack_type = le32_to_cpu(tplg_data->jack_type); + if (jack_type) { + module->jack_mask = jack_type & GBCODEC_JACK_MASK; + module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK; }
return ret;