1 /* 2 * clk-max77686.c - Clock driver for Maxim 77686/MAX77802 3 * 4 * Copyright (C) 2012 Samsung Electornics 5 * Jonghwa Lee <jonghwa3.lee@samsung.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 */ 22 23 #include <linux/kernel.h> 24 #include <linux/slab.h> 25 #include <linux/err.h> 26 #include <linux/module.h> 27 #include <linux/platform_device.h> 28 #include <linux/mfd/max77620.h> 29 #include <linux/mfd/max77686.h> 30 #include <linux/mfd/max77686-private.h> 31 #include <linux/clk-provider.h> 32 #include <linux/mutex.h> 33 #include <linux/clkdev.h> 34 #include <linux/of.h> 35 #include <linux/regmap.h> 36 37 #include <dt-bindings/clock/maxim,max77686.h> 38 #include <dt-bindings/clock/maxim,max77802.h> 39 #include <dt-bindings/clock/maxim,max77620.h> 40 41 #define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3 42 43 enum max77686_chip_name { 44 CHIP_MAX77686, 45 CHIP_MAX77802, 46 CHIP_MAX77620, 47 }; 48 49 struct max77686_hw_clk_info { 50 const char *name; 51 u32 clk_reg; 52 u32 clk_enable_mask; 53 u32 flags; 54 }; 55 56 struct max77686_clk_init_data { 57 struct regmap *regmap; 58 struct clk_hw hw; 59 struct clk_init_data clk_idata; 60 const struct max77686_hw_clk_info *clk_info; 61 }; 62 63 struct max77686_clk_driver_data { 64 enum max77686_chip_name chip; 65 struct max77686_clk_init_data *max_clk_data; 66 size_t num_clks; 67 }; 68 69 static const struct 70 max77686_hw_clk_info max77686_hw_clks_info[MAX77686_CLKS_NUM] = { 71 [MAX77686_CLK_AP] = { 72 .name = "32khz_ap", 73 .clk_reg = MAX77686_REG_32KHZ, 74 .clk_enable_mask = BIT(MAX77686_CLK_AP), 75 }, 76 [MAX77686_CLK_CP] = { 77 .name = "32khz_cp", 78 .clk_reg = MAX77686_REG_32KHZ, 79 .clk_enable_mask = BIT(MAX77686_CLK_CP), 80 }, 81 [MAX77686_CLK_PMIC] = { 82 .name = "32khz_pmic", 83 .clk_reg = MAX77686_REG_32KHZ, 84 .clk_enable_mask = BIT(MAX77686_CLK_PMIC), 85 }, 86 }; 87 88 static const struct 89 max77686_hw_clk_info max77802_hw_clks_info[MAX77802_CLKS_NUM] = { 90 [MAX77802_CLK_32K_AP] = { 91 .name = "32khz_ap", 92 .clk_reg = MAX77802_REG_32KHZ, 93 .clk_enable_mask = BIT(MAX77802_CLK_32K_AP), 94 }, 95 [MAX77802_CLK_32K_CP] = { 96 .name = "32khz_cp", 97 .clk_reg = MAX77802_REG_32KHZ, 98 .clk_enable_mask = BIT(MAX77802_CLK_32K_CP), 99 }, 100 }; 101 102 static const struct 103 max77686_hw_clk_info max77620_hw_clks_info[MAX77620_CLKS_NUM] = { 104 [MAX77620_CLK_32K_OUT0] = { 105 .name = "32khz_out0", 106 .clk_reg = MAX77620_REG_CNFG1_32K, 107 .clk_enable_mask = MAX77620_CNFG1_32K_OUT0_EN, 108 }, 109 }; 110 111 static struct max77686_clk_init_data *to_max77686_clk_init_data( 112 struct clk_hw *hw) 113 { 114 return container_of(hw, struct max77686_clk_init_data, hw); 115 } 116 117 static int max77686_clk_prepare(struct clk_hw *hw) 118 { 119 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); 120 121 return regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg, 122 max77686->clk_info->clk_enable_mask, 123 max77686->clk_info->clk_enable_mask); 124 } 125 126 static void max77686_clk_unprepare(struct clk_hw *hw) 127 { 128 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); 129 130 regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg, 131 max77686->clk_info->clk_enable_mask, 132 ~max77686->clk_info->clk_enable_mask); 133 } 134 135 static int max77686_clk_is_prepared(struct clk_hw *hw) 136 { 137 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); 138 int ret; 139 u32 val; 140 141 ret = regmap_read(max77686->regmap, max77686->clk_info->clk_reg, &val); 142 143 if (ret < 0) 144 return -EINVAL; 145 146 return val & max77686->clk_info->clk_enable_mask; 147 } 148 149 static unsigned long max77686_recalc_rate(struct clk_hw *hw, 150 unsigned long parent_rate) 151 { 152 return 32768; 153 } 154 155 static struct clk_ops max77686_clk_ops = { 156 .prepare = max77686_clk_prepare, 157 .unprepare = max77686_clk_unprepare, 158 .is_prepared = max77686_clk_is_prepared, 159 .recalc_rate = max77686_recalc_rate, 160 }; 161 162 static struct clk_hw * 163 of_clk_max77686_get(struct of_phandle_args *clkspec, void *data) 164 { 165 struct max77686_clk_driver_data *drv_data = data; 166 unsigned int idx = clkspec->args[0]; 167 168 if (idx >= drv_data->num_clks) { 169 pr_err("%s: invalid index %u\n", __func__, idx); 170 return ERR_PTR(-EINVAL); 171 } 172 173 return &drv_data->max_clk_data[idx].hw; 174 } 175 176 static int max77686_clk_probe(struct platform_device *pdev) 177 { 178 struct device *dev = &pdev->dev; 179 struct device *parent = dev->parent; 180 const struct platform_device_id *id = platform_get_device_id(pdev); 181 struct max77686_clk_driver_data *drv_data; 182 const struct max77686_hw_clk_info *hw_clks; 183 struct regmap *regmap; 184 int i, ret, num_clks; 185 186 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); 187 if (!drv_data) 188 return -ENOMEM; 189 190 regmap = dev_get_regmap(parent, NULL); 191 if (!regmap) { 192 dev_err(dev, "Failed to get rtc regmap\n"); 193 return -ENODEV; 194 } 195 196 drv_data->chip = id->driver_data; 197 198 switch (drv_data->chip) { 199 case CHIP_MAX77686: 200 num_clks = MAX77686_CLKS_NUM; 201 hw_clks = max77686_hw_clks_info; 202 break; 203 204 case CHIP_MAX77802: 205 num_clks = MAX77802_CLKS_NUM; 206 hw_clks = max77802_hw_clks_info; 207 break; 208 209 case CHIP_MAX77620: 210 num_clks = MAX77620_CLKS_NUM; 211 hw_clks = max77620_hw_clks_info; 212 break; 213 214 default: 215 dev_err(dev, "Unknown Chip ID\n"); 216 return -EINVAL; 217 } 218 219 drv_data->num_clks = num_clks; 220 drv_data->max_clk_data = devm_kcalloc(dev, num_clks, 221 sizeof(*drv_data->max_clk_data), 222 GFP_KERNEL); 223 if (!drv_data->max_clk_data) 224 return -ENOMEM; 225 226 for (i = 0; i < num_clks; i++) { 227 struct max77686_clk_init_data *max_clk_data; 228 const char *clk_name; 229 230 max_clk_data = &drv_data->max_clk_data[i]; 231 232 max_clk_data->regmap = regmap; 233 max_clk_data->clk_info = &hw_clks[i]; 234 max_clk_data->clk_idata.flags = hw_clks[i].flags; 235 max_clk_data->clk_idata.ops = &max77686_clk_ops; 236 237 if (parent->of_node && 238 !of_property_read_string_index(parent->of_node, 239 "clock-output-names", 240 i, &clk_name)) 241 max_clk_data->clk_idata.name = clk_name; 242 else 243 max_clk_data->clk_idata.name = hw_clks[i].name; 244 245 max_clk_data->hw.init = &max_clk_data->clk_idata; 246 247 ret = devm_clk_hw_register(dev, &max_clk_data->hw); 248 if (ret) { 249 dev_err(dev, "Failed to clock register: %d\n", ret); 250 return ret; 251 } 252 253 ret = clk_hw_register_clkdev(&max_clk_data->hw, 254 max_clk_data->clk_idata.name, NULL); 255 if (ret < 0) { 256 dev_err(dev, "Failed to clkdev register: %d\n", ret); 257 return ret; 258 } 259 } 260 261 if (parent->of_node) { 262 ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get, 263 drv_data); 264 265 if (ret < 0) { 266 dev_err(dev, "Failed to register OF clock provider: %d\n", 267 ret); 268 return ret; 269 } 270 } 271 272 /* MAX77802: Enable low-jitter mode on the 32khz clocks. */ 273 if (drv_data->chip == CHIP_MAX77802) { 274 ret = regmap_update_bits(regmap, MAX77802_REG_32KHZ, 275 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT, 276 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT); 277 if (ret < 0) { 278 dev_err(dev, "Failed to config low-jitter: %d\n", ret); 279 goto remove_of_clk_provider; 280 } 281 } 282 283 return 0; 284 285 remove_of_clk_provider: 286 if (parent->of_node) 287 of_clk_del_provider(parent->of_node); 288 289 return ret; 290 } 291 292 static int max77686_clk_remove(struct platform_device *pdev) 293 { 294 struct device *parent = pdev->dev.parent; 295 296 if (parent->of_node) 297 of_clk_del_provider(parent->of_node); 298 299 return 0; 300 } 301 302 static const struct platform_device_id max77686_clk_id[] = { 303 { "max77686-clk", .driver_data = CHIP_MAX77686, }, 304 { "max77802-clk", .driver_data = CHIP_MAX77802, }, 305 { "max77620-clock", .driver_data = CHIP_MAX77620, }, 306 {}, 307 }; 308 MODULE_DEVICE_TABLE(platform, max77686_clk_id); 309 310 static struct platform_driver max77686_clk_driver = { 311 .driver = { 312 .name = "max77686-clk", 313 }, 314 .probe = max77686_clk_probe, 315 .remove = max77686_clk_remove, 316 .id_table = max77686_clk_id, 317 }; 318 319 module_platform_driver(max77686_clk_driver); 320 321 MODULE_DESCRIPTION("MAXIM 77686 Clock Driver"); 322 MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); 323 MODULE_LICENSE("GPL"); 324