diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:54:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:54:50 -0400 |
commit | 92295f632cefbdf15d46e9ac5f0fc3cfade35259 (patch) | |
tree | 5b3820d4ed135ccbef540781d99a46137959bbb6 /drivers/clk/clk-si5351.c | |
parent | 750b2d7b93f2ba19f4f238cc641bda22fe07c155 (diff) | |
parent | 45e3ec3784aec0d194740b75b547bfabca448ff3 (diff) |
Merge tag 'clk-for-linus-3.11' of git://git.linaro.org/people/mturquette/linux
Pull clock framework updates from Mike Turquette:
"The common clock framework changes for 3.11 include new clock drivers
across several different platforms and architectures, fixes to
existing drivers, a MAINTAINERS file fix and improvements to the basic
clock types that allow them to be of use to more platforms than before.
Only a few fixes to the core framework are included with most all of
the changes landing in the various clock drivers themselves."
* tag 'clk-for-linus-3.11' of git://git.linaro.org/people/mturquette/linux: (55 commits)
clk: tegra: fix ifdef for tegra_periph_reset_assert inline
clk: tegra: provide tegra_periph_reset_assert alternative
clk: exynos4: Fix clock aliases for cpufreq related clocks
clk: samsung: Add MUX_FA macro to pass flag and alias
clk: add support for Rockchip gate clocks
clk: vexpress: Make the clock drivers directly available for arm64
clk: vexpress: Use full node name to identify individual clocks
clk: tegra: T114: add DFLL DVCO reset control
clk: tegra: T114: add DFLL source clocks
clk: tegra: T114: add FCPU clock shaper programming, needed by the DFLL
clk: gate: add CLK_GATE_HIWORD_MASK
clk: divider: add CLK_DIVIDER_HIWORD_MASK flag
clk: mux: add CLK_MUX_HIWORD_MASK
clk: Always notify whole subtree when reparenting
MAINTAINERS: make drivers/clk entry match subdirs
clk: honor CLK_GET_RATE_NOCACHE in clk_set_rate
clk: use clk_get_rate() for debugfs
clk: tegra: Use override bits when needed
clk: tegra: override bits for Tegra30 PLLM
clk: tegra: override bits for Tegra114 PLLM
...
Diffstat (limited to 'drivers/clk/clk-si5351.c')
-rw-r--r-- | drivers/clk/clk-si5351.c | 79 |
1 files changed, 75 insertions, 4 deletions
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 24f553673b72..c50e83744b0a 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c | |||
@@ -851,6 +851,41 @@ static int _si5351_clkout_set_drive_strength( | |||
851 | return 0; | 851 | return 0; |
852 | } | 852 | } |
853 | 853 | ||
854 | static int _si5351_clkout_set_disable_state( | ||
855 | struct si5351_driver_data *drvdata, int num, | ||
856 | enum si5351_disable_state state) | ||
857 | { | ||
858 | u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE : | ||
859 | SI5351_CLK7_4_DISABLE_STATE; | ||
860 | u8 shift = (num < 4) ? (2 * num) : (2 * (num-4)); | ||
861 | u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift; | ||
862 | u8 val; | ||
863 | |||
864 | if (num > 8) | ||
865 | return -EINVAL; | ||
866 | |||
867 | switch (state) { | ||
868 | case SI5351_DISABLE_LOW: | ||
869 | val = SI5351_CLK_DISABLE_STATE_LOW; | ||
870 | break; | ||
871 | case SI5351_DISABLE_HIGH: | ||
872 | val = SI5351_CLK_DISABLE_STATE_HIGH; | ||
873 | break; | ||
874 | case SI5351_DISABLE_FLOATING: | ||
875 | val = SI5351_CLK_DISABLE_STATE_FLOAT; | ||
876 | break; | ||
877 | case SI5351_DISABLE_NEVER: | ||
878 | val = SI5351_CLK_DISABLE_STATE_NEVER; | ||
879 | break; | ||
880 | default: | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | si5351_set_bits(drvdata, reg, mask, val << shift); | ||
885 | |||
886 | return 0; | ||
887 | } | ||
888 | |||
854 | static int si5351_clkout_prepare(struct clk_hw *hw) | 889 | static int si5351_clkout_prepare(struct clk_hw *hw) |
855 | { | 890 | { |
856 | struct si5351_hw_data *hwdata = | 891 | struct si5351_hw_data *hwdata = |
@@ -1225,6 +1260,33 @@ static int si5351_dt_parse(struct i2c_client *client) | |||
1225 | } | 1260 | } |
1226 | } | 1261 | } |
1227 | 1262 | ||
1263 | if (!of_property_read_u32(child, "silabs,disable-state", | ||
1264 | &val)) { | ||
1265 | switch (val) { | ||
1266 | case 0: | ||
1267 | pdata->clkout[num].disable_state = | ||
1268 | SI5351_DISABLE_LOW; | ||
1269 | break; | ||
1270 | case 1: | ||
1271 | pdata->clkout[num].disable_state = | ||
1272 | SI5351_DISABLE_HIGH; | ||
1273 | break; | ||
1274 | case 2: | ||
1275 | pdata->clkout[num].disable_state = | ||
1276 | SI5351_DISABLE_FLOATING; | ||
1277 | break; | ||
1278 | case 3: | ||
1279 | pdata->clkout[num].disable_state = | ||
1280 | SI5351_DISABLE_NEVER; | ||
1281 | break; | ||
1282 | default: | ||
1283 | dev_err(&client->dev, | ||
1284 | "invalid disable state %d for clkout %d\n", | ||
1285 | val, num); | ||
1286 | return -EINVAL; | ||
1287 | } | ||
1288 | } | ||
1289 | |||
1228 | if (!of_property_read_u32(child, "clock-frequency", &val)) | 1290 | if (!of_property_read_u32(child, "clock-frequency", &val)) |
1229 | pdata->clkout[num].rate = val; | 1291 | pdata->clkout[num].rate = val; |
1230 | 1292 | ||
@@ -1281,9 +1343,6 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1281 | 1343 | ||
1282 | /* Disable interrupts */ | 1344 | /* Disable interrupts */ |
1283 | si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0); | 1345 | si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0); |
1284 | /* Set disabled output drivers to drive low */ | ||
1285 | si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00); | ||
1286 | si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00); | ||
1287 | /* Ensure pll select is on XTAL for Si5351A/B */ | 1346 | /* Ensure pll select is on XTAL for Si5351A/B */ |
1288 | if (drvdata->variant != SI5351_VARIANT_C) | 1347 | if (drvdata->variant != SI5351_VARIANT_C) |
1289 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, | 1348 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, |
@@ -1327,6 +1386,15 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1327 | n, pdata->clkout[n].drive); | 1386 | n, pdata->clkout[n].drive); |
1328 | return ret; | 1387 | return ret; |
1329 | } | 1388 | } |
1389 | |||
1390 | ret = _si5351_clkout_set_disable_state(drvdata, n, | ||
1391 | pdata->clkout[n].disable_state); | ||
1392 | if (ret) { | ||
1393 | dev_err(&client->dev, | ||
1394 | "failed set disable state of clkout%d to %d\n", | ||
1395 | n, pdata->clkout[n].disable_state); | ||
1396 | return ret; | ||
1397 | } | ||
1330 | } | 1398 | } |
1331 | 1399 | ||
1332 | /* register xtal input clock gate */ | 1400 | /* register xtal input clock gate */ |
@@ -1500,7 +1568,10 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1500 | } | 1568 | } |
1501 | 1569 | ||
1502 | static const struct i2c_device_id si5351_i2c_ids[] = { | 1570 | static const struct i2c_device_id si5351_i2c_ids[] = { |
1503 | { "silabs,si5351", 0 }, | 1571 | { "si5351a", 0 }, |
1572 | { "si5351a-msop", 0 }, | ||
1573 | { "si5351b", 0 }, | ||
1574 | { "si5351c", 0 }, | ||
1504 | { } | 1575 | { } |
1505 | }; | 1576 | }; |
1506 | MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); | 1577 | MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); |