diff options
author | Qiao Zhou <zhouqiao@marvell.com> | 2012-07-09 02:37:33 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-07-09 09:13:31 -0400 |
commit | 5500e3964b8c154dc5af51ebcd7cd4df5d4abfee (patch) | |
tree | 729e2fb0ecd6b84b445722637cb511edbcc9df0b /drivers/mfd/88pm80x.c | |
parent | 70c6cce040661204986ebbf22224cb24bd77ea71 (diff) |
mfd: Add companion chip in 88pm80x
in hw design, 800 is mainly for pmic control, while 805 for audio.
but there are 3 registers which controls class D speaker property,
and they are defined in 800 i2c client domain. so 805 codec driver
needs to use 800 i2c client to access class D speaker reg for
audio path management. so add this workaround for the purpose to
let 805 access 800 i2c in some scenario.
Signed-off-by: Qiao Zhou <zhouqiao@marvell.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/88pm80x.c')
-rw-r--r-- | drivers/mfd/88pm80x.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index 90aa18a37f79..77b865594c29 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c | |||
@@ -18,6 +18,12 @@ | |||
18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | 20 | ||
21 | /* | ||
22 | * workaround: some registers needed by pm805 are defined in pm800, so | ||
23 | * need to use this global variable to maintain the relation between | ||
24 | * pm800 and pm805. would remove it after HW chip fixes the issue. | ||
25 | */ | ||
26 | static struct pm80x_chip *g_pm80x_chip; | ||
21 | 27 | ||
22 | const struct regmap_config pm80x_regmap_config = { | 28 | const struct regmap_config pm80x_regmap_config = { |
23 | .reg_bits = 8, | 29 | .reg_bits = 8, |
@@ -61,6 +67,19 @@ int __devinit pm80x_init(struct i2c_client *client, | |||
61 | 67 | ||
62 | device_init_wakeup(&client->dev, 1); | 68 | device_init_wakeup(&client->dev, 1); |
63 | 69 | ||
70 | /* | ||
71 | * workaround: set g_pm80x_chip to the first probed chip. if the | ||
72 | * second chip is probed, just point to the companion to each | ||
73 | * other so that pm805 can access those specific register. would | ||
74 | * remove it after HW chip fixes the issue. | ||
75 | */ | ||
76 | if (!g_pm80x_chip) | ||
77 | g_pm80x_chip = chip; | ||
78 | else { | ||
79 | chip->companion = g_pm80x_chip->client; | ||
80 | g_pm80x_chip->companion = chip->client; | ||
81 | } | ||
82 | |||
64 | return 0; | 83 | return 0; |
65 | 84 | ||
66 | err_chip_id: | 85 | err_chip_id: |
@@ -75,6 +94,15 @@ int __devexit pm80x_deinit(struct i2c_client *client) | |||
75 | { | 94 | { |
76 | struct pm80x_chip *chip = i2c_get_clientdata(client); | 95 | struct pm80x_chip *chip = i2c_get_clientdata(client); |
77 | 96 | ||
97 | /* | ||
98 | * workaround: clear the dependency between pm800 and pm805. | ||
99 | * would remove it after HW chip fixes the issue. | ||
100 | */ | ||
101 | if (g_pm80x_chip->companion) | ||
102 | g_pm80x_chip->companion = NULL; | ||
103 | else | ||
104 | g_pm80x_chip = NULL; | ||
105 | |||
78 | regmap_exit(chip->regmap); | 106 | regmap_exit(chip->regmap); |
79 | devm_kfree(&client->dev, chip); | 107 | devm_kfree(&client->dev, chip); |
80 | 108 | ||