Lines Matching defs:ssd130x
37 #include "ssd130x.h"
39 #define DRIVER_NAME "ssd130x"
165 static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count)
167 return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count);
174 * Note that the ssd130x protocol requires each command and option to be
178 static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
189 ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value);
201 static int ssd130x_set_col_range(struct ssd130x_device *ssd130x,
207 if (col_start == ssd130x->col_start && col_end == ssd130x->col_end)
210 ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, col_end);
214 ssd130x->col_start = col_start;
215 ssd130x->col_end = col_end;
219 static int ssd130x_set_page_range(struct ssd130x_device *ssd130x,
225 if (page_start == ssd130x->page_start && page_end == ssd130x->page_end)
228 ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start, page_end);
232 ssd130x->page_start = page_start;
233 ssd130x->page_end = page_end;
238 static int ssd130x_set_page_pos(struct ssd130x_device *ssd130x,
250 ret = ssd130x_write_cmd(ssd130x, 3, page, col_low, col_high);
257 static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x)
259 struct device *dev = ssd130x->dev;
262 ssd130x->pwm = pwm_get(dev, NULL);
263 if (IS_ERR(ssd130x->pwm)) {
265 return PTR_ERR(ssd130x->pwm);
268 pwm_init_state(ssd130x->pwm, &pwmstate);
270 pwm_apply_state(ssd130x->pwm, &pwmstate);
273 pwm_enable(ssd130x->pwm);
276 ssd130x->pwm->pwm, pwm_get_period(ssd130x->pwm));
281 static void ssd130x_reset(struct ssd130x_device *ssd130x)
283 if (!ssd130x->reset)
287 gpiod_set_value_cansleep(ssd130x->reset, 1);
289 gpiod_set_value_cansleep(ssd130x->reset, 0);
293 static int ssd130x_power_on(struct ssd130x_device *ssd130x)
295 struct device *dev = ssd130x->dev;
298 ssd130x_reset(ssd130x);
300 ret = regulator_enable(ssd130x->vcc_reg);
306 if (ssd130x->device_info->need_pwm) {
307 ret = ssd130x_pwm_enable(ssd130x);
310 regulator_disable(ssd130x->vcc_reg);
318 static void ssd130x_power_off(struct ssd130x_device *ssd130x)
320 pwm_disable(ssd130x->pwm);
321 pwm_put(ssd130x->pwm);
323 regulator_disable(ssd130x->vcc_reg);
326 static int ssd130x_init(struct ssd130x_device *ssd130x)
333 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast);
339 SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap));
340 ret = ssd130x_write_cmd(ssd130x, 1, seg_remap);
346 SSD130X_SET_COM_SCAN_DIR_SET(ssd130x->com_invdir));
347 ret = ssd130x_write_cmd(ssd130x, 1, com_invdir);
352 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
357 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x->com_offset);
362 dclk = (SSD130X_SET_CLOCK_DIV_SET(ssd130x->dclk_div - 1) |
363 SSD130X_SET_CLOCK_FREQ_SET(ssd130x->dclk_frq));
364 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_CLOCK_FREQ, dclk);
369 if (ssd130x->area_color_enable || ssd130x->low_power) {
372 if (ssd130x->area_color_enable)
375 if (ssd130x->low_power)
378 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_AREA_COLOR_MODE, mode);
384 precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) |
385 SSD130X_SET_PRECHARGE_PERIOD2_SET(ssd130x->prechargep2));
386 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge);
397 scan_mode = !ssd130x->com_seq;
399 SSD130X_SET_COM_PINS_CONFIG2_SET(ssd130x->com_lrremap));
400 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins);
405 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh);
412 if (ssd130x->device_info->need_chargepump)
415 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CHARGE_PUMP, chargepump);
420 if (ssd130x->lookup_table_set) {
423 ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE);
427 for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); i++) {
428 u8 val = ssd130x->lookup_table[i];
431 dev_warn(ssd130x->dev,
434 ret = ssd130x_write_cmd(ssd130x, 1, val);
441 if (ssd130x->page_address_mode)
442 return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
446 return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
450 static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
461 unsigned int page_height = ssd130x->device_info->page_height;
463 struct drm_device *drm = &ssd130x->drm;
498 if (!ssd130x->page_address_mode) {
500 ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width);
504 ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages);
513 if (8 * (y / 8 + i + 1) > ssd130x->height)
514 m = ssd130x->height % 8;
531 if (ssd130x->page_address_mode) {
532 ret = ssd130x_set_page_pos(ssd130x,
533 ssd130x->page_offset + i,
534 ssd130x->col_offset + x);
538 ret = ssd130x_write_data(ssd130x, data_array, width);
547 if (!ssd130x->page_address_mode)
548 ret = ssd130x_write_data(ssd130x, data_array, width * pages);
553 static void ssd130x_clear_screen(struct ssd130x_device *ssd130x,
556 unsigned int page_height = ssd130x->device_info->page_height;
557 unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
559 unsigned int width = ssd130x->width;
562 if (!ssd130x->page_address_mode) {
566 ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width);
570 ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages);
575 ssd130x_write_data(ssd130x, data_array, width * pages);
584 ret = ssd130x_set_page_pos(ssd130x,
585 ssd130x->page_offset + i,
586 ssd130x->col_offset);
590 ret = ssd130x_write_data(ssd130x, data_array, width);
602 struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
603 unsigned int page_height = ssd130x->device_info->page_height;
612 rect->y2 = min_t(unsigned int, round_up(rect->y2, page_height), ssd130x->height);
625 ssd130x_update_rect(ssd130x, ssd130x_state, rect);
634 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
637 unsigned int page_height = ssd130x->device_info->page_height;
638 unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
651 pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
653 ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
657 ssd130x_state->data_array = kcalloc(ssd130x->width, pages, GFP_KERNEL);
700 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
707 ssd130x_clear_screen(ssd130x, ssd130x_state);
783 struct ssd130x_device *ssd130x = drm_to_ssd130x(crtc->dev);
785 if (mode->hdisplay != ssd130x->mode.hdisplay &&
786 mode->vdisplay != ssd130x->mode.vdisplay)
788 else if (mode->hdisplay != ssd130x->mode.hdisplay)
790 else if (mode->vdisplay != ssd130x->mode.vdisplay)
819 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
822 ret = ssd130x_power_on(ssd130x);
826 ret = ssd130x_init(ssd130x);
830 ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON);
832 backlight_enable(ssd130x->bl_dev);
837 ssd130x_power_off(ssd130x);
845 struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
847 backlight_disable(ssd130x->bl_dev);
849 ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF);
851 ssd130x_power_off(ssd130x);
865 struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev);
867 struct device *dev = ssd130x->dev;
869 mode = drm_mode_duplicate(connector->dev, &ssd130x->mode);
919 struct ssd130x_device *ssd130x = bl_get_data(bdev);
923 ssd130x->contrast = brightness;
925 ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST);
929 ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast);
940 static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
942 struct device *dev = ssd130x->dev;
944 if (device_property_read_u32(dev, "solomon,width", &ssd130x->width))
945 ssd130x->width = ssd130x->device_info->default_width;
947 if (device_property_read_u32(dev, "solomon,height", &ssd130x->height))
948 ssd130x->height = ssd130x->device_info->default_height;
950 if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset))
951 ssd130x->page_offset = 1;
953 if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_offset))
954 ssd130x->col_offset = 0;
956 if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_offset))
957 ssd130x->com_offset = 0;
959 if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->prechargep1))
960 ssd130x->prechargep1 = 2;
962 if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
963 ssd130x->prechargep2 = 2;
966 ssd130x->lookup_table,
967 ARRAY_SIZE(ssd130x->lookup_table)))
968 ssd130x->lookup_table_set = 1;
970 ssd130x->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap");
971 ssd130x->com_seq = device_property_read_bool(dev, "solomon,com-seq");
972 ssd130x->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap");
973 ssd130x->com_invdir = device_property_read_bool(dev, "solomon,com-invdir");
974 ssd130x->area_color_enable =
976 ssd130x->low_power = device_property_read_bool(dev, "solomon,low-power");
978 ssd130x->contrast = 127;
979 ssd130x->vcomh = ssd130x->device_info->default_vcomh;
982 if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div))
983 ssd130x->dclk_div = ssd130x->device_info->default_dclk_div;
984 if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq))
985 ssd130x->dclk_frq = ssd130x->device_info->default_dclk_frq;
988 static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
990 struct drm_display_mode *mode = &ssd130x->mode;
991 struct device *dev = ssd130x->dev;
992 struct drm_device *drm = &ssd130x->drm;
1012 mode->hdisplay = mode->htotal = ssd130x->width;
1013 mode->hsync_start = mode->hsync_end = ssd130x->width;
1014 mode->vdisplay = mode->vtotal = ssd130x->height;
1015 mode->vsync_start = mode->vsync_end = ssd130x->height;
1031 primary_plane = &ssd130x->primary_plane;
1046 crtc = &ssd130x->crtc;
1058 encoder = &ssd130x->encoder;
1072 connector = &ssd130x->connector;
1093 static int ssd130x_get_resources(struct ssd130x_device *ssd130x)
1095 struct device *dev = ssd130x->dev;
1097 ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1098 if (IS_ERR(ssd130x->reset))
1099 return dev_err_probe(dev, PTR_ERR(ssd130x->reset),
1102 ssd130x->vcc_reg = devm_regulator_get(dev, "vcc");
1103 if (IS_ERR(ssd130x->vcc_reg))
1104 return dev_err_probe(dev, PTR_ERR(ssd130x->vcc_reg),
1112 struct ssd130x_device *ssd130x;
1117 ssd130x = devm_drm_dev_alloc(dev, &ssd130x_drm_driver,
1119 if (IS_ERR(ssd130x))
1120 return ERR_PTR(dev_err_probe(dev, PTR_ERR(ssd130x),
1123 drm = &ssd130x->drm;
1125 ssd130x->dev = dev;
1126 ssd130x->regmap = regmap;
1127 ssd130x->device_info = device_get_match_data(dev);
1129 if (ssd130x->device_info->page_mode_only)
1130 ssd130x->page_address_mode = 1;
1132 ssd130x_parse_properties(ssd130x);
1134 ret = ssd130x_get_resources(ssd130x);
1138 bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x,
1144 bl->props.brightness = ssd130x->contrast;
1146 ssd130x->bl_dev = bl;
1148 ret = ssd130x_init_modeset(ssd130x);
1158 return ssd130x;
1162 void ssd130x_remove(struct ssd130x_device *ssd130x)
1164 drm_dev_unplug(&ssd130x->drm);
1168 void ssd130x_shutdown(struct ssd130x_device *ssd130x)
1170 drm_atomic_helper_shutdown(&ssd130x->drm);