diff options
author | Lee Jones <lee.jones@linaro.org> | 2013-04-02 08:24:14 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-03 13:40:25 -0400 |
commit | 33aeb49e247ff6b0d51301b92681a304f097c263 (patch) | |
tree | cd1126b755059edf28f7329a12c7238fbc0d590e /drivers/regulator/ab8500.c | |
parent | 37daa8aed1af2e09abfdb66e8da9074eb9b9e1a1 (diff) |
regulator: ab8500: Use a struct to select the good regulator configuration
At the probe use a structure to select the good regulator array from
from ab9540, ab8505, ab8540 or ab8500 configuration.
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/ab8500.c')
-rw-r--r-- | drivers/regulator/ab8500.c | 135 |
1 files changed, 64 insertions, 71 deletions
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index ef12d3d79bdf..9cb634807ff8 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -2860,10 +2860,19 @@ static struct ab8500_reg_init ab8540_reg_init[] = { | |||
2860 | REG_INIT(AB8540_REGUCTRLDISCH4, 0x04, 0x49, 0x07), | 2860 | REG_INIT(AB8540_REGUCTRLDISCH4, 0x04, 0x49, 0x07), |
2861 | }; | 2861 | }; |
2862 | 2862 | ||
2863 | static struct { | ||
2864 | struct ab8500_regulator_info *info; | ||
2865 | int info_size; | ||
2866 | struct ab8500_reg_init *init; | ||
2867 | int init_size; | ||
2868 | struct of_regulator_match *match; | ||
2869 | int match_size; | ||
2870 | } abx500_regulator; | ||
2871 | |||
2863 | static int ab8500_regulator_init_registers(struct platform_device *pdev, | 2872 | static int ab8500_regulator_init_registers(struct platform_device *pdev, |
2864 | struct ab8500_reg_init *reg_init, | ||
2865 | int id, int mask, int value) | 2873 | int id, int mask, int value) |
2866 | { | 2874 | { |
2875 | struct ab8500_reg_init *reg_init = abx500_regulator.init; | ||
2867 | int err; | 2876 | int err; |
2868 | 2877 | ||
2869 | BUG_ON(value & ~mask); | 2878 | BUG_ON(value & ~mask); |
@@ -2893,7 +2902,6 @@ static int ab8500_regulator_init_registers(struct platform_device *pdev, | |||
2893 | 2902 | ||
2894 | static int ab8500_regulator_register(struct platform_device *pdev, | 2903 | static int ab8500_regulator_register(struct platform_device *pdev, |
2895 | struct regulator_init_data *init_data, | 2904 | struct regulator_init_data *init_data, |
2896 | struct ab8500_regulator_info *regulator_info, | ||
2897 | int id, struct device_node *np) | 2905 | int id, struct device_node *np) |
2898 | { | 2906 | { |
2899 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 2907 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
@@ -2902,7 +2910,7 @@ static int ab8500_regulator_register(struct platform_device *pdev, | |||
2902 | int err; | 2910 | int err; |
2903 | 2911 | ||
2904 | /* assign per-regulator data */ | 2912 | /* assign per-regulator data */ |
2905 | info = ®ulator_info[id]; | 2913 | info = &abx500_regulator.info[id]; |
2906 | info->dev = &pdev->dev; | 2914 | info->dev = &pdev->dev; |
2907 | 2915 | ||
2908 | config.dev = &pdev->dev; | 2916 | config.dev = &pdev->dev; |
@@ -2928,7 +2936,7 @@ static int ab8500_regulator_register(struct platform_device *pdev, | |||
2928 | info->desc.name); | 2936 | info->desc.name); |
2929 | /* when we fail, un-register all earlier regulators */ | 2937 | /* when we fail, un-register all earlier regulators */ |
2930 | while (--id >= 0) { | 2938 | while (--id >= 0) { |
2931 | info = ®ulator_info[id]; | 2939 | info = &abx500_regulator.info[id]; |
2932 | regulator_unregister(info->regulator); | 2940 | regulator_unregister(info->regulator); |
2933 | } | 2941 | } |
2934 | return err; | 2942 | return err; |
@@ -2995,19 +3003,49 @@ static struct of_regulator_match ab9540_regulator_match[] = { | |||
2995 | { .name = "ab8500_ldo_ana", .driver_data = (void *) AB9540_LDO_ANA, }, | 3003 | { .name = "ab8500_ldo_ana", .driver_data = (void *) AB9540_LDO_ANA, }, |
2996 | }; | 3004 | }; |
2997 | 3005 | ||
3006 | static void abx500_get_regulator_info(struct ab8500 *ab8500) | ||
3007 | { | ||
3008 | if (is_ab9540(ab8500)) { | ||
3009 | abx500_regulator.info = ab9540_regulator_info; | ||
3010 | abx500_regulator.info_size = ARRAY_SIZE(ab9540_regulator_info); | ||
3011 | abx500_regulator.init = ab9540_reg_init; | ||
3012 | abx500_regulator.init_size = AB9540_NUM_REGULATOR_REGISTERS; | ||
3013 | abx500_regulator.match = ab9540_regulator_match; | ||
3014 | abx500_regulator.match_size = ARRAY_SIZE(ab9540_regulator_match); | ||
3015 | } else if (is_ab8505(ab8500)) { | ||
3016 | abx500_regulator.info = ab8505_regulator_info; | ||
3017 | abx500_regulator.info_size = ARRAY_SIZE(ab8505_regulator_info); | ||
3018 | abx500_regulator.init = ab8505_reg_init; | ||
3019 | abx500_regulator.init_size = AB8505_NUM_REGULATOR_REGISTERS; | ||
3020 | abx500_regulator.match = ab8505_regulator_match; | ||
3021 | abx500_regulator.match_size = ARRAY_SIZE(ab8505_regulator_match); | ||
3022 | } else if (is_ab8540(ab8500)) { | ||
3023 | abx500_regulator.info = ab8540_regulator_info; | ||
3024 | abx500_regulator.info_size = ARRAY_SIZE(ab8540_regulator_info); | ||
3025 | abx500_regulator.init = ab8540_reg_init; | ||
3026 | abx500_regulator.init_size = AB8540_NUM_REGULATOR_REGISTERS; | ||
3027 | abx500_regulator.match = ab8540_regulator_match; | ||
3028 | abx500_regulator.match_size = ARRAY_SIZE(ab8540_regulator_match); | ||
3029 | } else { | ||
3030 | abx500_regulator.info = ab8500_regulator_info; | ||
3031 | abx500_regulator.info_size = ARRAY_SIZE(ab8500_regulator_info); | ||
3032 | abx500_regulator.init = ab8500_reg_init; | ||
3033 | abx500_regulator.init_size = AB8500_NUM_REGULATOR_REGISTERS; | ||
3034 | abx500_regulator.match = ab8500_regulator_match; | ||
3035 | abx500_regulator.match_size = ARRAY_SIZE(ab8500_regulator_match); | ||
3036 | } | ||
3037 | } | ||
3038 | |||
2998 | static int | 3039 | static int |
2999 | ab8500_regulator_of_probe(struct platform_device *pdev, | 3040 | ab8500_regulator_of_probe(struct platform_device *pdev, |
3000 | struct ab8500_regulator_info *regulator_info, | ||
3001 | int regulator_info_size, | ||
3002 | struct of_regulator_match *match, | ||
3003 | struct device_node *np) | 3041 | struct device_node *np) |
3004 | { | 3042 | { |
3043 | struct of_regulator_match *match = abx500_regulator.match; | ||
3005 | int err, i; | 3044 | int err, i; |
3006 | 3045 | ||
3007 | for (i = 0; i < regulator_info_size; i++) { | 3046 | for (i = 0; i < abx500_regulator.info_size; i++) { |
3008 | err = ab8500_regulator_register( | 3047 | err = ab8500_regulator_register( |
3009 | pdev, match[i].init_data, regulator_info, | 3048 | pdev, match[i].init_data, i, match[i].of_node); |
3010 | i, match[i].of_node); | ||
3011 | if (err) | 3049 | if (err) |
3012 | return err; | 3050 | return err; |
3013 | } | 3051 | } |
@@ -3019,59 +3057,31 @@ static int ab8500_regulator_probe(struct platform_device *pdev) | |||
3019 | { | 3057 | { |
3020 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 3058 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
3021 | struct device_node *np = pdev->dev.of_node; | 3059 | struct device_node *np = pdev->dev.of_node; |
3022 | struct of_regulator_match *match; | ||
3023 | struct ab8500_platform_data *ppdata; | 3060 | struct ab8500_platform_data *ppdata; |
3024 | struct ab8500_regulator_platform_data *pdata; | 3061 | struct ab8500_regulator_platform_data *pdata; |
3025 | int i, err; | 3062 | int i, err; |
3026 | struct ab8500_regulator_info *regulator_info; | ||
3027 | int regulator_info_size; | ||
3028 | struct ab8500_reg_init *reg_init; | ||
3029 | int reg_init_size; | ||
3030 | 3063 | ||
3031 | if (is_ab9540(ab8500)) { | 3064 | if (!ab8500) { |
3032 | regulator_info = ab9540_regulator_info; | 3065 | dev_err(&pdev->dev, "null mfd parent\n"); |
3033 | regulator_info_size = ARRAY_SIZE(ab9540_regulator_info); | 3066 | return -EINVAL; |
3034 | reg_init = ab9540_reg_init; | ||
3035 | reg_init_size = AB9540_NUM_REGULATOR_REGISTERS; | ||
3036 | match = ab9540_regulator_match; | ||
3037 | match_size = ARRAY_SIZE(ab9540_regulator_match) | ||
3038 | } else if (is_ab8505(ab8500)) { | ||
3039 | regulator_info = ab8505_regulator_info; | ||
3040 | regulator_info_size = ARRAY_SIZE(ab8505_regulator_info); | ||
3041 | reg_init = ab8505_reg_init; | ||
3042 | reg_init_size = AB8505_NUM_REGULATOR_REGISTERS; | ||
3043 | } else if (is_ab8540(ab8500)) { | ||
3044 | regulator_info = ab8540_regulator_info; | ||
3045 | regulator_info_size = ARRAY_SIZE(ab8540_regulator_info); | ||
3046 | reg_init = ab8540_reg_init; | ||
3047 | reg_init_size = AB8540_NUM_REGULATOR_REGISTERS; | ||
3048 | } else { | ||
3049 | regulator_info = ab8500_regulator_info; | ||
3050 | regulator_info_size = ARRAY_SIZE(ab8500_regulator_info); | ||
3051 | reg_init = ab8500_reg_init; | ||
3052 | reg_init_size = AB8500_NUM_REGULATOR_REGISTERS; | ||
3053 | match = ab8500_regulator_match; | ||
3054 | match_size = ARRAY_SIZE(ab8500_regulator_match) | ||
3055 | } | 3067 | } |
3056 | 3068 | ||
3069 | abx500_get_regulator_info(ab8500); | ||
3070 | |||
3057 | if (np) { | 3071 | if (np) { |
3058 | err = of_regulator_match(&pdev->dev, np, match, match_size); | 3072 | err = of_regulator_match(&pdev->dev, np, |
3073 | abx500_regulator.match, | ||
3074 | abx500_regulator.match_size); | ||
3059 | if (err < 0) { | 3075 | if (err < 0) { |
3060 | dev_err(&pdev->dev, | 3076 | dev_err(&pdev->dev, |
3061 | "Error parsing regulator init data: %d\n", err); | 3077 | "Error parsing regulator init data: %d\n", err); |
3062 | return err; | 3078 | return err; |
3063 | } | 3079 | } |
3064 | 3080 | ||
3065 | err = ab8500_regulator_of_probe(pdev, regulator_info, | 3081 | err = ab8500_regulator_of_probe(pdev, np); |
3066 | regulator_info_size, match, np); | ||
3067 | return err; | 3082 | return err; |
3068 | } | 3083 | } |
3069 | 3084 | ||
3070 | if (!ab8500) { | ||
3071 | dev_err(&pdev->dev, "null mfd parent\n"); | ||
3072 | return -EINVAL; | ||
3073 | } | ||
3074 | |||
3075 | ppdata = dev_get_platdata(ab8500->dev); | 3085 | ppdata = dev_get_platdata(ab8500->dev); |
3076 | if (!ppdata) { | 3086 | if (!ppdata) { |
3077 | dev_err(&pdev->dev, "null parent pdata\n"); | 3087 | dev_err(&pdev->dev, "null parent pdata\n"); |
@@ -3085,7 +3095,7 @@ static int ab8500_regulator_probe(struct platform_device *pdev) | |||
3085 | } | 3095 | } |
3086 | 3096 | ||
3087 | /* make sure the platform data has the correct size */ | 3097 | /* make sure the platform data has the correct size */ |
3088 | if (pdata->num_regulator != regulator_info_size) { | 3098 | if (pdata->num_regulator != abx500_regulator.info_size) { |
3089 | dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); | 3099 | dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); |
3090 | return -EINVAL; | 3100 | return -EINVAL; |
3091 | } | 3101 | } |
@@ -3104,9 +3114,9 @@ static int ab8500_regulator_probe(struct platform_device *pdev) | |||
3104 | value = pdata->reg_init[i].value; | 3114 | value = pdata->reg_init[i].value; |
3105 | 3115 | ||
3106 | /* check for configuration errors */ | 3116 | /* check for configuration errors */ |
3107 | BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS); | 3117 | BUG_ON(id >= abx500_regulator.init_size); |
3108 | 3118 | ||
3109 | err = ab8500_regulator_init_registers(pdev, reg_init, id, mask, value); | 3119 | err = ab8500_regulator_init_registers(pdev, id, mask, value); |
3110 | if (err < 0) | 3120 | if (err < 0) |
3111 | return err; | 3121 | return err; |
3112 | } | 3122 | } |
@@ -3119,9 +3129,9 @@ static int ab8500_regulator_probe(struct platform_device *pdev) | |||
3119 | } | 3129 | } |
3120 | 3130 | ||
3121 | /* register all regulators */ | 3131 | /* register all regulators */ |
3122 | for (i = 0; i < regulator_info_size; i++) { | 3132 | for (i = 0; i < abx500_regulator.info_size; i++) { |
3123 | err = ab8500_regulator_register(pdev, &pdata->regulator[i], | 3133 | err = ab8500_regulator_register(pdev, &pdata->regulator[i], |
3124 | regulator_info, i, NULL); | 3134 | i, NULL); |
3125 | if (err < 0) | 3135 | if (err < 0) |
3126 | return err; | 3136 | return err; |
3127 | } | 3137 | } |
@@ -3133,27 +3143,10 @@ static int ab8500_regulator_remove(struct platform_device *pdev) | |||
3133 | { | 3143 | { |
3134 | int i, err; | 3144 | int i, err; |
3135 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 3145 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
3136 | struct ab8500_regulator_info *regulator_info; | ||
3137 | int regulator_info_size; | ||
3138 | |||
3139 | |||
3140 | if (is_ab9540(ab8500)) { | ||
3141 | regulator_info = ab9540_regulator_info; | ||
3142 | regulator_info_size = ARRAY_SIZE(ab9540_regulator_info); | ||
3143 | } else if (is_ab8505(ab8500)) { | ||
3144 | regulator_info = ab8505_regulator_info; | ||
3145 | regulator_info_size = ARRAY_SIZE(ab8505_regulator_info); | ||
3146 | } else if (is_ab8540(ab8500)) { | ||
3147 | regulator_info = ab8540_regulator_info; | ||
3148 | regulator_info_size = ARRAY_SIZE(ab8540_regulator_info); | ||
3149 | } else { | ||
3150 | regulator_info = ab8500_regulator_info; | ||
3151 | regulator_info_size = ARRAY_SIZE(ab8500_regulator_info); | ||
3152 | } | ||
3153 | 3146 | ||
3154 | for (i = 0; i < regulator_info_size; i++) { | 3147 | for (i = 0; i < abx500_regulator.info_size; i++) { |
3155 | struct ab8500_regulator_info *info = NULL; | 3148 | struct ab8500_regulator_info *info = NULL; |
3156 | info = ®ulator_info[i]; | 3149 | info = &abx500_regulator.info[i]; |
3157 | 3150 | ||
3158 | dev_vdbg(rdev_get_dev(info->regulator), | 3151 | dev_vdbg(rdev_get_dev(info->regulator), |
3159 | "%s-remove\n", info->desc.name); | 3152 | "%s-remove\n", info->desc.name); |