From: Maxime Ripard <maxime.ripard@free-electrons.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Shawn Guo <shawn.guo@linaro.org>,
Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: linux-fbdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Maxime Ripard <maxime.ripard@free-electrons.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 4/4] ssd1307fb: Make use of horizontal addressing mode
Date: Mon, 22 Apr 2013 12:02:25 +0200 [thread overview]
Message-ID: <1366624945-5708-5-git-send-email-maxime.ripard@free-electrons.com> (raw)
In-Reply-To: <1366624945-5708-1-git-send-email-maxime.ripard@free-electrons.com>
By default, the ssd1307 controller uses an addressing mode called page
addressing. This mode only increments the column cursor in memory when
writing data but will not increments the page cursor when we are at the
end of the page.
However, the controller supports another addressing mode, called
horizontal addressing, that will maintain both the page and column
cursors when writing data to the controller.
That means that we can just remove the code that increments the current
page address and reset the column cursor when reaching the end of the
line, allowing to have a lower data overhead, and a simpler driver.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/video/ssd1307fb.c | 51 +++++++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 13 deletions(-)
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
index cab5f7c..259c9ee 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/ssd1307fb.c
@@ -19,6 +19,12 @@
#define SSD1307FB_DATA 0x40
#define SSD1307FB_COMMAND 0x80
+#define SSD1307FB_SET_ADDRESS_MODE 0x20
+#define SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL (0x00)
+#define SSD1307FB_SET_ADDRESS_MODE_VERTICAL (0x01)
+#define SSD1307FB_SET_ADDRESS_MODE_PAGE (0x02)
+#define SSD1307FB_SET_COL_RANGE 0x21
+#define SSD1307FB_SET_PAGE_RANGE 0x22
#define SSD1307FB_CONTRAST 0x81
#define SSD1307FB_CHARGE_PUMP 0x8d
#define SSD1307FB_SEG_REMAP_ON 0xa1
@@ -135,9 +141,15 @@ static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
static void ssd1307fb_update_display(struct ssd1307fb_par *par)
{
+ struct ssd1307fb_array *array;
u8 *vmem = par->info->screen_base;
int i, j, k;
+ array = ssd1307fb_alloc_array(par->width * par->height / 8,
+ SSD1307FB_DATA);
+ if (!array)
+ return;
+
/*
* The screen is divided in pages, each having a height of 8
* pixels, and the width of the screen. When sending a byte of
@@ -168,29 +180,22 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
*/
for (i = 0; i < (par->height / 8); i++) {
- struct ssd1307fb_array *array;
- ssd1307fb_write_cmd(par->client,
- SSD1307FB_START_PAGE_ADDRESS + i + par->page_offset);
- ssd1307fb_write_cmd(par->client, 0x00);
- ssd1307fb_write_cmd(par->client, 0x10);
-
- array = ssd1307fb_alloc_array(par->width, SSD1307FB_DATA);
-
for (j = 0; j < par->width; j++) {
- array->data[j] = 0;
+ u32 array_idx = i * par->width + j;
+ array->data[array_idx] = 0;
for (k = 0; k < 8; k++) {
u32 page_length = par->width * i;
u32 index = page_length + (par->width * k + j) / 8;
u8 byte = *(vmem + index);
u8 bit = byte & (1 << (j % 8));
bit = bit >> (j % 8);
- array->data[j] |= bit << k;
+ array->data[array_idx] |= bit << k;
}
}
-
- ssd1307fb_write_array(par->client, array, par->width);
- kfree(array);
}
+
+ ssd1307fb_write_array(par->client, array, par->width * par->height / 8);
+ kfree(array);
}
@@ -371,6 +376,26 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0)
return ret;
+ /* Switch to horizontal addressing mode */
+ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE);
+ ret = ret & ssd1307fb_write_cmd(par->client,
+ SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL);
+ if (ret < 0)
+ return ret;
+
+ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE);
+ ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
+ ret = ret & ssd1307fb_write_cmd(par->client, par->width - 1);
+ if (ret < 0)
+ return ret;
+
+ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE);
+ ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
+ ret = ret & ssd1307fb_write_cmd(par->client,
+ par->page_offset + (par->height / 8) - 1);
+ if (ret < 0)
+ return ret;
+
/* Turn on the display */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
if (ret < 0)
--
1.7.10.4
prev parent reply other threads:[~2013-04-22 10:05 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1366624945-5708-1-git-send-email-maxime.ripard@free-electrons.com>
2013-04-22 10:02 ` [PATCH 1/4] ARM: cfa10036: dt: Change i2c0 clock frequency Maxime Ripard
2013-05-08 14:01 ` Shawn Guo
2013-04-22 10:02 ` [PATCH 2/4] ssd1307fb: Rework the communication functions Maxime Ripard
2013-04-22 10:02 ` [PATCH 3/4] ssd1307fb: Speed up the communication with the controller Maxime Ripard
2013-04-22 10:02 ` Maxime Ripard [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1366624945-5708-5-git-send-email-maxime.ripard@free-electrons.com \
--to=maxime.ripard@free-electrons.com \
--cc=FlorianSchandinat@gmx.de \
--cc=akpm@linux-foundation.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=shawn.guo@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®