summaryrefslogtreecommitdiff
path: root/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c')
-rw-r--r--drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c129
1 files changed, 79 insertions, 50 deletions
diff --git a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
index bf9f34b7ad72..d8b7183db252 100644
--- a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
@@ -114,7 +114,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
struct i2c_board_info *bi;
struct gmin_subdev *gs;
struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct acpi_device *adev;
+ struct acpi_device *adev = ACPI_COMPANION(&client->dev);
dev_info(&client->dev, "register atomisp i2c module type %d\n", type);
@@ -124,9 +124,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
* tickled during suspend/resume. This has caused power and
* performance issues on multiple devices.
*/
- adev = ACPI_COMPANION(&client->dev);
- if (adev)
- adev->power.flags.power_resources = 0;
+ adev->power.flags.power_resources = 0;
for (i = 0; i < MAX_SUBDEVS; i++)
if (!pdata.subdevs[i].type)
@@ -211,7 +209,7 @@ struct gmin_cfg_var {
const char *name, *val;
};
-static const struct gmin_cfg_var ffrd8_vars[] = {
+static struct gmin_cfg_var ffrd8_vars[] = {
{ "INTCF1B:00_ImxId", "0x134" },
{ "INTCF1B:00_CsiPort", "1" },
{ "INTCF1B:00_CsiLanes", "4" },
@@ -222,14 +220,14 @@ static const struct gmin_cfg_var ffrd8_vars[] = {
/* Cribbed from MCG defaults in the mt9m114 driver, not actually verified
* vs. T100 hardware
*/
-static const struct gmin_cfg_var t100_vars[] = {
+static struct gmin_cfg_var t100_vars[] = {
{ "INT33F0:00_CsiPort", "0" },
{ "INT33F0:00_CsiLanes", "1" },
{ "INT33F0:00_CamClk", "1" },
{},
};
-static const struct gmin_cfg_var mrd7_vars[] = {
+static struct gmin_cfg_var mrd7_vars[] = {
{"INT33F8:00_CamType", "1"},
{"INT33F8:00_CsiPort", "1"},
{"INT33F8:00_CsiLanes", "2"},
@@ -245,7 +243,7 @@ static const struct gmin_cfg_var mrd7_vars[] = {
{},
};
-static const struct gmin_cfg_var ecs7_vars[] = {
+static struct gmin_cfg_var ecs7_vars[] = {
{"INT33BE:00_CsiPort", "1"},
{"INT33BE:00_CsiLanes", "2"},
{"INT33BE:00_CsiFmt", "13"},
@@ -260,8 +258,7 @@ static const struct gmin_cfg_var ecs7_vars[] = {
{},
};
-
-static const struct gmin_cfg_var i8880_vars[] = {
+static struct gmin_cfg_var i8880_vars[] = {
{"XXOV2680:00_CsiPort", "1"},
{"XXOV2680:00_CsiLanes", "1"},
{"XXOV2680:00_CamClk", "0"},
@@ -271,18 +268,46 @@ static const struct gmin_cfg_var i8880_vars[] = {
{},
};
-static const struct {
- const char *dmi_board_name;
- const struct gmin_cfg_var *vars;
-} hard_vars[] = {
- { "BYT-T FFD8", ffrd8_vars },
- { "T100TA", t100_vars },
- { "MRD7", mrd7_vars },
- { "ST70408", ecs7_vars },
- { "VTA0803", i8880_vars },
+static const struct dmi_system_id gmin_vars[] = {
+ {
+ .ident = "BYT-T FFD8",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+ },
+ .driver_data = ffrd8_vars,
+ },
+ {
+ .ident = "T100TA",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "T100TA"),
+ },
+ .driver_data = t100_vars,
+ },
+ {
+ .ident = "MRD7",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "TABLET"),
+ DMI_MATCH(DMI_BOARD_VERSION, "MRD 7"),
+ },
+ .driver_data = mrd7_vars,
+ },
+ {
+ .ident = "ST70408",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "ST70408"),
+ },
+ .driver_data = ecs7_vars,
+ },
+ {
+ .ident = "VTA0803",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "VTA0803"),
+ },
+ .driver_data = i8880_vars,
+ },
+ {}
};
-
#define GMIN_CFG_VAR_EFI_GUID EFI_GUID(0xecb54cd9, 0xe5ae, 0x4fdc, \
0xa9, 0x71, 0xe8, 0x77, \
0x75, 0x60, 0x68, 0xf7)
@@ -322,8 +347,6 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
VLV2_CLK_PLL_19P2MHZ);
gmin_subdevs[i].csi_port = gmin_get_var_int(dev, "CsiPort", 0);
gmin_subdevs[i].csi_lanes = gmin_get_var_int(dev, "CsiLanes", 1);
- gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
- gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
/* get PMC clock with clock framework */
snprintf(gmin_pmc_clk_name,
@@ -356,9 +379,11 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
if (!ret)
clk_disable_unprepare(gmin_subdevs[i].pmc_clk);
+ gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
if (IS_ERR(gmin_subdevs[i].gpio0))
gmin_subdevs[i].gpio0 = NULL;
+ gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
if (IS_ERR(gmin_subdevs[i].gpio1))
gmin_subdevs[i].gpio1 = NULL;
@@ -394,7 +419,7 @@ static int gmin_gpio0_ctrl(struct v4l2_subdev *subdev, int on)
{
struct gmin_subdev *gs = find_gmin_subdev(subdev);
- if (gs && gs->gpio0) {
+ if (gs) {
gpiod_set_value(gs->gpio0, on);
return 0;
}
@@ -405,7 +430,7 @@ static int gmin_gpio1_ctrl(struct v4l2_subdev *subdev, int on)
{
struct gmin_subdev *gs = find_gmin_subdev(subdev);
- if (gs && gs->gpio1) {
+ if (gs) {
gpiod_set_value(gs->gpio1, on);
return 0;
}
@@ -606,17 +631,41 @@ int atomisp_gmin_register_vcm_control(struct camera_vcm_control *vcmCtrl)
}
EXPORT_SYMBOL_GPL(atomisp_gmin_register_vcm_control);
+static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
+ const char *var8, char *out, size_t *out_len)
+{
+ struct gmin_cfg_var *gv;
+
+ for (gv = varlist; gv->name; gv++) {
+ size_t vl;
+
+ if (strcmp(var8, gv->name))
+ continue;
+
+ vl = strlen(gv->val);
+ if (vl > *out_len - 1)
+ return -ENOSPC;
+
+ strcpy(out, gv->val);
+ *out_len = vl;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
/* Retrieves a device-specific configuration variable. The dev
* argument should be a device with an ACPI companion, as all
* configuration is based on firmware ID.
*/
-int gmin_get_config_var(struct device *dev, const char *var, char *out,
- size_t *out_len)
+static int gmin_get_config_var(struct device *dev, const char *var,
+ char *out, size_t *out_len)
{
char var8[CFG_VAR_NAME_MAX];
efi_char16_t var16[CFG_VAR_NAME_MAX];
struct efivar_entry *ev;
- int i, j, ret;
+ const struct dmi_system_id *id;
+ int i, ret;
if (dev && ACPI_COMPANION(dev))
dev = &ACPI_COMPANION(dev)->dev;
@@ -633,28 +682,9 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
* Some device firmwares lack the ability to set EFI variables at
* runtime.
*/
- for (i = 0; i < ARRAY_SIZE(hard_vars); i++) {
- if (dmi_match(DMI_BOARD_NAME, hard_vars[i].dmi_board_name)) {
- for (j = 0; hard_vars[i].vars[j].name; j++) {
- size_t vl;
- const struct gmin_cfg_var *gv;
-
- gv = &hard_vars[i].vars[j];
- vl = strlen(gv->val);
-
- if (strcmp(var8, gv->name))
- continue;
- if (vl > *out_len - 1)
- return -ENOSPC;
-
- memcpy(out, gv->val, min(*out_len, vl+1));
- out[*out_len-1] = 0;
- *out_len = vl;
-
- return 0;
- }
- }
- }
+ id = dmi_first_match(gmin_vars);
+ if (id)
+ return gmin_get_hardcoded_var(id->driver_data, var8, out, out_len);
/* Our variable names are ASCII by construction, but EFI names
* are wide chars. Convert and zero-pad.
@@ -693,7 +723,6 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
return ret;
}
-EXPORT_SYMBOL_GPL(gmin_get_config_var);
int gmin_get_var_int(struct device *dev, const char *var, int def)
{