u16     y;
        u16     z1, z2;
        int     ignore;
+       u8      x_buf[3];
+       u8      y_buf[3];
 };
 
 /*
        u8                      read_x, read_y, read_z1, read_z2, pwrdown;
        u16                     dummy;          /* for the pwrdown read */
        struct ts_event         tc;
+       /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */
+       u8                      read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3];
 };
 
 struct ads7846 {
        struct spi_transfer     xfer[6];
 };
 
+struct ads7845_ser_req {
+       u8                      command[3];
+       u8                      pwrdown[3];
+       u8                      sample[3];
+       struct spi_message      msg;
+       struct spi_transfer     xfer[2];
+};
+
 static void ads7846_enable(struct ads7846 *ts);
 static void ads7846_disable(struct ads7846 *ts);
 
        return status;
 }
 
+static int ads7845_read12_ser(struct device *dev, unsigned command)
+{
+       struct spi_device       *spi = to_spi_device(dev);
+       struct ads7846          *ts = dev_get_drvdata(dev);
+       struct ads7845_ser_req  *req = kzalloc(sizeof *req, GFP_KERNEL);
+       int                     status;
+
+       if (!req)
+               return -ENOMEM;
+
+       spi_message_init(&req->msg);
+
+       req->command[0] = (u8) command;
+       req->xfer[0].tx_buf = req->command;
+       req->xfer[0].rx_buf = req->sample;
+       req->xfer[0].len = 3;
+       spi_message_add_tail(&req->xfer[0], &req->msg);
+
+       ts->irq_disabled = 1;
+       disable_irq(spi->irq);
+       status = spi_sync(spi, &req->msg);
+       ts->irq_disabled = 0;
+       enable_irq(spi->irq);
+
+       if (status == 0) {
+               /* BE12 value, then padding */
+               status = be16_to_cpu(*((u16 *)&req->sample[1]));
+               status = status >> 3;
+               status &= 0x0fff;
+       }
+
+       kfree(req);
+       return status;
+}
+
 #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
 
 #define SHOW(name, var, adjust) static ssize_t \
        /* ads7846_rx_val() did in-place conversion (including byteswap) from
         * on-the-wire format as part of debouncing to get stable readings.
         */
-       x = packet->tc.x;
-       y = packet->tc.y;
-       z1 = packet->tc.z1;
-       z2 = packet->tc.z2;
+       if (ts->model == 7845) {
+               x = *(u16 *)packet->tc.x_buf;
+               y = *(u16 *)packet->tc.y_buf;
+               z1 = 0;
+               z2 = 0;
+       } else {
+               x = packet->tc.x;
+               y = packet->tc.y;
+               z1 = packet->tc.z1;
+               z2 = packet->tc.z2;
+       }
 
        /* range filtering */
        if (x == MAX_12BIT)
 
        if (ts->model == 7843) {
                Rt = ts->pressure_max / 2;
+       } else if (ts->model == 7845) {
+               if (get_pendown_state(ts))
+                       Rt = ts->pressure_max / 2;
+               else
+                       Rt = 0;
+               dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt);
        } else if (likely(x && z1)) {
                /* compute touch pressure resistance using equation #2 */
                Rt = z2;
        m = &ts->msg[ts->msg_idx];
        t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
 
-       /* adjust:  on-wire is a must-ignore bit, a BE12 value, then padding;
-        * built from two 8 bit values written msb-first.
-        */
-       val = be16_to_cpup((__be16 *)t->rx_buf) >> 3;
+       if (ts->model == 7845) {
+               val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
+       } else {
+               /* adjust:  on-wire is a must-ignore bit, a BE12 value, then
+                * padding; built from two 8 bit values written msb-first.
+                */
+               val = be16_to_cpup((__be16 *)t->rx_buf) >> 3;
+       }
 
        action = ts->filter(ts->filter_data, ts->msg_idx, &val);
        switch (action) {
 
        spi_message_init(m);
 
-       /* y- still on; turn on only y+ (and ADC) */
-       packet->read_y = READ_Y(vref);
-       x->tx_buf = &packet->read_y;
-       x->len = 1;
-       spi_message_add_tail(x, m);
+       if (ts->model == 7845) {
+               packet->read_y_cmd[0] = READ_Y(vref);
+               packet->read_y_cmd[1] = 0;
+               packet->read_y_cmd[2] = 0;
+               x->tx_buf = &packet->read_y_cmd[0];
+               x->rx_buf = &packet->tc.y_buf[0];
+               x->len = 3;
+               spi_message_add_tail(x, m);
+       } else {
+               /* y- still on; turn on only y+ (and ADC) */
+               packet->read_y = READ_Y(vref);
+               x->tx_buf = &packet->read_y;
+               x->len = 1;
+               spi_message_add_tail(x, m);
 
-       x++;
-       x->rx_buf = &packet->tc.y;
-       x->len = 2;
-       spi_message_add_tail(x, m);
+               x++;
+               x->rx_buf = &packet->tc.y;
+               x->len = 2;
+               spi_message_add_tail(x, m);
+       }
 
        /* the first sample after switching drivers can be low quality;
         * optionally discard it, using a second one after the signals
        m++;
        spi_message_init(m);
 
-       /* turn y- off, x+ on, then leave in lowpower */
-       x++;
-       packet->read_x = READ_X(vref);
-       x->tx_buf = &packet->read_x;
-       x->len = 1;
-       spi_message_add_tail(x, m);
+       if (ts->model == 7845) {
+               x++;
+               packet->read_x_cmd[0] = READ_X(vref);
+               packet->read_x_cmd[1] = 0;
+               packet->read_x_cmd[2] = 0;
+               x->tx_buf = &packet->read_x_cmd[0];
+               x->rx_buf = &packet->tc.x_buf[0];
+               x->len = 3;
+               spi_message_add_tail(x, m);
+       } else {
+               /* turn y- off, x+ on, then leave in lowpower */
+               x++;
+               packet->read_x = READ_X(vref);
+               x->tx_buf = &packet->read_x;
+               x->len = 1;
+               spi_message_add_tail(x, m);
 
-       x++;
-       x->rx_buf = &packet->tc.x;
-       x->len = 2;
-       spi_message_add_tail(x, m);
+               x++;
+               x->rx_buf = &packet->tc.x;
+               x->len = 2;
+               spi_message_add_tail(x, m);
+       }
 
        /* ... maybe discard first sample ... */
        if (pdata->settle_delay_usecs) {
        m++;
        spi_message_init(m);
 
-       x++;
-       packet->pwrdown = PWRDOWN;
-       x->tx_buf = &packet->pwrdown;
-       x->len = 1;
-       spi_message_add_tail(x, m);
+       if (ts->model == 7845) {
+               x++;
+               packet->pwrdown_cmd[0] = PWRDOWN;
+               packet->pwrdown_cmd[1] = 0;
+               packet->pwrdown_cmd[2] = 0;
+               x->tx_buf = &packet->pwrdown_cmd[0];
+               x->len = 3;
+       } else {
+               x++;
+               packet->pwrdown = PWRDOWN;
+               x->tx_buf = &packet->pwrdown;
+               x->len = 1;
+               spi_message_add_tail(x, m);
+
+               x++;
+               x->rx_buf = &packet->dummy;
+               x->len = 2;
+       }
 
-       x++;
-       x->rx_buf = &packet->dummy;
-       x->len = 2;
        CS_CHANGE(*x);
        spi_message_add_tail(x, m);
 
        /* take a first sample, leaving nPENIRQ active and vREF off; avoid
         * the touchscreen, in case it's not connected.
         */
-       (void) ads7846_read12_ser(&spi->dev,
-                         READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+       if (ts->model == 7845)
+               ads7845_read12_ser(&spi->dev, PWRDOWN);
+       else
+               (void) ads7846_read12_ser(&spi->dev,
+                               READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
 
        err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
        if (err)