struct ssam_tablet_sw;
 
+struct ssam_tablet_sw_state {
+       u32 source;
+       u32 state;
+};
+
 struct ssam_tablet_sw_ops {
-       int (*get_state)(struct ssam_tablet_sw *sw, u32 *state);
-       const char *(*state_name)(struct ssam_tablet_sw *sw, u32 state);
-       bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw, u32 state);
+       int (*get_state)(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state);
+       const char *(*state_name)(struct ssam_tablet_sw *sw,
+                                 const struct ssam_tablet_sw_state *state);
+       bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw,
+                                    const struct ssam_tablet_sw_state *state);
 };
 
 struct ssam_tablet_sw {
        struct ssam_device *sdev;
 
-       u32 state;
+       struct ssam_tablet_sw_state state;
        struct work_struct update_work;
        struct input_dev *mode_switch;
 
 
        struct {
                u32 (*notify)(struct ssam_event_notifier *nf, const struct ssam_event *event);
-               int (*get_state)(struct ssam_tablet_sw *sw, u32 *state);
-               const char *(*state_name)(struct ssam_tablet_sw *sw, u32 state);
-               bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw, u32 state);
+               int (*get_state)(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state);
+               const char *(*state_name)(struct ssam_tablet_sw *sw,
+                                         const struct ssam_tablet_sw_state *state);
+               bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw,
+                                            const struct ssam_tablet_sw_state *state);
        } ops;
 
        struct {
 static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct ssam_tablet_sw *sw = dev_get_drvdata(dev);
-       const char *state = sw->ops.state_name(sw, sw->state);
+       const char *state = sw->ops.state_name(sw, &sw->state);
 
        return sysfs_emit(buf, "%s\n", state);
 }
 static void ssam_tablet_sw_update_workfn(struct work_struct *work)
 {
        struct ssam_tablet_sw *sw = container_of(work, struct ssam_tablet_sw, update_work);
+       struct ssam_tablet_sw_state state;
        int tablet, status;
-       u32 state;
 
        status = sw->ops.get_state(sw, &state);
        if (status)
                return;
 
-       if (sw->state == state)
+       if (sw->state.source == state.source && sw->state.state == state.state)
                return;
        sw->state = state;
 
        /* Send SW_TABLET_MODE event. */
-       tablet = sw->ops.state_is_tablet_mode(sw, state);
+       tablet = sw->ops.state_is_tablet_mode(sw, &state);
        input_report_switch(sw->mode_switch, SW_TABLET_MODE, tablet);
        input_sync(sw->mode_switch);
 }
        sw->mode_switch->id.bustype = BUS_HOST;
        sw->mode_switch->dev.parent = &sdev->dev;
 
-       tablet = sw->ops.state_is_tablet_mode(sw, sw->state);
+       tablet = sw->ops.state_is_tablet_mode(sw, &sw->state);
        input_set_capability(sw->mode_switch, EV_SW, SW_TABLET_MODE);
        input_report_switch(sw->mode_switch, SW_TABLET_MODE, tablet);
 
        SSAM_KIP_COVER_STATE_FOLDED_BACK   = 0x05,
 };
 
-static const char *ssam_kip_cover_state_name(struct ssam_tablet_sw *sw, u32 state)
+static const char *ssam_kip_cover_state_name(struct ssam_tablet_sw *sw,
+                                            const struct ssam_tablet_sw_state *state)
 {
-       switch (state) {
+       switch (state->state) {
        case SSAM_KIP_COVER_STATE_DISCONNECTED:
                return "disconnected";
 
                return "folded-back";
 
        default:
-               dev_warn(&sw->sdev->dev, "unknown KIP cover state: %u\n", state);
+               dev_warn(&sw->sdev->dev, "unknown KIP cover state: %u\n", state->state);
                return "<unknown>";
        }
 }
 
-static bool ssam_kip_cover_state_is_tablet_mode(struct ssam_tablet_sw *sw, u32 state)
+static bool ssam_kip_cover_state_is_tablet_mode(struct ssam_tablet_sw *sw,
+                                               const struct ssam_tablet_sw_state *state)
 {
-       switch (state) {
+       switch (state->state) {
        case SSAM_KIP_COVER_STATE_DISCONNECTED:
        case SSAM_KIP_COVER_STATE_FOLDED_CANVAS:
        case SSAM_KIP_COVER_STATE_FOLDED_BACK:
                return false;
 
        default:
-               dev_warn(&sw->sdev->dev, "unknown KIP cover state: %d\n", sw->state);
+               dev_warn(&sw->sdev->dev, "unknown KIP cover state: %d\n", state->state);
                return true;
        }
 }
        .instance_id     = 0x00,
 });
 
-static int ssam_kip_get_cover_state(struct ssam_tablet_sw *sw, u32 *state)
+static int ssam_kip_get_cover_state(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state)
 {
        int status;
        u8 raw;
                return status;
        }
 
-       *state = raw;
+       state->source = 0;      /* Unused for KIP switch. */
+       state->state = raw;
        return 0;
 }
 
 #define SSAM_EVENT_POS_CID_POSTURE_CHANGED     0x03
 #define SSAM_POS_MAX_SOURCES                   4
 
-enum ssam_pos_state {
-       SSAM_POS_POSTURE_LID_CLOSED = 0x00,
-       SSAM_POS_POSTURE_LAPTOP     = 0x01,
-       SSAM_POS_POSTURE_SLATE      = 0x02,
-       SSAM_POS_POSTURE_TABLET     = 0x03,
+enum ssam_pos_source_id {
+       SSAM_POS_SOURCE_SLS   = 0x03,
+};
+
+enum ssam_pos_state_sls {
+       SSAM_POS_SLS_LID_CLOSED = 0x00,
+       SSAM_POS_SLS_LAPTOP     = 0x01,
+       SSAM_POS_SLS_SLATE      = 0x02,
+       SSAM_POS_SLS_TABLET     = 0x03,
 };
 
 struct ssam_sources_list {
        __le32 id[SSAM_POS_MAX_SOURCES];
 } __packed;
 
-static const char *ssam_pos_state_name(struct ssam_tablet_sw *sw, u32 state)
+static const char *ssam_pos_state_name_sls(struct ssam_tablet_sw *sw, u32 state)
 {
        switch (state) {
-       case SSAM_POS_POSTURE_LID_CLOSED:
+       case SSAM_POS_SLS_LID_CLOSED:
                return "closed";
 
-       case SSAM_POS_POSTURE_LAPTOP:
+       case SSAM_POS_SLS_LAPTOP:
                return "laptop";
 
-       case SSAM_POS_POSTURE_SLATE:
+       case SSAM_POS_SLS_SLATE:
                return "slate";
 
-       case SSAM_POS_POSTURE_TABLET:
+       case SSAM_POS_SLS_TABLET:
                return "tablet";
 
        default:
-               dev_warn(&sw->sdev->dev, "unknown device posture: %u\n", state);
+               dev_warn(&sw->sdev->dev, "unknown device posture for SLS: %u\n", state);
                return "<unknown>";
        }
 }
 
-static bool ssam_pos_state_is_tablet_mode(struct ssam_tablet_sw *sw, u32 state)
+static const char *ssam_pos_state_name(struct ssam_tablet_sw *sw,
+                                      const struct ssam_tablet_sw_state *state)
+{
+       switch (state->source) {
+       case SSAM_POS_SOURCE_SLS:
+               return ssam_pos_state_name_sls(sw, state->state);
+
+       default:
+               dev_warn(&sw->sdev->dev, "unknown device posture source: %u\n", state->source);
+               return "<unknown>";
+       }
+}
+
+static bool ssam_pos_state_is_tablet_mode_sls(struct ssam_tablet_sw *sw, u32 state)
 {
        switch (state) {
-       case SSAM_POS_POSTURE_LAPTOP:
-       case SSAM_POS_POSTURE_LID_CLOSED:
+       case SSAM_POS_SLS_LAPTOP:
+       case SSAM_POS_SLS_LID_CLOSED:
                return false;
 
-       case SSAM_POS_POSTURE_SLATE:
+       case SSAM_POS_SLS_SLATE:
                return tablet_mode_in_slate_state;
 
-       case SSAM_POS_POSTURE_TABLET:
+       case SSAM_POS_SLS_TABLET:
                return true;
 
        default:
-               dev_warn(&sw->sdev->dev, "unknown device posture: %u\n", state);
+               dev_warn(&sw->sdev->dev, "unknown device posture for SLS: %u\n", state);
+               return true;
+       }
+}
+
+static bool ssam_pos_state_is_tablet_mode(struct ssam_tablet_sw *sw,
+                                         const struct ssam_tablet_sw_state *state)
+{
+       switch (state->source) {
+       case SSAM_POS_SOURCE_SLS:
+               return ssam_pos_state_is_tablet_mode_sls(sw, state->state);
+
+       default:
+               dev_warn(&sw->sdev->dev, "unknown device posture source: %u\n", state->source);
                return true;
        }
 }
        return 0;
 }
 
-static int ssam_pos_get_posture(struct ssam_tablet_sw *sw, u32 *state)
+static int ssam_pos_get_posture(struct ssam_tablet_sw *sw, struct ssam_tablet_sw_state *state)
 {
        u32 source_id;
+       u32 source_state;
        int status;
 
        status = ssam_pos_get_source(sw, &source_id);
                return status;
        }
 
-       status = ssam_pos_get_posture_for_source(sw, source_id, state);
+       status = ssam_pos_get_posture_for_source(sw, source_id, &source_state);
        if (status) {
                dev_err(&sw->sdev->dev, "failed to get posture value for source %u: %d\n",
                        source_id, status);
                return status;
        }
 
+       state->source = source_id;
+       state->state = source_state;
        return 0;
 }