u32 als_vmin, als_vmax, als_vstep;
        struct lm3530_platform_data *pltfm = drvdata->pdata;
        struct i2c_client *client = drvdata->client;
+       struct lm3530_pwm_data *pwm = &pltfm->pwm_data;
 
        gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
                        ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
        }
 
        for (i = 0; i < LM3530_REG_MAX; i++) {
+               /* do not update brightness register when pwm mode */
+               if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
+                   drvdata->mode == LM3530_BL_MODE_PWM) {
+                       if (pwm->pwm_set_intensity)
+                               pwm->pwm_set_intensity(reg_val[i],
+                                       drvdata->led_dev.max_brightness);
+                       continue;
+               }
+
                ret = i2c_smbus_write_byte_data(client,
                                lm3530_reg[i], reg_val[i]);
                if (ret)
        int err;
        struct lm3530_data *drvdata =
            container_of(led_cdev, struct lm3530_data, led_dev);
+       struct lm3530_platform_data *pdata = drvdata->pdata;
+       struct lm3530_pwm_data *pwm = &pdata->pwm_data;
+       u8 max_brightness = led_cdev->max_brightness;
 
        switch (drvdata->mode) {
        case LM3530_BL_MODE_MANUAL:
        case LM3530_BL_MODE_ALS:
                break;
        case LM3530_BL_MODE_PWM:
+               if (pwm->pwm_set_intensity)
+                       pwm->pwm_set_intensity(brt_val, max_brightness);
                break;
        default:
                break;
 {
        struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct lm3530_data *drvdata;
+       struct lm3530_pwm_data *pwm;
+       u8 max_brightness;
        int mode, err;
 
        drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
+       pwm = &drvdata->pdata->pwm_data;
+       max_brightness = led_cdev->max_brightness;
        mode = lm3530_get_mode_from_str(buf);
        if (mode < 0) {
                dev_err(dev, "Invalid mode\n");
                return -EINVAL;
        }
 
-       if (mode == LM3530_BL_MODE_MANUAL)
-               drvdata->mode = LM3530_BL_MODE_MANUAL;
-       else if (mode == LM3530_BL_MODE_ALS)
-               drvdata->mode = LM3530_BL_MODE_ALS;
-       else if (mode == LM3530_BL_MODE_PWM) {
-               dev_err(dev, "PWM mode not supported\n");
-               return -EINVAL;
-       }
+       drvdata->mode = mode;
+
+       /* set pwm to low if unnecessary */
+       if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
+               pwm->pwm_set_intensity(0, max_brightness);
 
        err = lm3530_init_registers(drvdata);
        if (err) {
 
        LM3530_INPUT_CEIL,      /* Max of ALS1 and ALS2 */
 };
 
+/* PWM Platform Specific Data */
+struct lm3530_pwm_data {
+       void (*pwm_set_intensity) (int brightness, int max_brightness);
+       int (*pwm_get_intensity) (int max_brightness);
+};
+
 /**
  * struct lm3530_platform_data
  * @mode: mode of operation i.e. Manual, ALS or PWM
  * @als_vmin: als input voltage calibrated for max brightness in mV
  * @als_vmax: als input voltage calibrated for min brightness in mV
  * @brt_val: brightness value (0-255)
+ * @pwm_data: PWM control functions (only valid when the mode is PWM)
  */
 struct lm3530_platform_data {
        enum lm3530_mode mode;
        u32 als_vmax;
 
        u8 brt_val;
+
+       struct lm3530_pwm_data pwm_data;
 };
 
 #endif /* _LINUX_LED_LM3530_H__ */