diff options
-rw-r--r-- | drivers/video/ssd1307fb.c | 77 |
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 | ||
54 | struct ssd1307fb_array { | ||
55 | u8 type; | ||
56 | u8 data[0]; | ||
57 | }; | ||
58 | |||
54 | static struct fb_fix_screeninfo ssd1307fb_fix = { | 59 | static 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 | ||
68 | static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len) | 73 | static 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 | ||
88 | error: | 83 | return array; |
89 | kfree(buf); | ||
90 | return ret; | ||
91 | } | 84 | } |
92 | 85 | ||
93 | static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len) | 86 | static 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 | ||
98 | static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd) | 102 | static 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 | ||
103 | static 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 | ||
108 | static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data) | 119 | static 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 | ||
113 | static void ssd1307fb_update_display(struct ssd1307fb_par *par) | 136 | static void ssd1307fb_update_display(struct ssd1307fb_par *par) |