aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/ssd1307fb.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
index a0d6f96ec4e4..9daf058917a7 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/ssd1307fb.c
@@ -51,6 +51,11 @@ struct ssd1307fb_par {
51 u32 width; 51 u32 width;
52}; 52};
53 53
54struct ssd1307fb_array {
55 u8 type;
56 u8 data[0];
57};
58
54static struct fb_fix_screeninfo ssd1307fb_fix = { 59static struct fb_fix_screeninfo ssd1307fb_fix = {
55 .id = "Solomon SSD1307", 60 .id = "Solomon SSD1307",
56 .type = FB_TYPE_PACKED_PIXELS, 61 .type = FB_TYPE_PACKED_PIXELS,
@@ -65,49 +70,67 @@ static struct fb_var_screeninfo ssd1307fb_var = {
65 .bits_per_pixel = 1, 70 .bits_per_pixel = 1,
66}; 71};
67 72
68static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len) 73static struct ssd1307fb_array *ssd1307fb_alloc_array(u32 len, u8 type)
69{ 74{
70 u8 *buf; 75 struct ssd1307fb_array *array;
71 int ret = 0;
72
73 buf = kzalloc(len + 1, GFP_KERNEL);
74 if (!buf) {
75 dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
76 return -ENOMEM;
77 }
78 76
79 buf[0] = type; 77 array = kzalloc(sizeof(struct ssd1307fb_array) + len, GFP_KERNEL);
80 memcpy(buf + 1, cmd, len); 78 if (!array)
79 return NULL;
81 80
82 ret = i2c_master_send(client, buf, len + 1); 81 array->type = type;
83 if (ret != len + 1) {
84 dev_err(&client->dev, "Couldn't send I2C command.\n");
85 goto error;
86 }
87 82
88error: 83 return array;
89 kfree(buf);
90 return ret;
91} 84}
92 85
93static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len) 86static int ssd1307fb_write_array(struct i2c_client *client,
87 struct ssd1307fb_array *array, u32 len)
94{ 88{
95 return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len); 89 int ret;
90
91 len += sizeof(struct ssd1307fb_array);
92
93 ret = i2c_master_send(client, (u8 *)array, len);
94 if (ret != len) {
95 dev_err(&client->dev, "Couldn't send I2C command.\n");
96 return ret;
97 }
98
99 return 0;
96} 100}
97 101
98static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd) 102static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
99{ 103{
100 return ssd1307fb_write_cmd_array(client, &cmd, 1); 104 struct ssd1307fb_array *array;
101} 105 int ret;
102 106
103static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len) 107 array = ssd1307fb_alloc_array(1, SSD1307FB_COMMAND);
104{ 108 if (!array)
105 return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len); 109 return -ENOMEM;
110
111 array->data[0] = cmd;
112
113 ret = ssd1307fb_write_array(client, array, 1);
114 kfree(array);
115
116 return ret;
106} 117}
107 118
108static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data) 119static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
109{ 120{
110 return ssd1307fb_write_data_array(client, &data, 1); 121 struct ssd1307fb_array *array;
122 int ret;
123
124 array = ssd1307fb_alloc_array(1, SSD1307FB_DATA);
125 if (!array)
126 return -ENOMEM;
127
128 array->data[0] = data;
129
130 ret = ssd1307fb_write_array(client, array, 1);
131 kfree(array);
132
133 return ret;
111} 134}
112 135
113static void ssd1307fb_update_display(struct ssd1307fb_par *par) 136static void ssd1307fb_update_display(struct ssd1307fb_par *par)