Message ID | 1420206085-2913-4-git-send-email-shobhit.kumar@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, 02 Jan 2015, Shobhit Kumar <shobhit.kumar@intel.com> wrote: > This driver provides support for the "crystal_cove_panel" cell device. > On BYT-T pmic has to be used to enable/disable panel. This needs to be sent to dri-devel. With the comments below addressed, and with the disclaimer that I have no idea about the pmic registers or required sleeps, this is Reviewed-by: Jani Nikula <jani.nikula@intel.com> > > Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com> > --- > drivers/gpu/drm/panel/Kconfig | 7 ++ > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-crystalcove.c | 191 ++++++++++++++++++++++++++++++ > 3 files changed, 199 insertions(+) > create mode 100644 drivers/gpu/drm/panel/panel-crystalcove.c > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 024e98e..d813bd1 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -40,4 +40,11 @@ config DRM_PANEL_SHARP_LQ101R1SX01 > To compile this driver as a module, choose M here: the module > will be called panel-sharp-lq101r1sx01. > > +config DRM_PANEL_CRYSTALCOVE > + tristate "Crystalcove PMIC controlled panel" > + depends on INTEL_SOC_PMIC INTEL_SOC_PMIC is still a bool (and requires I2C=y), and IMO should be fixed to support tristate. Or are there fundamental reasons this can't be done? > + help > + Say Y here if you want to enable support for DSI panel and backlight > + control using crystalcove pmic. This is used for BYT CR configurations > + > endmenu > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 4b2a043..c05824e 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o > obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o > obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o > obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o > +obj-$(CONFIG_DRM_PANEL_CRYSTALCOVE) += panel-crystalcove.o > diff --git a/drivers/gpu/drm/panel/panel-crystalcove.c b/drivers/gpu/drm/panel/panel-crystalcove.c > new file mode 100644 > index 0000000..22f7ff5 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-crystalcove.c > @@ -0,0 +1,191 @@ > +/* > + * Copyright © 2006-2014 Intel Corporation 2006?! > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Shobhit Kumar <shobhit.kumar@intel.com> > + */ > + > +#include <drm/drmP.h> > +#include <drm/drm_crtc.h> > +#include <drm/drm_panel.h> > +#include <linux/mfd/intel_soc_pmic.h> > +#include <linux/platform_device.h> > +#include <linux/regmap.h> > + > +#define PMIC_PANEL_EN 0x52 > +#define PMIC_PWM_EN 0x51 > +#define PMIC_BKL_EN 0x4B > +#define PMIC_PWM_LEVEL 0x4E > + > +struct crystalcove_panel { > + struct drm_panel base; > + char name[NAME_MAX]; Unused. > + bool prepared; > + bool enabled; > + > + struct mutex lock; Unused. > + > + /* crystal cove pmic regmap */ > + struct regmap *regmap; > +}; > + > +static inline struct crystalcove_panel *to_crystalcove_panel(struct drm_panel *panel) > +{ > + return container_of(panel, struct crystalcove_panel, base); > +} > + > +static int crystalcove_panel_disable(struct drm_panel *panel) > +{ > + struct crystalcove_panel *p = to_crystalcove_panel(panel); > + > + if (!p->enabled) > + return 0; > + > + DRM_DEBUG_KMS("\n"); > + > + /* invoke the pmic driver */ > + regmap_write(p->regmap, PMIC_PANEL_EN, 0x00); > + > + /* Disable backlight as well */ > + regmap_write(p->regmap, PMIC_PWM_LEVEL, 0); > + msleep(20); Seems like a long delay. > + regmap_write(p->regmap, PMIC_PWM_EN, 0x00); > + regmap_write(p->regmap, PMIC_BKL_EN, 0x7F); > + > + p->enabled = false; > + > + return 0; > +} > + > +static int crystalcove_panel_unprepare(struct drm_panel *panel) > +{ > + struct crystalcove_panel *p = to_crystalcove_panel(panel); > + > + if (!p->prepared) > + return 0; > + > + /* Nothing needed */ > + p->prepared = false; > + > + return 0; > +} > + > +static int crystalcove_panel_prepare(struct drm_panel *panel) > +{ > + struct crystalcove_panel *p = to_crystalcove_panel(panel); > + > + if (p->prepared) > + return 0; > + > + /* Nothing needed */ > + p->prepared = true; > + > + return 0; > +} If you don't need prepare/unprepare, you can just leave them out altogether. It's easy to add them if you need them later. > + > +static int crystalcove_panel_enable(struct drm_panel *panel) > +{ > + struct crystalcove_panel *p = to_crystalcove_panel(panel); > + > + if (p->enabled) > + return 0; > + > + DRM_DEBUG_KMS("\n"); > + > + /* invoke the pmic driver */ > + regmap_write(p->regmap, PMIC_PANEL_EN, 0x01); > + > + /* Enable BKL as well */ > + regmap_write(p->regmap, PMIC_BKL_EN, 0xFF); > + regmap_write(p->regmap, PMIC_PWM_EN, 0x01); > + msleep(20); > + regmap_write(p->regmap, PMIC_PWM_LEVEL, 255); > + > + p->enabled = true; > + > + return 0; > +} > + > +static const struct drm_panel_funcs crystalcove_panel_funcs = { > + .disable = crystalcove_panel_disable, > + .unprepare = crystalcove_panel_unprepare, > + .prepare = crystalcove_panel_prepare, > + .enable = crystalcove_panel_enable, > +}; > + > +static int crystalcove_panel_probe(struct platform_device *pdev) > +{ > + struct crystalcove_panel *panel; > + int retval; > + struct device *dev = pdev->dev.parent; > + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); > + > + panel = devm_kzalloc(&pdev->dev, sizeof(*panel), GFP_KERNEL); > + if (!panel) > + return -ENOMEM; > + > + DRM_DEBUG_KMS("\n"); > + > + platform_set_drvdata(pdev, panel); > + > + strcpy(panel->base.name, "crystal_cove_panel"); > + panel->regmap = pmic->regmap; > + > + regmap_read(panel->regmap, PMIC_PANEL_EN, &retval); > + panel->enabled = panel->prepared = retval ? true : false; For bools you can just assign retval, or if you want to emphasis it's a bool you can use !!retval. > + > + drm_panel_init(&panel->base); > + panel->base.dev = dev; > + panel->base.funcs = &crystalcove_panel_funcs; > + > + drm_panel_add(&panel->base); > + > + return 0; > +} > + > +static int crystalcove_panel_remove(struct platform_device *pdev) > +{ > + struct crystalcove_panel *panel = platform_get_drvdata(pdev); > + > + DRM_DEBUG_KMS("\n"); > + > + drm_panel_detach(&panel->base); > + drm_panel_remove(&panel->base); > + > + crystalcove_panel_disable(&panel->base); > + > + return 0; > +} > + > +static struct platform_driver crystalcove_panel_driver = { > + .probe = crystalcove_panel_probe, > + .remove = crystalcove_panel_remove, > + .driver = { > + .name = "crystal_cove_panel", > + }, > +}; > + > +module_platform_driver(crystalcove_panel_driver); > + > +MODULE_AUTHOR("Shobhit Kumar <shobhit.kumar@linux.intel.com"); > +MODULE_DESCRIPTION("Intel Crystal Cove Panel Driver"); > +MODULE_LICENSE("GPL v2"); This conflicts with the copyright header of the file. > -- > 1.9.1 >
On 1/9/2015 6:38 PM, Jani Nikula wrote: > On Fri, 02 Jan 2015, Shobhit Kumar <shobhit.kumar@intel.com> wrote: >> This driver provides support for the "crystal_cove_panel" cell device. >> On BYT-T pmic has to be used to enable/disable panel. > > This needs to be sent to dri-devel. Will do for the updated patch after addressing all your comments. > > With the comments below addressed, and with the disclaimer that I have > no idea about the pmic registers or required sleeps, this is > > Reviewed-by: Jani Nikula <jani.nikula@intel.com> > >> >> Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com> >> --- >> drivers/gpu/drm/panel/Kconfig | 7 ++ >> drivers/gpu/drm/panel/Makefile | 1 + >> drivers/gpu/drm/panel/panel-crystalcove.c | 191 ++++++++++++++++++++++++++++++ >> 3 files changed, 199 insertions(+) >> create mode 100644 drivers/gpu/drm/panel/panel-crystalcove.c >> >> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig >> index 024e98e..d813bd1 100644 >> --- a/drivers/gpu/drm/panel/Kconfig >> +++ b/drivers/gpu/drm/panel/Kconfig >> @@ -40,4 +40,11 @@ config DRM_PANEL_SHARP_LQ101R1SX01 >> To compile this driver as a module, choose M here: the module >> will be called panel-sharp-lq101r1sx01. >> >> +config DRM_PANEL_CRYSTALCOVE >> + tristate "Crystalcove PMIC controlled panel" >> + depends on INTEL_SOC_PMIC > > INTEL_SOC_PMIC is still a bool (and requires I2C=y), and IMO should be > fixed to support tristate. Or are there fundamental reasons this can't > be done? Jacob, can you answer this one for the PMIC driver. This has come up multiple times earlier also in some discussions. > >> + help >> + Say Y here if you want to enable support for DSI panel and backlight >> + control using crystalcove pmic. This is used for BYT CR configurations >> + >> endmenu >> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile >> index 4b2a043..c05824e 100644 >> --- a/drivers/gpu/drm/panel/Makefile >> +++ b/drivers/gpu/drm/panel/Makefile >> @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o >> obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o >> obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o >> obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o >> +obj-$(CONFIG_DRM_PANEL_CRYSTALCOVE) += panel-crystalcove.o >> diff --git a/drivers/gpu/drm/panel/panel-crystalcove.c b/drivers/gpu/drm/panel/panel-crystalcove.c >> new file mode 100644 >> index 0000000..22f7ff5 >> --- /dev/null >> +++ b/drivers/gpu/drm/panel/panel-crystalcove.c >> @@ -0,0 +1,191 @@ >> +/* >> + * Copyright © 2006-2014 Intel Corporation > > 2006?! > >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining a >> + * copy of this software and associated documentation files (the "Software"), >> + * to deal in the Software without restriction, including without limitation >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense, >> + * and/or sell copies of the Software, and to permit persons to whom the >> + * Software is furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice (including the next >> + * paragraph) shall be included in all copies or substantial portions of the >> + * Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING >> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >> + * DEALINGS IN THE SOFTWARE. >> + * >> + * Authors: >> + * Shobhit Kumar <shobhit.kumar@intel.com> >> + */ >> + >> +#include <drm/drmP.h> >> +#include <drm/drm_crtc.h> >> +#include <drm/drm_panel.h> >> +#include <linux/mfd/intel_soc_pmic.h> >> +#include <linux/platform_device.h> >> +#include <linux/regmap.h> >> + >> +#define PMIC_PANEL_EN 0x52 >> +#define PMIC_PWM_EN 0x51 >> +#define PMIC_BKL_EN 0x4B >> +#define PMIC_PWM_LEVEL 0x4E >> + >> +struct crystalcove_panel { >> + struct drm_panel base; >> + char name[NAME_MAX]; > > Unused. > >> + bool prepared; >> + bool enabled; >> + >> + struct mutex lock; > > Unused. > >> + >> + /* crystal cove pmic regmap */ >> + struct regmap *regmap; >> +}; >> + >> +static inline struct crystalcove_panel *to_crystalcove_panel(struct drm_panel *panel) >> +{ >> + return container_of(panel, struct crystalcove_panel, base); >> +} >> + >> +static int crystalcove_panel_disable(struct drm_panel *panel) >> +{ >> + struct crystalcove_panel *p = to_crystalcove_panel(panel); >> + >> + if (!p->enabled) >> + return 0; >> + >> + DRM_DEBUG_KMS("\n"); >> + >> + /* invoke the pmic driver */ >> + regmap_write(p->regmap, PMIC_PANEL_EN, 0x00); >> + >> + /* Disable backlight as well */ >> + regmap_write(p->regmap, PMIC_PWM_LEVEL, 0); >> + msleep(20); > > Seems like a long delay. > >> + regmap_write(p->regmap, PMIC_PWM_EN, 0x00); >> + regmap_write(p->regmap, PMIC_BKL_EN, 0x7F); >> + >> + p->enabled = false; >> + >> + return 0; >> +} >> + >> +static int crystalcove_panel_unprepare(struct drm_panel *panel) >> +{ >> + struct crystalcove_panel *p = to_crystalcove_panel(panel); >> + >> + if (!p->prepared) >> + return 0; >> + >> + /* Nothing needed */ >> + p->prepared = false; >> + >> + return 0; >> +} >> + >> +static int crystalcove_panel_prepare(struct drm_panel *panel) >> +{ >> + struct crystalcove_panel *p = to_crystalcove_panel(panel); >> + >> + if (p->prepared) >> + return 0; >> + >> + /* Nothing needed */ >> + p->prepared = true; >> + >> + return 0; >> +} > > If you don't need prepare/unprepare, you can just leave them out > altogether. It's easy to add them if you need them later. > >> + >> +static int crystalcove_panel_enable(struct drm_panel *panel) >> +{ >> + struct crystalcove_panel *p = to_crystalcove_panel(panel); >> + >> + if (p->enabled) >> + return 0; >> + >> + DRM_DEBUG_KMS("\n"); >> + >> + /* invoke the pmic driver */ >> + regmap_write(p->regmap, PMIC_PANEL_EN, 0x01); >> + >> + /* Enable BKL as well */ >> + regmap_write(p->regmap, PMIC_BKL_EN, 0xFF); >> + regmap_write(p->regmap, PMIC_PWM_EN, 0x01); >> + msleep(20); >> + regmap_write(p->regmap, PMIC_PWM_LEVEL, 255); >> + >> + p->enabled = true; >> + >> + return 0; >> +} >> + >> +static const struct drm_panel_funcs crystalcove_panel_funcs = { >> + .disable = crystalcove_panel_disable, >> + .unprepare = crystalcove_panel_unprepare, >> + .prepare = crystalcove_panel_prepare, >> + .enable = crystalcove_panel_enable, >> +}; >> + >> +static int crystalcove_panel_probe(struct platform_device *pdev) >> +{ >> + struct crystalcove_panel *panel; >> + int retval; >> + struct device *dev = pdev->dev.parent; >> + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); >> + >> + panel = devm_kzalloc(&pdev->dev, sizeof(*panel), GFP_KERNEL); >> + if (!panel) >> + return -ENOMEM; >> + >> + DRM_DEBUG_KMS("\n"); >> + >> + platform_set_drvdata(pdev, panel); >> + >> + strcpy(panel->base.name, "crystal_cove_panel"); >> + panel->regmap = pmic->regmap; >> + >> + regmap_read(panel->regmap, PMIC_PANEL_EN, &retval); >> + panel->enabled = panel->prepared = retval ? true : false; > > For bools you can just assign retval, or if you want to emphasis it's a > bool you can use !!retval. > >> + >> + drm_panel_init(&panel->base); >> + panel->base.dev = dev; >> + panel->base.funcs = &crystalcove_panel_funcs; >> + >> + drm_panel_add(&panel->base); >> + >> + return 0; >> +} >> + >> +static int crystalcove_panel_remove(struct platform_device *pdev) >> +{ >> + struct crystalcove_panel *panel = platform_get_drvdata(pdev); >> + >> + DRM_DEBUG_KMS("\n"); >> + >> + drm_panel_detach(&panel->base); >> + drm_panel_remove(&panel->base); >> + >> + crystalcove_panel_disable(&panel->base); >> + >> + return 0; >> +} >> + >> +static struct platform_driver crystalcove_panel_driver = { >> + .probe = crystalcove_panel_probe, >> + .remove = crystalcove_panel_remove, >> + .driver = { >> + .name = "crystal_cove_panel", >> + }, >> +}; >> + >> +module_platform_driver(crystalcove_panel_driver); >> + >> +MODULE_AUTHOR("Shobhit Kumar <shobhit.kumar@linux.intel.com"); >> +MODULE_DESCRIPTION("Intel Crystal Cove Panel Driver"); >> +MODULE_LICENSE("GPL v2"); > > This conflicts with the copyright header of the file. > > >> -- >> 1.9.1 >> >
On 1/12/2015 1:56 PM, Kumar, Shobhit wrote: > On 1/9/2015 6:38 PM, Jani Nikula wrote: >> On Fri, 02 Jan 2015, Shobhit Kumar <shobhit.kumar@intel.com> wrote: >>> This driver provides support for the "crystal_cove_panel" cell device. >>> On BYT-T pmic has to be used to enable/disable panel. >> >> This needs to be sent to dri-devel. > > Will do for the updated patch after addressing all your comments. Also do we really need to make it as part of drm. How about keeping this internal to i915 as most likely no one else other than i915 will use it ? > >> >> With the comments below addressed, and with the disclaimer that I have >> no idea about the pmic registers or required sleeps, this is >> >> Reviewed-by: Jani Nikula <jani.nikula@intel.com> >> >>> >>> Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com> >>> --- >>> +module_platform_driver(crystalcove_panel_driver); >>> + >>> +MODULE_AUTHOR("Shobhit Kumar <shobhit.kumar@linux.intel.com"); >>> +MODULE_DESCRIPTION("Intel Crystal Cove Panel Driver"); >>> +MODULE_LICENSE("GPL v2"); >> >> This conflicts with the copyright header of the file. I have seen drivers in kernel header both with Copyright and GPL V2. Example - "drivers/gpu/drm/panel/panel-s6e8aa0.c" I can change to MODULE_LICENSE("GPL and additional rights"); Regards Shobhit
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 024e98e..d813bd1 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -40,4 +40,11 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_CRYSTALCOVE + tristate "Crystalcove PMIC controlled panel" + depends on INTEL_SOC_PMIC + help + Say Y here if you want to enable support for DSI panel and backlight + control using crystalcove pmic. This is used for BYT CR configurations + endmenu diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 4b2a043..c05824e 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o +obj-$(CONFIG_DRM_PANEL_CRYSTALCOVE) += panel-crystalcove.o diff --git a/drivers/gpu/drm/panel/panel-crystalcove.c b/drivers/gpu/drm/panel/panel-crystalcove.c new file mode 100644 index 0000000..22f7ff5 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-crystalcove.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2006-2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Shobhit Kumar <shobhit.kumar@intel.com> + */ + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_panel.h> +#include <linux/mfd/intel_soc_pmic.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define PMIC_PANEL_EN 0x52 +#define PMIC_PWM_EN 0x51 +#define PMIC_BKL_EN 0x4B +#define PMIC_PWM_LEVEL 0x4E + +struct crystalcove_panel { + struct drm_panel base; + char name[NAME_MAX]; + bool prepared; + bool enabled; + + struct mutex lock; + + /* crystal cove pmic regmap */ + struct regmap *regmap; +}; + +static inline struct crystalcove_panel *to_crystalcove_panel(struct drm_panel *panel) +{ + return container_of(panel, struct crystalcove_panel, base); +} + +static int crystalcove_panel_disable(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (!p->enabled) + return 0; + + DRM_DEBUG_KMS("\n"); + + /* invoke the pmic driver */ + regmap_write(p->regmap, PMIC_PANEL_EN, 0x00); + + /* Disable backlight as well */ + regmap_write(p->regmap, PMIC_PWM_LEVEL, 0); + msleep(20); + regmap_write(p->regmap, PMIC_PWM_EN, 0x00); + regmap_write(p->regmap, PMIC_BKL_EN, 0x7F); + + p->enabled = false; + + return 0; +} + +static int crystalcove_panel_unprepare(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (!p->prepared) + return 0; + + /* Nothing needed */ + p->prepared = false; + + return 0; +} + +static int crystalcove_panel_prepare(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (p->prepared) + return 0; + + /* Nothing needed */ + p->prepared = true; + + return 0; +} + +static int crystalcove_panel_enable(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (p->enabled) + return 0; + + DRM_DEBUG_KMS("\n"); + + /* invoke the pmic driver */ + regmap_write(p->regmap, PMIC_PANEL_EN, 0x01); + + /* Enable BKL as well */ + regmap_write(p->regmap, PMIC_BKL_EN, 0xFF); + regmap_write(p->regmap, PMIC_PWM_EN, 0x01); + msleep(20); + regmap_write(p->regmap, PMIC_PWM_LEVEL, 255); + + p->enabled = true; + + return 0; +} + +static const struct drm_panel_funcs crystalcove_panel_funcs = { + .disable = crystalcove_panel_disable, + .unprepare = crystalcove_panel_unprepare, + .prepare = crystalcove_panel_prepare, + .enable = crystalcove_panel_enable, +}; + +static int crystalcove_panel_probe(struct platform_device *pdev) +{ + struct crystalcove_panel *panel; + int retval; + struct device *dev = pdev->dev.parent; + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + panel = devm_kzalloc(&pdev->dev, sizeof(*panel), GFP_KERNEL); + if (!panel) + return -ENOMEM; + + DRM_DEBUG_KMS("\n"); + + platform_set_drvdata(pdev, panel); + + strcpy(panel->base.name, "crystal_cove_panel"); + panel->regmap = pmic->regmap; + + regmap_read(panel->regmap, PMIC_PANEL_EN, &retval); + panel->enabled = panel->prepared = retval ? true : false; + + drm_panel_init(&panel->base); + panel->base.dev = dev; + panel->base.funcs = &crystalcove_panel_funcs; + + drm_panel_add(&panel->base); + + return 0; +} + +static int crystalcove_panel_remove(struct platform_device *pdev) +{ + struct crystalcove_panel *panel = platform_get_drvdata(pdev); + + DRM_DEBUG_KMS("\n"); + + drm_panel_detach(&panel->base); + drm_panel_remove(&panel->base); + + crystalcove_panel_disable(&panel->base); + + return 0; +} + +static struct platform_driver crystalcove_panel_driver = { + .probe = crystalcove_panel_probe, + .remove = crystalcove_panel_remove, + .driver = { + .name = "crystal_cove_panel", + }, +}; + +module_platform_driver(crystalcove_panel_driver); + +MODULE_AUTHOR("Shobhit Kumar <shobhit.kumar@linux.intel.com"); +MODULE_DESCRIPTION("Intel Crystal Cove Panel Driver"); +MODULE_LICENSE("GPL v2");
This driver provides support for the "crystal_cove_panel" cell device. On BYT-T pmic has to be used to enable/disable panel. Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com> --- drivers/gpu/drm/panel/Kconfig | 7 ++ drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-crystalcove.c | 191 ++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-crystalcove.c