M7350v3_en_gpl

This commit is contained in:
T
2024-09-09 08:55:19 +00:00
parent 801e6d2ad8
commit 2d95e8761a
2791 changed files with 89608 additions and 390711 deletions

View File

@ -1,19 +0,0 @@
config OLED
bool "Support OLED display"
default n
---help---
Say Y here if you use OLED display
config OLED_SSD1306_PT
bool "Driver for OLED SSD1306"
select OLED
default n
---help---
Say Y here if you use OLED SSD1306
config OLED_S90319_PT
bool "Driver for OLED s90319"
select OLED
default n
---help---
Say Y here if you use OLED S90319

View File

@ -1,6 +0,0 @@
obj-$(CONFIG_OLED_SSD1306_PT) += oled_ssd1306_pt.o
obj-$(CONFIG_OLED_S90319_PT) += oled_s90319_pt.o
obj-$(CONFIG_OLED) += oled_pt.o oled_display.o
clean:
rm *.o .*cmd

View File

@ -1,184 +0,0 @@
/*******************************************************************************
Copyright (C), 2014, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_display.h
Description : oled sysfs interface.
Author : Luowei
History:
------------------------------
V0.1, 2014-05-13, Luowei create file.
*******************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
#include "oled_display.h"
struct class *oled_display_class;
EXPORT_SYMBOL_GPL(oled_display_class);
static struct device_type oled_display_dev_type;
#define DISPLAY_ATTR(_name) \
{ \
.attr = { .name = #_name }, \
.show = oled_display_show_property, \
.store = oled_display_store_property, \
}
static struct device_attribute oled_display_attrs[];
static ssize_t oled_display_show_property(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct oled_display *display = dev_get_drvdata(dev);
const ptrdiff_t off = attr - oled_display_attrs;
ssize_t ret = 0;
if (!display)
goto show_failed;
if ((off >= DISPLAY_PROP_BUFFER && off < DISPLAY_PROP_NUMBER)
&& display->show_property[off])
ret = display->show_property[off](dev, attr, buf);
return ret;
show_failed:
return 0;
}
static ssize_t oled_display_store_property(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct oled_display *display = dev_get_drvdata(dev);
const ptrdiff_t off = attr - oled_display_attrs;
ssize_t ret = 0;
if (!display)
goto show_failed;
if ((off >= DISPLAY_PROP_BUFFER && off < DISPLAY_PROP_NUMBER)
&& display->store_property[off])
ret = display->store_property[off](dev, attr, buf, count);
return ret;
show_failed:
return 0;
}
static struct device_attribute oled_display_attrs[] = {
DISPLAY_ATTR(oled_buffer),
DISPLAY_ATTR(backlight_on),
DISPLAY_ATTR(panel_on),
};
static struct attribute *__oled_display_attrs[ARRAY_SIZE(oled_display_attrs) + 1];
static umode_t oled_display_attr_is_visible(struct kobject *kobj,
struct attribute *attr,
int attrno)
{
return (S_IRUGO | S_IWUGO);
}
static struct attribute_group oled_display_attr_group = {
.attrs = __oled_display_attrs,
.is_visible = oled_display_attr_is_visible,
};
static const struct attribute_group *oled_display_attr_groups[] = {
&oled_display_attr_group,
NULL,
};
static void oled_display_init_attrs(struct device_type *dev_type)
{
int i;
dev_type->groups = oled_display_attr_groups;
for (i = 0; i < ARRAY_SIZE(oled_display_attrs); i++)
__oled_display_attrs[i] = &oled_display_attrs[i].attr;
}
static void oled_display_dev_release(struct device *dev)
{
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
kfree(dev);
}
int oled_display_register(struct device *parent, struct oled_display *display)
{
struct device *dev;
int rc;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
device_initialize(dev);
dev->class = oled_display_class;
dev->type = &oled_display_dev_type;
dev->parent = parent;
dev->release = oled_display_dev_release;
dev_set_drvdata(dev, display);
display->dev = dev;
rc = kobject_set_name(&dev->kobj, "%s", display->name);
if (rc)
goto kobject_set_name_failed;
rc = device_add(dev);
if (rc)
goto device_add_failed;
spin_lock_init(&display->lock);
return 0;
kobject_set_name_failed:
put_device(dev);
kfree(dev->p);
kfree(dev);
return rc;
device_add_failed:
device_del(dev);
put_device(dev);
return rc;
}
EXPORT_SYMBOL_GPL(oled_display_register);
void oled_display_unregister(struct oled_display *display)
{
device_unregister(display->dev);
}
EXPORT_SYMBOL_GPL(oled_display_unregister);
static int __init oled_display_class_init(void)
{
oled_display_class = class_create(THIS_MODULE, "display");
if (IS_ERR(oled_display_class))
return PTR_ERR(oled_display_class);
oled_display_init_attrs(&oled_display_dev_type);
return 0;
}
static void __exit oled_display_class_exit(void)
{
class_destroy(oled_display_class);
}
subsys_initcall(oled_display_class_init);
module_exit(oled_display_class_exit);
MODULE_DESCRIPTION("Universal display class");
MODULE_AUTHOR("LuoWei <luoweisj@tp-link.net>");
MODULE_LICENSE("GPL");

View File

@ -1,40 +0,0 @@
/*******************************************************************************
Copyright (C), 2014, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_display.h
Description : Header file of oled sysfs interface.
Author : Luowei
History:
------------------------------
V0.1, 2014-05-13, Luowei create file.
*******************************************************************************/
#ifndef __OLED_DISPLAY_H__
#define __OLED_DISPLAY_H__
#include <linux/types.h>
enum oled_display_property {
DISPLAY_PROP_BUFFER = 0,
DISPLAY_PROP_BACKLIGHTON,
DISPLAY_PROP_PANELON,
DISPLAY_PROP_NUMBER
};
struct oled_display {
const char *name;
enum oled_display_property *properties;
size_t num_properties;
ssize_t (*show_property[DISPLAY_PROP_NUMBER]) (struct device *dev,
struct device_attribute *attr, char *buf);
ssize_t (*store_property[DISPLAY_PROP_NUMBER]) (struct device *dev,
struct device_attribute *attr, const char *buf, size_t count);
struct device *dev;
spinlock_t lock;
};
int oled_display_register(struct device *parent, struct oled_display *display);
#endif

View File

@ -1,274 +0,0 @@
/*******************************************************************************
Copyright (C), 1996-2012, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_pt.c
Description : Driver for OLED s90319.
Author : linyunfeng
History:
------------------------------
V0.1, 2011-08-16, linyunfeng create file.
*******************************************************************************/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <mach/board.h>
#include <linux/device.h>
#include <linux/wakelock.h>
#include "oled_pt.h"
#include "oled_display.h"
//#define OLED_DEBUG
struct mutex oled_mutex;
struct wake_lock oled_wlock;
static struct oled_panel_data *oled_pdata;
#ifdef CONFIG_OLED_SSD1306_PT
extern uint8_t oled_ssd1306_buf[];
extern struct oled_panel_data oled_ssd1306_panel_data;
#endif
#ifdef CONFIG_OLED_S90319_PT
extern uint8_t oled_s90319_buf[];
extern struct oled_panel_data oled_s90319_panel_data;
#endif
static uint32_t oled_buf_size = 0;
/*******************************************************************************
Function : oled_buffer_show
Description : Print the oled buffer data, hex
Input : None
Output : buf: Command line buffer
Return : The number of characters will display in command
line.
Others : None
*******************************************************************************/
static ssize_t oled_buffer_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return oled_pdata->oled_print_buffer(buf);
}
/*******************************************************************************
Function : oled_buffer_store
Description : Write data to oled buffer.
Input : buf: Input format is: x,y,width,height,data.
count: Length of input.
Output : None
Return : Length of input or error number.
Others : None
*******************************************************************************/
static ssize_t oled_buffer_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
uint32_t data_length = 0;
uint8_t x = buf[0];
uint8_t y = buf[1];
uint8_t width = buf[2];
uint8_t height = buf[3];
if ('\n' == *(buf + count - 1)){
data_length = count - 5;
} else {
data_length = count - 4;
}
if (data_length > oled_buf_size) {
printk("%s, data_length=%d, oled_buf_size=%d, oled buffer overflow!\n",
__func__, data_length, oled_buf_size);
mutex_unlock(&oled_mutex);
return -1;
}
mutex_lock(&oled_mutex);
#ifdef CONFIG_OLED_SSD1306_PT
memcpy(oled_ssd1306_buf, buf + 4, data_length);
oled_pdata->oled_fill_with_pic(oled_ssd1306_buf,
x, y, width, height);
#endif
#ifdef CONFIG_OLED_S90319_PT
memcpy(oled_s90319_buf, buf + 4, buf[2] * buf[3] / 8);
oled_pdata->oled_fill_with_pic(oled_s90319_buf,
x, y, width, height);
#endif
mutex_unlock(&oled_mutex);
return count;
}
/*******************************************************************************
Function : backlight_on_store
Description : Control backlight.
Input : buf: 0: off, 1: on.
count: Length of input.
Output : None
Return : Length of input.
Others : None
*******************************************************************************/
static ssize_t backlight_on_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
uint8_t on = simple_strtoul(buf, NULL, 10);
#if defined(OLED_DEBUG)
printk("%s, buf=%s\n", __func__, buf);
#endif
oled_pdata->oled_set_backlight(on);
return count;
}
/*******************************************************************************
Function : panel_on_store
Description : Control panel.
Input : buf: 0: off, 1: on.
count: Length of input.
Output : None
Return : Length of input.
Others : None
*******************************************************************************/
static ssize_t panel_on_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
uint8_t on = simple_strtoul(buf, NULL, 10);
#if defined(OLED_DEBUG)
printk("%s, buf=%s\n", __func__, buf);
#endif
if (0 == on) {
oled_pdata->oled_panel_off();
if (wake_lock_active(&oled_wlock)) {
wake_unlock(&oled_wlock);
}
} else {
if (!wake_lock_active(&oled_wlock)) {
wake_lock(&oled_wlock);
}
oled_pdata->oled_panel_on();
}
#if defined(OLED_DEBUG)
printk("%s end\n", __func__);
#endif
return count;
}
static enum oled_display_property oled_display_prop[] = {
DISPLAY_PROP_BUFFER,
DISPLAY_PROP_BACKLIGHTON,
DISPLAY_PROP_PANELON
};
static struct oled_display oled_display = {
.name = "oled",
.properties = oled_display_prop,
.num_properties = ARRAY_SIZE(oled_display_prop),
.show_property = {oled_buffer_show},
.store_property = {oled_buffer_store, backlight_on_store, panel_on_store}
};
/* Function to load the device */
static int __devinit oled_probe(struct platform_device *pdev)
{
int ret = 0;
struct device *dev = &(pdev->dev);
printk("%s\n", __func__);
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
if (ret)
pr_err("%s: of_platform_populate failed %d\n", __func__, ret);
#ifdef CONFIG_OLED_SSD1306_PT
pdev->dev.platform_data = &oled_ssd1306_panel_data;
#endif
#ifdef CONFIG_OLED_S90319_PT
pdev->dev.platform_data = &oled_s90319_panel_data;
#endif
oled_pdata = pdev->dev.platform_data;
oled_buf_size = oled_pdata->panel_width * oled_pdata->panel_height;
oled_display.dev = dev;
ret = oled_display_register(dev, &oled_display);
if (ret < 0) {
dev_err(dev, "%s: oled_display_register failed, ret=%d\n",
__func__, ret);
return ret;
}
mutex_init(&oled_mutex);
wake_lock_init(&oled_wlock, WAKE_LOCK_SUSPEND, "oled");
return ret;
}
static int __devexit oled_remove(struct platform_device *pdev)
{
#if defined(OLED_DEBUG)
printk("%s\n", __func__);
#endif
wake_lock_destroy(&oled_wlock);
return 0;
}
static struct of_device_id tp_oled_pt_table[] = {
{ .compatible = "tp,oled_pt",},
{ },
};
static struct platform_driver oled_device_driver = {
.probe = oled_probe,
.remove = __devexit_p(oled_remove),
.driver = {
.name = "oled",
.owner = THIS_MODULE,
.of_match_table = tp_oled_pt_table,
},
};
static int __init oled_init(void)
{
int rc = 0;
#if defined(OLED_DEBUG)
printk("%s\n", __func__);
#endif
rc = platform_driver_register(&oled_device_driver);
if (!rc)
printk("oled init success!\n");
return rc;
}
static void __exit oled_exit(void)
{
#if defined(OLED_DEBUG)
printk("%s\n", __func__);
#endif
platform_driver_unregister(&oled_device_driver);
}
module_init(oled_init);
module_exit(oled_exit);
MODULE_AUTHOR("Lin Yunfeng");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("OLED display driver");

View File

@ -1,54 +0,0 @@
/*******************************************************************************
Copyright (C), 2014, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_pt.h
Description : Driver for OLED.
Author : Zhang Tao<zhangtao@tp-link.net>
History:
------------------------------
V0.1, 2014-04-14, ZhangTao create file.
*******************************************************************************/
#ifndef _OLED_PT_H
#define _OLED_PT_H
#ifdef CONFIG_OLED_SSD1306_PT
struct oled_panel_data {
void (*oled_gpio_config)(int on);
int (*oled_power_save)(int);
int (*oled_panel_on)(void);
int (*oled_panel_off)(void);
int (*oled_horizontal_scroll)(const uint8_t y, const uint8_t height,
const uint8_t t_interval_scroll, const uint8_t direction);
int (*oled_scroll_stop)(void);
int (*oled_fade_blink)(const uint8_t mode, const uint8_t t_interval_scroll);
int (*oled_fill_with_pic)(const uint8_t *pic, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height);
int (*oled_fill_with_value)(const uint8_t value, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height);
int (*oled_print_buffer)(char *buf);
int (*oled_set_backlight)(const uint8_t on);
int panel_width;
int panel_height;
int *gpio_num;
};
#endif
#ifdef CONFIG_OLED_S90319_PT
struct oled_panel_data {
void (*oled_gpio_config)(int on);
int (*oled_power_save)(int);
int (*oled_panel_on)(void);
int (*oled_panel_off)(void);
int (*oled_fill_with_pic)(const uint8_t *pic, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height);
int (*oled_set_backlight)(const uint8_t on);
int (*oled_print_buffer)(char *buf);
int panel_width;
int panel_height;
int *gpio_num;
};
#endif
#endif //end of _OLED_PT_H

View File

@ -1,781 +0,0 @@
/*******************************************************************************
Copyright (C), 1996-2014, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_s90319_pt.c
Description : Driver for OLED s90319.
Author : xiongsizhe
History:
------------------------------
V0.1, 2014-03-28, xiongsizhe create file.
*******************************************************************************/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include <mach/pmic.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <mach/board.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <mach/board.h>
#include <mach/gpiomux.h>
#include <linux/device.h>
#include "oled_pt.h"
#include "oled_s90319_pt.h"
//#define OLED_S90319_DEBUG
typedef unsigned int boolean;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
static int s90319_spi_write_cmd(const uint8_t *data, const uint16_t len);
static int s90319_spi_write_data(const uint8_t *data, const uint16_t len);
uint8_t oled_s90319_buf[COLUMN_NUM * ROW_NUM * 2] = {0};
static uint8_t frame_data[COLUMN_NUM * ROW_NUM * 2] ={0};
static uint8_t frame_data_buf[COLUMN_NUM * ROW_NUM * 2] ={0};
struct s90319_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
static struct s90319_state_type s90319_state = {0};
struct oled_panel_data oled_s90319_panel_data;
static struct oled_panel_data *oled_s90319_pdata;
static struct mutex flush_mutex;
static struct mutex oled_panel_mutex;
#define BUFFER_SIZE 4<<10
struct spi_message spi_msg;
//struct spi_transfer spi_xfer;
unsigned char *tx_buf;
struct s90319_work_t {
struct work_struct work;
};
static DECLARE_WAIT_QUEUE_HEAD(s90319_wait_queue);
static struct s90319_work_t *s90319_sensorw;
static struct spi_device *s90319_spi;
static int oled_s90319_rsx;
static int oled_s90319_cs;
static int oled_s90319_boost_en;
enum GPIO_OLED_S90319 {
GPIO_OLED_CS = 0,
GPIO_OLED_RESET,
GPIO_OLED_BOOST_EN,
GPIO_OLED_RSX,
GPIO_OLED_VDD0,
GPIO_OLED_VDD1,
GPIO_OLED_END,
};
static const char *dts_gpio_name[] = {
[GPIO_OLED_CS] = "qcom,oled-cs-gpio",
[GPIO_OLED_RESET] = "qcom,oled-reset-gpio",
[GPIO_OLED_BOOST_EN] = "qcom,oled-boost-en-gpio",
[GPIO_OLED_RSX] = "qcom,oled-rsx-gpio",
[GPIO_OLED_VDD0] = "qcom,oled-vdd0-gpio",
[GPIO_OLED_VDD1] = "qcom,oled-vdd1-gpio",
[GPIO_OLED_END] = "",
};
static int oled_s90319_gpio[GPIO_OLED_END] = {0};
/************************************************************
Function : wr_comm
Description: transfer command to oled
Input : commond
Return :
************************************************************/
void wr_comm(uint8_t cmd)
{
s90319_spi_write_cmd(&cmd, 1);
}
/************************************************************
Function : wr_dat
Description: transfer data to oled
Input : data
Return :
************************************************************/
void wr_dat(uint8_t data)
{
s90319_spi_write_data(&data, 1);
}
/************************************************************
Function : Delay
Description: delay time
Input : t
Return :
************************************************************/
void Delay(unsigned int t)
{
mdelay(t);
}
/************************************************************
Function : get_gpio_by_dtsname
Description: get gpio number by dtsname
Input :
Return :
************************************************************/
static void get_gpio_by_dtsname(struct device_node *node, const char *gpio_name[], u32 *gpio_num, int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
gpio_num[i] = of_get_named_gpio(node, gpio_name[i], 0);
}
}
/************************************************************
Function : oled_s90319_config_gpios
Description: config gpio
Input :
Return :
************************************************************/
static void oled_s90319_config_gpios(int enable)
{
int i, rc = 0;
for (i = 0; i < GPIO_OLED_END; i++)
{
if (enable)
{
rc = gpio_request(oled_s90319_gpio[i], dts_gpio_name[i]);
if (rc)
{
pr_err("request gpio %s failed, rc=%d\n", dts_gpio_name[i], rc);
gpio_free(oled_s90319_gpio[i]);
return;
}
}
else
{
gpio_free(oled_s90319_gpio[i]);
}
}
return;
}
/************************************************************
Function : oled_s90319_power_save
Description: open or close power supply
Input :
Return :
************************************************************/
static int oled_s90319_power_save(int on)
{
int rc = 0;
if (on)
{
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_RESET], 0);
mdelay(1);
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_VDD0], 1);
mdelay(1);
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_VDD1], 1);
mdelay(1);
gpio_set_value_cansleep(oled_s90319_gpio[GPIO_OLED_RESET], 1);
mdelay(1);
}
else
{
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_BOOST_EN], 0);
mdelay(1);
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_VDD1], 0);
mdelay(1);
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_VDD0], 0);
mdelay(1);
gpio_direction_output(oled_s90319_gpio[GPIO_OLED_RESET], 0);
mdelay(1);
}
return rc;
}
/************************************************************
Function : s90319_spi_txdata
Description: transfer data by spi
Input : txdata: data to transfer
length: length of txdata
Return :
************************************************************/
static int s90319_spi_txdata(uint8_t *txdata, const uint16_t length)
{
struct spi_transfer spi_xfer = {
.tx_buf = txdata,
.len = length,
};
spi_message_init(&spi_msg);
spi_message_add_tail(&spi_xfer, &spi_msg);
return spi_sync(s90319_spi, &spi_msg);
}
/************************************************************
Function : s90319_spi_write_cmd
Description: transfer cmd by spi
Input : data: cmd to transfer
len: length of cmd
Return :
************************************************************/
static int s90319_spi_write_cmd(const uint8_t *data, const uint16_t len)
{
int rc = 0;
#ifdef OLED_S90319_DEBUG
int i = 0;
printk("%s, data = 0x%x, len = %d\n", __func__, *data, len);
#endif
if (TRUE == s90319_state.disp_powered_up) {
memcpy(frame_data, data, len);
#ifdef OLED_S90319_DEBUG
for (i = 0; i < len; i++){
printk("0x%x ", *(frame_data+i));
}
printk("\n");
#endif
gpio_set_value_cansleep(oled_s90319_rsx, 0);
rc = s90319_spi_txdata(frame_data, len);
if (rc < 0) {
printk("%s fail, data = 0x%x, len = %d, rc = %d\n",
__func__, *data, len, rc);
}
}
return rc;
}
/************************************************************
Function : s90319_spi_write_data
Description: data need to be write
Input : data: data need to be write
len: length of data
Return :
************************************************************/
static int s90319_spi_write_data(const uint8_t *data, const uint16_t len)
{
int rc = -EFAULT;
#ifdef OLED_S90319_DEBUG
printk("%s, data = 0x%x, len = %d\n", __func__, *data, len);
#endif
if (TRUE == s90319_state.disp_powered_up) {
memcpy(frame_data, data, len);
gpio_set_value_cansleep(oled_s90319_rsx, 1);
rc = s90319_spi_txdata(frame_data, len);
if (rc < 0) {
printk("%s fail, data = 0x%x, len = %d, rc = %d\n",
__func__, *data, len, rc);
}
}
return rc;
}
/************************************************************
Function : oled_s90319_area_check
Description: check data area bigger than oled area or not
Input :
Return :
************************************************************/
static int oled_s90319_area_check(const uint8_t x, const uint8_t y,
const uint8_t width, const uint8_t height)
{
if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)
|| (x + width > COLUMN_NUM) || (y + height > ROW_NUM)){
printk("%s error, row_start=%d, col_start=%d, width=%d, height=%d",
__func__, x, y, width, height);
return -EINVAL;
}
return 0;
}
/************************************************************
Function : oled_s90319_fill_with_pic
Description: write pic data on location assign
Input :
Return :
************************************************************/
static int oled_s90319_fill_with_pic(const uint8_t *pic, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height)
{
int i = 0, m = 0, j = 0;
uint8_t data;
#if defined(OLED_S90319_DEBUG)
printk("%s,width=%d, height=%d\n", __func__, width, height);
#endif
if (oled_s90319_area_check(x, y, width, height)) {
return -EINVAL;
}
oled_s90319_set_col_addr[1] = x + X_OFFSET;
oled_s90319_set_col_addr[3] = x + width - 1 + X_OFFSET;
oled_s90319_set_row_addr[1] = y + Y_OFFSET;
oled_s90319_set_row_addr[3] = y + height - 1 + Y_OFFSET;
for (i = 0; i < width * height / 8; i++)
{
data = *pic;
for(m = 7; (m >= 0)&&(m <= 7); m--)
{
if((data >> m) & 0x01)
{
frame_data_buf[j] = 0x00;
frame_data_buf[j + 1] = 0x00;
}
else
{
frame_data_buf[j] = 0xFF;
frame_data_buf[j + 1] = 0xFF;
}
j = j + 2;
}
pic++;
}
if (TRUE == s90319_state.disp_initialized) {
mutex_lock(&flush_mutex);
s90319_spi_write_cmd(oled_set_col_cmd, sizeof(oled_set_col_cmd));
s90319_spi_write_data(oled_s90319_set_col_addr, sizeof(oled_s90319_set_col_addr));
s90319_spi_write_cmd(oled_set_row_cmd, sizeof(oled_set_row_cmd));
s90319_spi_write_data(oled_s90319_set_row_addr, sizeof(oled_s90319_set_row_addr));
s90319_spi_write_cmd(oled_write_data_cmd, sizeof(oled_write_data_cmd));
s90319_spi_write_data(frame_data_buf, width * height * 2);
mutex_unlock(&flush_mutex);
}
return 0;
}
static int oled_s90319_print_buffer(char* buf)
{
return 0;
}
/************************************************************
Function : oled_s90319_set_backlight
Description: backlight on/off
Input :
Return :
************************************************************/
static int oled_s90319_set_backlight(const uint8_t on)
{
#if defined(OLED_S90319_DEBUG)
printk("%s, on =%u\n", __func__, on);
#endif
if (0 == on) {
gpio_direction_output(oled_s90319_boost_en, 0);
} else {
gpio_direction_output(oled_s90319_boost_en, 1);
}
return 0;
}
/************************************************************
Function : oled_s90319_panel_init
Description: init panel
Input :
Return :
************************************************************/
static void oled_s90319_panel_init(void)
{
/* End Reset Sequence */
wr_comm(0x11); //Sleep out
Delay (120); //Delay 120ms
/* Frame Rate */
wr_comm(0xB1);
wr_dat(0x05);
wr_dat(0x3A);
wr_dat(0x3A);
wr_comm(0xB2);
wr_dat(0x05);
wr_dat(0x3A);
wr_dat(0x3A);
wr_comm(0xB3);
wr_dat(0x05);
wr_dat(0x3A);
wr_dat(0x3A);
wr_dat(0x05);
wr_dat(0x3A);
wr_dat(0x3A);
/* End Frame Rate */
wr_comm(0xB4); //Column inversion
wr_dat(0x07);
/* Power Sequence */
wr_comm(0xC0);
wr_dat(0xC8);
wr_dat(0x08);
wr_dat(0x84);
wr_comm(0xC1);
wr_dat(0XC5);
wr_comm(0xC2);
wr_dat(0x0A);
wr_dat(0x00);
wr_comm(0xC3);
wr_dat(0x8A);
wr_dat(0x2A);
wr_comm(0xC4);
wr_dat(0x8A);
wr_dat(0xEE);
/* End Power Sequence*/
wr_comm(0xC5); //VCOM
wr_dat(0x0C);
wr_comm(0x36); //MX, MY, RGB mode
wr_dat(0xc8);
/* Gamma Sequence */
wr_comm(0xE0);
wr_dat(0x05);
wr_dat(0x1A);
wr_dat(0x0C);
wr_dat(0x0E);
wr_dat(0x3A);
wr_dat(0x34);
wr_dat(0x2D);
wr_dat(0x2F);
wr_dat(0x2D);
wr_dat(0x2A);
wr_dat(0x2F);
wr_dat(0x3C);
wr_dat(0x00);
wr_dat(0x01);
wr_dat(0x02);
wr_dat(0x10);
wr_comm(0xE1);
wr_dat(0x04);
wr_dat(0x1B);
wr_dat(0x0D);
wr_dat(0x0E);
wr_dat(0x2D);
wr_dat(0x29);
wr_dat(0x24);
wr_dat(0x29);
wr_dat(0x28);
wr_dat(0x26);
wr_dat(0x31);
wr_dat(0x3B);
wr_dat(0x00);
wr_dat(0x00);
wr_dat(0x03);
wr_dat(0x12);
/* End Gamma Sequence */
wr_comm(0x3A); //65k mode
wr_dat(0x05);
wr_comm(0x2a);
wr_dat(0x00);
wr_dat(0x02);
wr_dat(0x00);
wr_dat(0x81);
wr_comm(0x2b);
wr_dat(0x00);
wr_dat(0x03);
wr_dat(0x00);
wr_dat(0x82);
wr_comm(0x29); //Display on
wr_comm(0x2C);
}
/************************************************************
Function : s90319_disp_on
Description: init oled and display on
Input :
Return :
************************************************************/
static void s90319_disp_on(void)
{
#if defined(OLED_S90319_DEBUG)
printk("%s\n", __func__);
#endif
if (s90319_state.disp_powered_up && !s90319_state.display_on) {
oled_s90319_panel_init();
s90319_state.display_on = TRUE;
}
}
/************************************************************
Function : s90319_disp_powerup
Description: power on
Input :
Return :
************************************************************/
static void s90319_disp_powerup(void)
{
#if defined(OLED_S90319_DEBUG)
printk("%s\n", __func__);
#endif
if (!s90319_state.disp_powered_up && !s90319_state.display_on) {
/* Reset the hardware first */
s90319_state.disp_powered_up = TRUE;
if (oled_s90319_pdata->oled_power_save)
oled_s90319_pdata->oled_power_save(1);
gpio_direction_output(oled_s90319_cs, 0);
/* 1 data, 0 command*/
gpio_direction_output(oled_s90319_rsx, 0);
mdelay(5);
gpio_set_value_cansleep(oled_s90319_cs, 0);
mdelay(3);
}
}
/************************************************************
Function : oled_s90319_panel_on
Description: init oled and power on
Input :
Return :
************************************************************/
static int oled_s90319_panel_on(void)
{
#if defined(OLED_S90319_DEBUG)
printk("%s\n", __func__);
#endif
mutex_lock(&oled_panel_mutex);
if (!s90319_state.disp_initialized) {
gpio_direction_output(oled_s90319_boost_en, 0);
s90319_disp_powerup();
s90319_disp_on();
s90319_state.disp_initialized = TRUE;
}
mutex_unlock(&oled_panel_mutex);
return 0;
}
/************************************************************
Function : oled_s90319_panel_off
Description: panel off
Input :
Return :
************************************************************/
static int oled_s90319_panel_off(void)
{
#if defined(OLED_S90319_DEBUG)
printk("%s\n", __func__);
#endif
mutex_lock(&oled_panel_mutex);
if (s90319_state.disp_powered_up && s90319_state.display_on) {
/* Main panel power off (Deep standby in) */
s90319_spi_write_cmd(oled_s90319_panel_off_cmd,
sizeof(oled_s90319_panel_off_cmd));
mdelay(100); /* Typical 100ms */
if (oled_s90319_pdata->oled_power_save)
oled_s90319_pdata->oled_power_save(0);
//if (oled_s90319_pdata->oled_gpio_config)
//oled_s90319_pdata->oled_gpio_config(0);
s90319_state.disp_powered_up = FALSE;
s90319_state.display_on = FALSE;
s90319_state.disp_initialized = FALSE;
}
mutex_unlock(&oled_panel_mutex);
return 0;
}
static struct of_device_id s90319__spi_table[] = {
{ .compatible = "tplink,oled",},
{ },
};
static int s90319_init_spi(struct spi_device *spi)
{
/* Initialize the MSM_CAMI2C Chip */
init_waitqueue_head(&s90319_wait_queue);
return 0;
}
/************************************************************
Function : s90319_spi_probe
Description: spi driver probe
Input :
Return :
************************************************************/
static int __devinit s90319_spi_probe(struct spi_device *spi)
{
tx_buf = kmalloc(BUFFER_SIZE, GFP_ATOMIC);
if (tx_buf == NULL)
{
printk("kmalloc failed.\n");
return -ENOMEM;
}
s90319_sensorw = kzalloc(sizeof(struct s90319_work_t), GFP_KERNEL);
if (!s90319_sensorw) {
printk("kzalloc failed.\n");
return -ENOMEM;
}
spi_set_drvdata(spi, s90319_sensorw);
s90319_init_spi(spi);
s90319_spi = spi;
msleep(50);
printk("%s successed!\n", __func__);
return 0;
}
/************************************************************
Function : oled_s90319_pin_assign
Description: assign gpio number
Input :
Return :
************************************************************/
static void oled_s90319_pin_assign(void)
{
/* Setting the Default GPIO's */
oled_s90319_cs = oled_s90319_gpio[GPIO_OLED_CS];
oled_s90319_rsx = oled_s90319_gpio[GPIO_OLED_RSX];
oled_s90319_boost_en = oled_s90319_gpio[GPIO_OLED_BOOST_EN];
}
/************************************************************
Function : oled_s90319_probe
Description: platform device driver probe
Input :
Return :
************************************************************/
static int __devinit oled_s90319_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
if (!node)
{
dev_err(&pdev->dev, "%s: device tree information missing\n", __func__);
return -ENODEV;
}
printk("%s\n", __func__);
pdev->dev.platform_data = &oled_s90319_panel_data;
oled_s90319_pdata = pdev->dev.platform_data;
get_gpio_by_dtsname(node, dts_gpio_name, oled_s90319_gpio, GPIO_OLED_END);
oled_s90319_pin_assign();
oled_s90319_pdata->oled_gpio_config = oled_s90319_config_gpios;
oled_s90319_pdata->oled_power_save = oled_s90319_power_save;
oled_s90319_pdata->oled_panel_on = oled_s90319_panel_on;
oled_s90319_pdata->oled_panel_off = oled_s90319_panel_off;
oled_s90319_pdata->oled_fill_with_pic = oled_s90319_fill_with_pic;
oled_s90319_pdata->oled_set_backlight = oled_s90319_set_backlight;
oled_s90319_pdata->oled_print_buffer = oled_s90319_print_buffer;
oled_s90319_pdata->panel_width = COLUMN_NUM;
oled_s90319_pdata->panel_height = ROW_NUM;
oled_s90319_config_gpios(ENABLE);
mutex_init(&flush_mutex);
mutex_init(&oled_panel_mutex);
return 0;
}
static int __devexit oled_s90319_remove(struct platform_device *pdev)
{
return 0;
}
static struct spi_driver s90319_spi_driver = {
.driver = {
.name = "oleds90319",
.owner = THIS_MODULE,
.of_match_table = s90319__spi_table,
},
.probe = s90319_spi_probe,
};
static struct of_device_id qcom_s90319_pt_table[] = {
{ .compatible = "qcom,oled_s90319_pt",},
{},
};
static struct platform_driver this_driver = {
.probe = oled_s90319_probe,
.remove = __devexit_p(oled_s90319_remove),
.driver = {
.name = "oled_s90319_pt",
.of_match_table = qcom_s90319_pt_table,
},
};
/************************************************************
Function : oled_90319_panel_init
Description: init function
Input :
Return :
************************************************************/
static int __init oled_90319_panel_init(void)
{
int ret = 0;
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
ret = spi_register_driver(&s90319_spi_driver);
if (ret < 0 || s90319_spi == NULL)
{
ret = -ENOTSUPP;
printk("SPI add driver failed.\n");
goto fail_driver;
}
printk("oled_90319_panel_init success.\n");
return ret;
fail_driver:
platform_driver_unregister(&this_driver);
return ret;
}
device_initcall(oled_90319_panel_init);
MODULE_AUTHOR("Xiong Sizhe");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("OLED 90319 driver");

View File

@ -1,145 +0,0 @@
/*******************************************************************************
Copyright (C), 1996-2012, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_s90319_pt.h
Description : Driver for OLED S90319.
Author : xiongsizhe
History:
------------------------------
V0.1, 2014-03-30, xiongsizhe create file.
*******************************************************************************/
#ifndef __OLED_S90319_PT_H__
#define __OLED_S90319_PT_H__
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef int int32_t;
typedef unsigned int uint32_t;
#define ROW_NUM 128 /* 0~7 */
#define PAGE_NUM 128
#define COLUMN_NUM 128
#define ENABLE 1
#define DISABLE 0
#define COLUMN_NUM_EXP 7 /* 2^7 = 128 */
/*
* Four Formats:
* 1. CMD_CONTROL BYTE . CMD . CMD . CMD <20><><EFBFBD><EFBFBD>
* 2. CMD_CONTROL BYTE . CMD . CMD_CONTROL_BYTE . CMD <20><><EFBFBD><EFBFBD>
* 3. DAT_CONTROL BYTE . DATA . DATA . DATA <20><><EFBFBD><EFBFBD>
* 4. DAT_CONTROL BYTE . DATA . DAT_CONTROL_BYTE . DATA <20><><EFBFBD><EFBFBD>
*/
#define OLED_CONTROL_CMDS 0x00
#define OLED_CONTROL_CMD_PAIRS 0x80
#define OLED_CONTROL_DATAS 0x40
#define OLED_CONTROL_DATA_PAIRS 0xC0
/* SINGLE CMDS */
#define CMD_DUMMY_BYTE_ZERO 0x00
#define CMD_DUMMY_BYTE_FF 0xFF
#define CMD_GRAM_IGNORE(bit) (0xA4|(bit)) /* 0: No, 1: Yes */
#define CMD_DISPLAY_OFF_ON(bit) (0xAE|(bit)) /* v: 0|1 */
#define CMD_SCAN_DIRECTION_0_TO_N 0xC0
#define CMD_SCAN_DIRECTION_N_TO_0 0xC8
#define CMD_LOWER_COL_ADDR(addr) (0x00|(addr)) /* addr: 0~F */
#define CMD_HIGHER_COL_ADDR(addr) (0x10|(addr)) /* addr: 0~F */
#define CMD_SEGMENT_REMAP(dir) (0xA0|(dir)) /* dir:0 normal direction, dir:1 reverse direction */
#define CMD_START_LINE(line) (0x40|(line)) /* line: 0 ~ 63 */
#define CMD_NORMAL_REV_DISPLAY(bit) (0xA6|(bit)) /* bit:0 normal display, bit:1 reverse display */
#define CMD_HORIZONTAL_SCROLL(dir) (0x26|(dir)) /* 0: L->R, 1:R->L */
#define CMD_SCROLL_ENABLE(ena) (0x2E|(ena)) /* 0:Disable, 1:Enable */
/* DOUBLE CMDS */
#define CMD_DOUBLE_CLOCK_DIVIDE_RATIO 0xD5
#define CMD_DOUBLE_MULTIPLEX_RATIO 0xA8
#define CMD_DOUBLE_PRECHARGE_PERIOD 0xD9
#define CMD_DOUBLE_PADS_HW_CONFIG 0xDA /* Sequence: 0x02; Alternative: 0x12*/
#define CMD_DOUBLE_CONTRAST_CONTROL 0x81
#define CMD_DOUBLE_DISPLAY_OFFSET 0xD3 /* 0x00 ~ 3f */
#define CMD_DOUBLE_VCOM_HLEVEL 0xDB /* 0x00 ~ 0xff */
#define CMD_DOUBLE_SET_CHARGE_PUMP 0x8D /* Enable: 0x14, Disable: 0x10*/
#define CMD_DOUBLE_MEMORY_ADDRESSING_MODE 0x20 /* 00: Horizontal 01: Vertial 10: Page 11: Invalid*/
#define CMD_DOUBLE_FADE_BLINK_MODE 0x23 /* Fade out or blinking mode */
/* TRIPLE CMDS */
#define CMD_TRIPE_COLUMN_ADDRESS 0x21 /* 0~127, 0~127 */
#define CMD_TRIPE_PAGE_ADDRESS 0x22 /* 0~7, 0~7 */
#define OLED_MATREIAL_STANDARD_CONTRAST 0xAF
#define OLED_MATREIAL_LOW_CONTRAST 0x0F
#define OLED_SET_COL_CMD 0x2A
#define OLED_SET_ROW_CMD 0x2B
#define OLED_WRITE_DATA_CMD 0x2C
#define X_OFFSET 2
#define Y_OFFSET 3
uint8_t CMD_HORIZONTAL_SCROLL_ARRAY[] = {CMD_HORIZONTAL_SCROLL(0), CMD_HORIZONTAL_SCROLL(1)};
uint8_t CMD_BACKLIGHT_ARRAY[] = {
CMD_DISPLAY_OFF_ON(0), /* Backlight off */
CMD_DISPLAY_OFF_ON(1) /* Backlight oN */
};
/* set col command */
uint8_t oled_set_col_cmd[] = {
OLED_SET_COL_CMD,
};
/* set row command */
uint8_t oled_set_row_cmd[] = {
OLED_SET_ROW_CMD,
};
/* write data command */
uint8_t oled_write_data_cmd[] = {
OLED_WRITE_DATA_CMD,
};
/* set backlight command */
uint8_t oled_s90319_backlight_cmd[] = {
CMD_DISPLAY_OFF_ON(0)
};
/* panel on/off command */
uint8_t oled_s90319_panel_off_cmd[] = {
CMD_DISPLAY_OFF_ON(0), /* manual display on */
CMD_DOUBLE_SET_CHARGE_PUMP, 0x10 /* set charge pump enable*/
};
uint8_t oled_s90319_scroll_stop_cmd[] = {
CMD_SCROLL_ENABLE(0)
};
/* Fade out or blinking mode */
uint8_t oled_s90319_fade_blink_cmd[] = {
CMD_DOUBLE_FADE_BLINK_MODE,
0
};
/*
* fade_blink_parameter:
* A[5:4] = 00b Disable Fade Out / Blinking Mode
* A[5:4] = 10b Enable Fade Out mode
* A[5:4] = 11b Enable Blinking mode
* A[3:0] : Set time interval for each fade step, (8 * (A[3:0] + 1))frames
*/
struct oled_s90319_fade_blink_cmd_config_struct {
uint8_t *fade_blink_parameter;
};
uint8_t oled_s90319_set_col_addr[] = {
0x00, 0x00, 0x00, 0x00
};
uint8_t oled_s90319_set_row_addr[] = {
0x00, 0x00, 0x00, 0x00
};
#endif /* __OLED_S90319_PT__ */

View File

@ -1,840 +0,0 @@
/*******************************************************************************
Copyright (C), 1996-2012, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_ssd1306_pt.c
Description : Driver for OLED SSD1306.
Author : linyunfeng
History:
------------------------------
V0.2, 2014-04-16, zhangtao modified oled_ssd1306_pt driver for dts of the new kernel.
V0.1, 2011-08-16, linyunfeng create file.
*******************************************************************************/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include <mach/pmic.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <mach/board.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_i2c.h>
#include <linux/of_gpio.h>
#include <mach/board.h>
#include <mach/gpiomux.h>
#include "oled_ssd1306_pt.h"
#include "oled_pt.h"
//#define OLED_SSD1306_DEBUG
typedef unsigned int boolean;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
uint8_t oled_ssd1306_buf[COLUMN_NUM * PAGE_NUM] = {0};
static uint8_t frame_data[COLUMN_NUM * PAGE_NUM + 1] ={0};
static uint8_t oled_ssd1306_image[COLUMN_NUM * PAGE_NUM] = {0};
struct ssd1306_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
struct ssd1306_work_t {
struct work_struct work;
};
struct ssd1306_i2c_reg_conf {
unsigned short waddr;
unsigned short wdata;
};
static struct ssd1306_state_type ssd1306_state = {0};
struct oled_panel_data oled_ssd1306_panel_data;
static struct oled_panel_data *oled_ssd1306_pdata;
static DECLARE_WAIT_QUEUE_HEAD(ssd1306_wait_queue);
static struct ssd1306_work_t *ssd1306_sensorw;
static struct i2c_client *ssd1306_client;
static struct mutex flush_mutex;
static struct mutex oled_panel_mutex;
/* Data/Command flag, 0: Command, 1: Data */
static int oled_ssd1306_sa0;
/* Chip select, always 0 in I2C mode */
static int oled_ssd1306_cs;
/* [ZhangTao start] for getting the gpio number configered in the dts file */
enum ENUM_OLED_SSD1306_GPIO {
GPIO_OLED_CS = 0,
GPIO_OLED_A0,
GPIO_OLED_RES,
GPIO_OLED_BOOST_EN,
GPIO_OLED_END
};
/* enum the gpio name defined in the dts config file */
static const char *dts_gpio_name[] = {
[GPIO_OLED_CS] = "qcom,oled-cs-gpio",
[GPIO_OLED_A0] = "qcom,oled-a0-gpio",
[GPIO_OLED_RES] = "qcom,oled-res-gpio",
[GPIO_OLED_BOOST_EN] = "qcom,oled-boost-en-gpio",
[GPIO_OLED_END] = "",
};
/* Store oled ssd1306 gpio pin number, will be filled by get_gpio_by_dtsname() */
static int oled_ssd1306_gpio[GPIO_OLED_END] = {0};
/*******************************************************************************
Function : get_gpio_by_dtsname
Description : get gpio pin number by name defined in dts config file.
Input : @node, the device node defined in dts which we get the gpio pin number form
@gpio_name[], the string array which store the gpio name defined in dts file
@gpio_num, we will store the gpio pin number getted from dts file in the int array gpio_num point to
@len, the numbers of gpio we will get
Output : gpio_num: the request gpios pin number which gpio_num point to
Return : void
Others : None
*******************************************************************************/
static void get_gpio_by_dtsname(struct device_node *node, const char *gpio_name[], u32 *gpio_num, int len)
{
int i;
for (i = 0; i < len; ++ i)
{
gpio_num[i] = of_get_named_gpio(node, gpio_name[i], 0);
}
}
/*******************************************************************************
Function : oled_ssd1306_config_gpios
Description : request/free for specific gpio
Input : @enable, 0: free gpios, 1: request gpios
Output : request or free the specific gpio stored in oled_ssd1306_gpio[]
Return : void
Others : None
*******************************************************************************/
static void oled_ssd1306_config_gpios(int enable)
{
int i, rc = 0;
for (i = 0; i < GPIO_OLED_END; ++ i)
{
if (enable) {
rc = gpio_request(oled_ssd1306_gpio[i], dts_gpio_name[i]);
if (rc)
{
pr_err("request gpio %s failed, rc=%d\n", dts_gpio_name[i], rc);
gpio_free(oled_ssd1306_gpio[i]);
return;
}
} else {
gpio_free(oled_ssd1306_gpio[i]);
}
}
return;
}
/*******************************************************************************
Function : oled_ssd1306_power_save
Description : power on/off the oled
Input : @on, 0: power off, 1: power on
Output :
Return : None
Others : None
*******************************************************************************/
static int oled_ssd1306_power_save(int on)
{
int rc = 0;
if (on) {
gpio_direction_output(oled_ssd1306_gpio[GPIO_OLED_RES], 0);
mdelay(1);
gpio_direction_output(oled_ssd1306_gpio[GPIO_OLED_BOOST_EN], 1);
mdelay(1);
__gpio_set_value(oled_ssd1306_gpio[GPIO_OLED_RES], 1);
mdelay(1);
} else {
gpio_direction_output(oled_ssd1306_gpio[GPIO_OLED_BOOST_EN], 0);
mdelay(1);
gpio_direction_output(oled_ssd1306_gpio[GPIO_OLED_RES], 0);
mdelay(1);
}
return rc;
}
/* [ZhangTao end]*/
static int ssd1306_i2c_txdata(const uint16_t saddr,
uint8_t *txdata, const uint16_t length)
{
struct i2c_msg msg[] = {
{
.addr = saddr,
.flags = 0,
.len = length,
.buf = txdata,
},
};
if (i2c_transfer(ssd1306_client->adapter, msg, 1) < 0) {
printk("ssd1306_i2c_txdata faild 0x%x\n", saddr);
return -EIO;
}
return 0;
}
/*******************************************************************************
Function : oled_ssd1306_print_buffer
Description : print the oled buffer data, hex
Input : None
Output : buf: Command line buffer
Return : The number of characters will display in command
line.
Others : None
*******************************************************************************/
static int oled_ssd1306_print_buffer(char *buf)
{
int i = 0;
int j = 0;
for (i = 0; i < PAGE_NUM; i++){
for (j = 0; j < COLUMN_NUM; j++) {
sprintf(buf + 3 *(i * (COLUMN_NUM + 1) + j), "%02x ",
*(oled_ssd1306_image
+ (i << COLUMN_NUM_EXP) + j));
}
sprintf(buf + (i + 1) * 3 * (COLUMN_NUM + 1) - 3, " \n" );
}
return (COLUMN_NUM + 1) * 3 * PAGE_NUM;
}
/*******************************************************************************
Function : ssd1306_i2c_write_cmd
Description : Send command by I2C
Input : data: Command will be send
len: The length of Command
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int ssd1306_i2c_write_cmd(const uint8_t *data, const uint16_t len)
{
int rc = 0;
#ifdef OLED_SSD1306_DEBUG
int i = 0;
printk("%s, data = 0x%x, len = %d\n", __func__, *data, len);
#endif
if (TRUE == ssd1306_state.disp_powered_up) {
*frame_data = OLED_CONTROL_CMDS;
memcpy(frame_data + 1, data, len);
#ifdef OLED_SSD1306_DEBUG
for (i = 0; i < len + 1; i++){
printk("0x%x ", *(frame_data+i));
}
printk("\n");
#endif
rc = ssd1306_i2c_txdata(ssd1306_client->addr, frame_data, len + 1);
if (rc < 0) {
printk("%s fail, data = 0x%x, len = %d\n",
__func__, *data, len);
}
}
return rc;
}
/*******************************************************************************
Function : ssd1306_i2c_write_data
Description : Send data by I2C
Input : data: Data will be send
len: The length of data
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int ssd1306_i2c_write_data(const uint8_t *data, const uint16_t len)
{
int rc = -EFAULT;
#ifdef OLED_SSD1306_DEBUG
printk("%s, data = 0x%x, len = %d\n", __func__, *data, len);
#endif
if (TRUE == ssd1306_state.disp_powered_up) {
*frame_data = OLED_CONTROL_DATAS;
memcpy(frame_data + 1, data, len);
rc = ssd1306_i2c_txdata((ssd1306_client->addr),
frame_data, len + 1);
if (rc < 0) {
printk("%s fail, data = 0x%x, len = %d\n",
__func__, *data, len);
}
}
return rc;
}
static void oled_ssd1306_pin_assign(void)
{
/* Setting the Default GPIO's */
oled_ssd1306_sa0 = oled_ssd1306_gpio[GPIO_OLED_A0];
oled_ssd1306_cs = oled_ssd1306_gpio[GPIO_OLED_CS];
}
static int oled_ssd1306_area_check(const uint8_t x, const uint8_t y,
const uint8_t width, const uint8_t height)
{
if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)
|| (x + width > COLUMN_NUM) || (y + height > PAGE_NUM)){
printk("%s error, row_start=%d, col_start=%d, width=%d, height=%d",
__func__, x, y, width, height);
return -EINVAL;
}
return 0;
}
/* [wuzhong start] */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
static int oled_sh1106_and_ssd1306_fill_with_pic(const uint8_t *pic, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height)
{
int i = 0;
#if defined(OLED_SSD1306_DEBUG)
printk("%s,width=%d, height=%d\n", __func__, width, height);
#endif
if (oled_ssd1306_area_check(x, y, width, height)) {
return -EINVAL;
}
if (TRUE == ssd1306_state.disp_initialized) {
mutex_lock(&flush_mutex);
for (i = 0; i < height; i++)
{
oled_sh1106_flush_cmd[1] = 0xb0 + y + i;
oled_sh1106_flush_cmd[2] = (x + SH1106_OFFSET) & 0x0f;
oled_sh1106_flush_cmd[3] = (((x + SH1106_OFFSET) & 0xf0) >> 4) | 0x10;
ssd1306_i2c_write_cmd(oled_sh1106_flush_cmd, sizeof(oled_sh1106_flush_cmd));
ssd1306_i2c_write_data(pic + i * width, width);
}
for (i = y; i < y + height; i++) {
memcpy(oled_ssd1306_image + (i << COLUMN_NUM_EXP) + x,
pic + width * (i - y), width);
}
mutex_unlock(&flush_mutex);
}
return 0;
}
#else /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
/*******************************************************************************
Function : oled_ssd1306_fill_with_pic
Description : Fill and flush certain area with picture.
Input : pic: Picture to fill
x: Start point, x coordinate, 0 ~ COLUMN_NUM - 1
y: Start point, y coordiante, 0 ~ PAGE_NUM - 1
width: Area width
height: Area height
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_fill_with_pic(const uint8_t *pic, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height)
{
int i = 0;
#if defined(OLED_SSD1306_DEBUG)
printk("%s,width=%d, height=%d\n", __func__, width, height);
#endif
if (oled_ssd1306_area_check(x, y, width, height)) {
return -EINVAL;
}
if (TRUE == ssd1306_state.disp_initialized) {
mutex_lock(&flush_mutex);
*(oled_ssd1306_flush_cmd_config.col_addr_start) = x;
*(oled_ssd1306_flush_cmd_config.col_addr_end) = x + width - 1;
*(oled_ssd1306_flush_cmd_config.page_addr_start) = y;
*(oled_ssd1306_flush_cmd_config.page_addr_end) = y + height - 1;
ssd1306_i2c_write_cmd(oled_ssd1306_flush_cmd, sizeof(oled_ssd1306_flush_cmd));
ssd1306_i2c_write_data(pic, width * height);
for (i = y; i < y + height; i++) {
memcpy(oled_ssd1306_image + (i << COLUMN_NUM_EXP) + x,
pic + width * (i - y), width);
}
mutex_unlock(&flush_mutex);
}
return 0;
}
#endif /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
/* [wuzhong end] */
/*******************************************************************************
Function : oled_ssd1306_fill_with_value
Description : Fill and flush certain area with value.
Input : value: Value to fill
x: Start point, x coordinate, 0 ~ COLUMN_NUM - 1
y: Start point, y coordiante, 0 ~ PAGE_NUM - 1
width: Area width
height: Area height
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_fill_with_value(const uint8_t value, const uint8_t x,
const uint8_t y, const uint8_t width, const uint8_t height)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
if (oled_ssd1306_area_check(x, y, width, height)) {
return -EINVAL;
}
memset(oled_ssd1306_buf, value, width * height);
/* [wuzhong start] */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
return oled_sh1106_and_ssd1306_fill_with_pic(oled_ssd1306_buf, x, y, width, height);
#else
return oled_ssd1306_fill_with_pic(oled_ssd1306_buf, x, y, width, height);
#endif
/* [wuzhong end] */
}
/*******************************************************************************
Function : oled_ssd1306_fade_blink
Description : Fade out or blink.
Input : mode: 0: Disable Fade Out / Blinking Mode.
2: Enable Fade Out mode.
3: Enable Blinking mode.
t_interval_scroll: Set time interval for each fade step, 0~7,
(8 * t_interval_scroll + 1))frames
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_fade_blink(const uint8_t mode, const uint8_t t_interval_scroll)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
if ((mode < 0) || (t_interval_scroll < 0) || (mode > 3)
|| (1 == mode) || (t_interval_scroll > 15)) {
printk("%s error, mode=%d, t_interval_scroll=%d",
__func__, mode, t_interval_scroll);
return -EINVAL;
}
*(oled_ssd1306_fade_blink_cmd_config.fade_blink_parameter)
= (mode << 4) | t_interval_scroll;
return ssd1306_i2c_write_cmd(oled_ssd1306_fade_blink_cmd, sizeof(oled_ssd1306_fade_blink_cmd));
}
/*******************************************************************************
Function : oled_ssd1306_scroll_stop
Description : Stop scroll.
Input : None
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_scroll_stop(void)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
return ssd1306_i2c_write_cmd(oled_ssd1306_scroll_stop_cmd, sizeof(oled_ssd1306_scroll_stop_cmd));
}
/*******************************************************************************
Function : oled_ssd1306_horizontal_scroll
Description : Horizontal scroll.
Input : y: Start point, y coordiante, 0 ~ PAGE_NUM - 1
height: Scroll area height
t_interval_scroll: 0: 5 frame, 1: 64, 2: 128, 3: 256,
4: 3, 5: 4, 6: 25, 7: 2
direction: 0: Left->Right, 1:Right->Left
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_horizontal_scroll(const uint8_t y, const uint8_t height,
const uint8_t t_interval_scroll, const uint8_t direction)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
if ((y < 0) || (height < 0) || (y + height > PAGE_NUM)
|| (t_interval_scroll < 0) || (t_interval_scroll > 7)
|| (direction < 0) || (direction > 1)) {
printk("%s error, y=%d, height=%d, t_interval_scroll=%d, direction=%d",
__func__, y, height, t_interval_scroll, direction);
return -EINVAL;
}
oled_ssd1306_scroll_stop();
mdelay(1);
*(oled_ssd1306_h_scroll_cmd_config.horizontal_scroll_direction) = CMD_HORIZONTAL_SCROLL_ARRAY[direction];
*(oled_ssd1306_h_scroll_cmd_config.page_addr_start) = y;
*(oled_ssd1306_h_scroll_cmd_config.time_interval_scroll) = t_interval_scroll;
*(oled_ssd1306_h_scroll_cmd_config.page_addr_end) = y + height - 1;
return ssd1306_i2c_write_cmd(oled_ssd1306_h_scroll_cmd, sizeof(oled_ssd1306_h_scroll_cmd));
}
/*******************************************************************************
Function : oled_ssd1306_set_backlight
Description : Set backlight on or off.
Input : on: 0: off, 1: on.
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_set_backlight(const uint8_t on)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s, on =%u\n", __func__, on);
#endif
if (0 == on) {
oled_ssd1306_backlight_cmd[0] = CMD_DISPLAY_OFF_ON(0);
} else {
oled_ssd1306_backlight_cmd[0] = CMD_DISPLAY_OFF_ON(1);
}
return ssd1306_i2c_write_cmd(oled_ssd1306_backlight_cmd, sizeof(oled_ssd1306_backlight_cmd));
}
/*******************************************************************************
Function : ssd1306_disp_on
Description : initial oled.
Input : None
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static void ssd1306_disp_on(void)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
if (ssd1306_state.disp_powered_up && !ssd1306_state.display_on) {
ssd1306_i2c_write_cmd(oled_ssd1306_init_cmd, sizeof(oled_ssd1306_init_cmd));
ssd1306_state.display_on = TRUE;
}
}
/*******************************************************************************
Function : ssd1306_disp_powerup
Description : Power and initial.
Input : None
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static void ssd1306_disp_powerup(void)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
if (!ssd1306_state.disp_powered_up && !ssd1306_state.display_on) {
/* Reset the hardware first */
ssd1306_state.disp_powered_up = TRUE;
if (oled_ssd1306_pdata->oled_power_save)
oled_ssd1306_pdata->oled_power_save(1);
gpio_direction_output(oled_ssd1306_cs, 0);
gpio_direction_output(oled_ssd1306_sa0, 0);
mdelay(5);
/* CS will be always 0 in I2C mode */
__gpio_set_value(oled_ssd1306_cs, 0);
/* SA0 is used to determine the I2C address in I2C mode */
__gpio_set_value(oled_ssd1306_sa0, 0);
mdelay(3);
}
}
/*******************************************************************************
Function : oled_ssd1306_panel_on
Description : Power and initial oled SSD1306.
Input : None
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_panel_on(void)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
mutex_lock(&oled_panel_mutex);
if (!ssd1306_state.disp_initialized) {
/* Configure reset GPIO that drives DAC */
if (oled_ssd1306_pdata->oled_gpio_config)
oled_ssd1306_pdata->oled_gpio_config(1);
ssd1306_disp_powerup();
ssd1306_disp_on();
ssd1306_state.disp_initialized = TRUE;
}
mutex_unlock(&oled_panel_mutex);
return 0;
}
/*******************************************************************************
Function : oled_ssd1306_panel_off
Description : Power down oled SSD1306.
Input : None
Output : None
Return : 0: OK, Others: Error.
Others : None
*******************************************************************************/
static int oled_ssd1306_panel_off(void)
{
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
mutex_lock(&oled_panel_mutex);
if (ssd1306_state.disp_powered_up && ssd1306_state.display_on) {
/* Main panel power off (Deep standby in) */
ssd1306_i2c_write_cmd(oled_ssd1306_panel_off_cmd,
sizeof(oled_ssd1306_panel_off_cmd));
mdelay(100); /* Typical 100ms */
if (oled_ssd1306_pdata->oled_power_save)
oled_ssd1306_pdata->oled_power_save(0);
if (oled_ssd1306_pdata->oled_gpio_config)
oled_ssd1306_pdata->oled_gpio_config(0);
ssd1306_state.disp_powered_up = FALSE;
ssd1306_state.display_on = FALSE;
ssd1306_state.disp_initialized = FALSE;
}
mutex_unlock(&oled_panel_mutex);
return 0;
}
static int __devinit oled_ssd1306_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
if (!node)
{
dev_err(&pdev->dev, "%s: device tree information missing\n", __func__);
return -ENODEV;
}
printk("%s\n", __func__);
pdev->dev.platform_data = &oled_ssd1306_panel_data;
oled_ssd1306_pdata = pdev->dev.platform_data;
/* get gpios' number by name defined in the dts config file and store them in oled_ssd1306_gpio array */
get_gpio_by_dtsname(node, dts_gpio_name, oled_ssd1306_gpio, GPIO_OLED_END);
oled_ssd1306_pin_assign();
/* [ZhangTao start] */
oled_ssd1306_pdata->oled_gpio_config = oled_ssd1306_config_gpios;
oled_ssd1306_pdata->oled_power_save = oled_ssd1306_power_save;
/* [ZhangTao end] */
oled_ssd1306_pdata->oled_panel_on = oled_ssd1306_panel_on;
oled_ssd1306_pdata->oled_panel_off = oled_ssd1306_panel_off;
oled_ssd1306_pdata->oled_horizontal_scroll = oled_ssd1306_horizontal_scroll;
oled_ssd1306_pdata->oled_scroll_stop = oled_ssd1306_scroll_stop;
oled_ssd1306_pdata->oled_fade_blink = oled_ssd1306_fade_blink;
/* [wuzhong start] */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
oled_ssd1306_pdata->oled_fill_with_pic = oled_sh1106_and_ssd1306_fill_with_pic;
#else
oled_ssd1306_pdata->oled_fill_with_pic = oled_ssd1306_fill_with_pic;
#endif
/* [wuzhong end] */
oled_ssd1306_pdata->oled_fill_with_value = oled_ssd1306_fill_with_value;
oled_ssd1306_pdata->oled_print_buffer = oled_ssd1306_print_buffer;
oled_ssd1306_pdata->oled_set_backlight = oled_ssd1306_set_backlight;
oled_ssd1306_pdata->panel_width = COLUMN_NUM;
oled_ssd1306_pdata->panel_height = PAGE_NUM;
mutex_init(&flush_mutex);
mutex_init(&oled_panel_mutex);
return 0;
}
static int __devexit oled_ssd1306_remove(struct platform_device *pdev)
{
return 0;
}
static int __devexit ssd1306_i2c_remove(struct i2c_client *client)
{
struct ssd1306_work_t *ssd1306 = i2c_get_clientdata(client);
free_irq(client->irq, ssd1306);
ssd1306_client = NULL;
kfree(ssd1306);
return 0;
}
static int ssd1306_init_client(struct i2c_client *client)
{
/* Initialize the MSM_CAMI2C Chip */
init_waitqueue_head(&ssd1306_wait_queue);
return 0;
}
static int ssd1306_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc = 0;
printk("%s called!\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk("i2c_check_functionality failed\n");
goto probe_failure;
}
ssd1306_sensorw = kzalloc(sizeof(struct ssd1306_work_t), GFP_KERNEL);
if (!ssd1306_sensorw) {
printk("kzalloc failed.\n");
rc = -ENOMEM;
goto probe_failure;
}
i2c_set_clientdata(client, ssd1306_sensorw);
ssd1306_init_client(client);
ssd1306_client = client;
msleep(50);
printk("%s successed! rc = %d\n", __func__, rc);
return 0;
probe_failure:
printk("%s failed! rc = %d\n", __func__, rc);
return rc;
}
static struct of_device_id qcom_ssd1306_i2c_table[] = {
{ .compatible = "qcom,ssd1306",},
{ },
};
static const struct i2c_device_id ssd1306_i2c_id[] = {
{"ssd1306", 0},
{ }
};
static struct i2c_driver ssd1306_i2c_driver = {
.id_table = ssd1306_i2c_id,
.probe = ssd1306_i2c_probe,
.remove = __exit_p(ssd1306_i2c_remove),
.driver = {
.name = "ssd1306",
.of_match_table = qcom_ssd1306_i2c_table,
},
};
static struct of_device_id qcom_ssd1306_pt_table[] = {
{ .compatible = "qcom,oled_ssd1306_pt",},
{ },
};
static struct platform_driver this_driver = {
.probe = oled_ssd1306_probe,
.remove = __devexit_p(oled_ssd1306_remove),
.driver = {
.name = "oled_ssd1306_pt",
.of_match_table = qcom_ssd1306_pt_table,
},
};
static int __init oled_ssd1306_panel_init(void)
{
int ret = 0;
#if defined(OLED_SSD1306_DEBUG)
printk("%s\n", __func__);
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
ret = i2c_add_driver(&ssd1306_i2c_driver);
if (ret < 0 || ssd1306_client == NULL) {
ret = -ENOTSUPP;
printk("I2C add driver failed");
goto fail_driver;
}
return ret;
fail_driver:
platform_driver_unregister(&this_driver);
return ret;
}
device_initcall(oled_ssd1306_panel_init);
MODULE_AUTHOR("Lin Yunfeng");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("OLED SSD1306 driver");

View File

@ -1,272 +0,0 @@
/*******************************************************************************
Copyright (C), 1996-2012, TP-LINK TECHNOLOGIES CO., LTD.
File name : oled_ssd1306_pt.h
Description : Driver for OLED SSD1306.
Author : linyunfeng
History:
------------------------------
V0.1, 2011-08-16, linyunfeng create file.
*******************************************************************************/
#ifndef __OLED_SSD1306_PT_H__
#define __OLED_SSD1306_PT_H__
/* [wuzhong start] 2012-11-29 */
#define __ENABLE_OLED_SH1106_AND_SSD1306__
/* [wuzhong end] */
#define PAGE_NUM 8 /* 0~7 */
/* [wuzhong start] 2012-11-29 */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
#define COLUMN_NUM 132
#else
#define COLUMN_NUM 128
#endif
/* [wuzhong end] */
#define COLUMN_NUM_EXP 7 /* 2^7 = 128 */
/*
* Four Formats:
* 1. CMD_CONTROL BYTE . CMD . CMD . CMD <20><><EFBFBD><EFBFBD>
* 2. CMD_CONTROL BYTE . CMD . CMD_CONTROL_BYTE . CMD <20><><EFBFBD><EFBFBD>
* 3. DAT_CONTROL BYTE . DATA . DATA . DATA <20><><EFBFBD><EFBFBD>
* 4. DAT_CONTROL BYTE . DATA . DAT_CONTROL_BYTE . DATA <20><><EFBFBD><EFBFBD>
*/
#define OLED_CONTROL_CMDS 0x00
#define OLED_CONTROL_CMD_PAIRS 0x80
#define OLED_CONTROL_DATAS 0x40
#define OLED_CONTROL_DATA_PAIRS 0xC0
/* SINGLE CMDS */
#define CMD_DUMMY_BYTE_ZERO 0x00
#define CMD_DUMMY_BYTE_FF 0xFF
#define CMD_GRAM_IGNORE(bit) (0xA4|(bit)) /* 0: No, 1: Yes */
#define CMD_DISPLAY_OFF_ON(bit) (0xAE|(bit)) /* v: 0|1 */
#define CMD_SCAN_DIRECTION_0_TO_N 0xC0
#define CMD_SCAN_DIRECTION_N_TO_0 0xC8
#define CMD_LOWER_COL_ADDR(addr) (0x00|(addr)) /* addr: 0~F */
#define CMD_HIGHER_COL_ADDR(addr) (0x10|(addr)) /* addr: 0~F */
#define CMD_SEGMENT_REMAP(dir) (0xA0|(dir)) /* dir:0 normal direction, dir:1 reverse direction */
#define CMD_START_LINE(line) (0x40|(line)) /* line: 0 ~ 63 */
#define CMD_NORMAL_REV_DISPLAY(bit) (0xA6|(bit)) /* bit:0 normal display, bit:1 reverse display */
#define CMD_HORIZONTAL_SCROLL(dir) (0x26|(dir)) /* 0: L->R, 1:R->L */
#define CMD_SCROLL_ENABLE(ena) (0x2E|(ena)) /* 0:Disable, 1:Enable */
/* DOUBLE CMDS */
#define CMD_DOUBLE_CLOCK_DIVIDE_RATIO 0xD5
#define CMD_DOUBLE_MULTIPLEX_RATIO 0xA8
#define CMD_DOUBLE_PRECHARGE_PERIOD 0xD9
#define CMD_DOUBLE_PADS_HW_CONFIG 0xDA /* Sequence: 0x02; Alternative: 0x12*/
#define CMD_DOUBLE_CONTRAST_CONTROL 0x81
#define CMD_DOUBLE_DISPLAY_OFFSET 0xD3 /* 0x00 ~ 3f */
#define CMD_DOUBLE_VCOM_HLEVEL 0xDB /* 0x00 ~ 0xff */
#define CMD_DOUBLE_SET_CHARGE_PUMP 0x8D /* Enable: 0x14, Disable: 0x10*/
#define CMD_DOUBLE_MEMORY_ADDRESSING_MODE 0x20 /* 00: Horizontal 01: Vertial 10: Page 11: Invalid*/
#define CMD_DOUBLE_FADE_BLINK_MODE 0x23 /* Fade out or blinking mode */
/* TRIPLE CMDS */
#define CMD_TRIPE_COLUMN_ADDRESS 0x21 /* 0~127, 0~127 */
#define CMD_TRIPE_PAGE_ADDRESS 0x22 /* 0~7, 0~7 */
#define OLED_MATREIAL_STANDARD_CONTRAST 0xAF
#define OLED_MATREIAL_LOW_CONTRAST 0x0F
uint8_t CMD_HORIZONTAL_SCROLL_ARRAY[] = {CMD_HORIZONTAL_SCROLL(0), CMD_HORIZONTAL_SCROLL(1)};
uint8_t CMD_BACKLIGHT_ARRAY[] = {
CMD_DISPLAY_OFF_ON(0), /* Backlight off */
CMD_DISPLAY_OFF_ON(1) /* Backlight oN */
};
/* [wuzhong start] 2012-11-29 */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
#define CMD_DC_DC_CONTROL 0xad
#define CMD_DC_DC_ON 0x8b /* POR */
#define CMD_DC_DC_OFF 0x8a
#endif
/* [wuzhong end] */
uint8_t oled_ssd1306_init_cmd[] = {
#if 0
CMD_DISPLAY_OFF_ON(0),
CMD_LOWER_COL_ADDR(0),
CMD_HIGHER_COL_ADDR(0),
CMD_START_LINE(0),
CMD_DOUBLE_CONTRAST_CONTROL,
OLED_MATREIAL_STANDARD_CONTRAST,
CMD_SEGMENT_REMAP(1), /* left-right */
CMD_NORMAL_REV_DISPLAY(0),
CMD_SCAN_DIRECTION_N_TO_0, /* up-down */
CMD_DOUBLE_MULTIPLEX_RATIO, 0x3F, /* something influence */
CMD_DOUBLE_DISPLAY_OFFSET, 0x00,
CMD_DOUBLE_CLOCK_DIVIDE_RATIO, 0xF0, /* something influence */
CMD_DOUBLE_PRECHARGE_PERIOD, 0x22, /* something influence */
CMD_DOUBLE_PADS_HW_CONFIG, 0x12,
CMD_DOUBLE_VCOM_HLEVEL, 0x40, /* something influence */
CMD_DOUBLE_SET_CHARGE_PUMP, 0x14, /* set charge pump enable*/
CMD_DISPLAY_OFF_ON(1) /* manual display on */
#else /* From vendor */
/* [wuzhong start] */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
CMD_DISPLAY_OFF_ON(0),
CMD_DOUBLE_CLOCK_DIVIDE_RATIO, 0x80, /* something influence */
CMD_DOUBLE_MULTIPLEX_RATIO, 0x3f, /* something influence */
CMD_DOUBLE_DISPLAY_OFFSET, 0x00,
CMD_START_LINE(0),
//CMD_DC_DC_CONTROL, CMD_DC_DC_ON, /* same with POR in sh1106, no this command in ssd1306 */
CMD_DOUBLE_SET_CHARGE_PUMP, 0x14, /* set charge pump enable for ssd1306, no this command in sh1106 */
//CMD_DOUBLE_MEMORY_ADDRESSING_MODE, 0x10, /* POR in ssd1306 , no this command in sh1106 */
CMD_SEGMENT_REMAP(1), /* left-right */
CMD_SCAN_DIRECTION_N_TO_0,
CMD_DOUBLE_PADS_HW_CONFIG, 0x12,
CMD_DOUBLE_CONTRAST_CONTROL,OLED_MATREIAL_STANDARD_CONTRAST, /* 0x40 was given in sh1106 init code(0x80 is recommended in sh1106 datasheet ), while SSD1306 use 0xaf */
CMD_DOUBLE_PRECHARGE_PERIOD, 0xF1, /* TODO: */
CMD_DOUBLE_VCOM_HLEVEL, 0x40, /* something influence */
CMD_GRAM_IGNORE(0),
CMD_NORMAL_REV_DISPLAY(0),
//CMD_DISPLAY_OFF_ON(1) /* Backlight on */
#else /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
CMD_DISPLAY_OFF_ON(0),
CMD_DOUBLE_CLOCK_DIVIDE_RATIO, 0x80, /* something influence */
CMD_DOUBLE_MULTIPLEX_RATIO, 0x3f, /* something influence */
CMD_DOUBLE_DISPLAY_OFFSET, 0x00,
CMD_START_LINE(0),
CMD_DOUBLE_SET_CHARGE_PUMP, 0x14, /* set charge pump enable*/
CMD_DOUBLE_MEMORY_ADDRESSING_MODE, 0x00,
CMD_SEGMENT_REMAP(1), /* left-right */
CMD_SCAN_DIRECTION_N_TO_0,
CMD_DOUBLE_PADS_HW_CONFIG, 0x12,
CMD_DOUBLE_CONTRAST_CONTROL,
OLED_MATREIAL_STANDARD_CONTRAST,
CMD_DOUBLE_PRECHARGE_PERIOD, 0xF1, /* something influence */
CMD_DOUBLE_VCOM_HLEVEL, 0x40, /* something influence */
CMD_GRAM_IGNORE(0),
CMD_NORMAL_REV_DISPLAY(0),
//CMD_DISPLAY_OFF_ON(1) /* Backlight on */
#endif /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
/* [wuzhong end] */
#endif /* From vendor */
};
uint8_t oled_ssd1306_backlight_cmd[] = {
CMD_DISPLAY_OFF_ON(0)
};
uint8_t oled_ssd1306_panel_off_cmd[] = {
CMD_DISPLAY_OFF_ON(0), /* manual display on */
CMD_DOUBLE_SET_CHARGE_PUMP, 0x10 /* set charge pump enable*/
};
uint8_t oled_ssd1306_scroll_stop_cmd[] = {
CMD_SCROLL_ENABLE(0)
};
/* Fade out or blinking mode */
uint8_t oled_ssd1306_fade_blink_cmd[] = {
CMD_DOUBLE_FADE_BLINK_MODE,
0
};
/*
* fade_blink_parameter:
* A[5:4] = 00b Disable Fade Out / Blinking Mode
* A[5:4] = 10b Enable Fade Out mode
* A[5:4] = 11b Enable Blinking mode
* A[3:0] : Set time interval for each fade step, (8 * (A[3:0] + 1))frames
*/
struct oled_ssd1306_fade_blink_cmd_config_struct {
uint8_t *fade_blink_parameter;
};
static struct oled_ssd1306_fade_blink_cmd_config_struct oled_ssd1306_fade_blink_cmd_config = {
.fade_blink_parameter = &oled_ssd1306_fade_blink_cmd[1],
};
/* [wuzhong start] */
#ifdef __ENABLE_OLED_SH1106_AND_SSD1306__
// sh1106 is 4 pixel widder then ssd1306
#define SH1106_OFFSET 2
//struct oled_sh1106_flush_cmd {
// uint8_t* line_start;
// uint8_t* low_column;
// uint8_t* high_column;
// uint8_t* page_number;
//};
// line: 0x40 as default
// page: range 0xb0~0xb7
// low column: range 0x00~0x0f
// high column: range 0x10~0x1f
uint8_t oled_sh1106_flush_cmd[] = {
0x40, 0xb0, 0x00, 0x10
};
#else /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
/* Flush the screen */
uint8_t oled_ssd1306_flush_cmd[] = {
CMD_DOUBLE_MEMORY_ADDRESSING_MODE, 0,
CMD_TRIPE_COLUMN_ADDRESS, 0, (COLUMN_NUM - 1),
CMD_TRIPE_PAGE_ADDRESS, 0, (PAGE_NUM - 1)
};
struct oled_ssd1306_flush_cmd_config_struct {
uint8_t *col_addr_start;
uint8_t *col_addr_end;
uint8_t *page_addr_start;
uint8_t *page_addr_end;
};
static struct oled_ssd1306_flush_cmd_config_struct oled_ssd1306_flush_cmd_config = {
.col_addr_start = &oled_ssd1306_flush_cmd[3], /* Start column address, 0~127 */
.col_addr_end = &oled_ssd1306_flush_cmd[4], /* End column address, 0~127 */
.page_addr_start = &oled_ssd1306_flush_cmd[6], /* Start page address, 0~7 */
.page_addr_end = &oled_ssd1306_flush_cmd[7], /* End page address, 0~7 */
};
#endif /* __ENABLE_OLED_SH1106_AND_SSD1306__ */
/* [wuzhong end] */
/* Horizontal scroll */
uint8_t oled_ssd1306_h_scroll_cmd[] = {
CMD_HORIZONTAL_SCROLL(0), /* Direction, 0: L->R, 1:R->L */
CMD_DUMMY_BYTE_ZERO,
0, /* Start page address */
0, /* Frames interval between each scroll,
* 0: 5 frame, 1: 64, 2: 128, 3: 256,
* 4: 3, 5: 4, 6: 25, 7: 2 */
(PAGE_NUM - 1), /* End page address */
CMD_DUMMY_BYTE_ZERO,
CMD_DUMMY_BYTE_FF,
CMD_SCROLL_ENABLE(1)
};
struct oled_ssd1306_h_scroll_cmd_config_struct {
uint8_t *horizontal_scroll_direction;
uint8_t *page_addr_start;
uint8_t *time_interval_scroll;
uint8_t *page_addr_end;
};
static struct oled_ssd1306_h_scroll_cmd_config_struct oled_ssd1306_h_scroll_cmd_config = {
.horizontal_scroll_direction = &oled_ssd1306_h_scroll_cmd[0],
.page_addr_start = &oled_ssd1306_h_scroll_cmd[2],
.time_interval_scroll = &oled_ssd1306_h_scroll_cmd[3],
.page_addr_end = &oled_ssd1306_h_scroll_cmd[4],
};
#endif /* __OLED_SSD1306_PT__ */